0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React】ChakraUI(V3系)を使ってアニメーションライブラリMotion(旧 Framer-motion)の導入とフェードインの実装方法

Posted at

今回は、ReactアプリにMotion(旧 Framer-motion)を使ってCardコンポーネントがフェードインする方法について記載します。

完成イメージ

image.png

使用する技術スタック

 技術スタック   バージョン 
 React   ^19.1.1 
 ChakraUI/React   ^3.29.0 
 motion   ^12.23.24 

Motionのインストール方法

手順

1.Motionをインストールする

// npm
npm install motion

// yarn
yarn add motion

//pnpm
pnpm add motion

2.実装する

src/framerMotionComponents/fadeinWithScroll.tsx
import { motion, useReducedMotion } from "framer-motion";
import React, { createContext } from "react";
import type{ComponentPropsWithRef} from "react";
// 連動させてFadeInするかどうかのコンテキスト
const StaggerContext = createContext(false);

// スクロールに合わせて表示するためのViewportの設定
const viewport = { once: true, margin: "0px 0px -120px" };

// FadeInコンポーネント
export function FadeIn(props: ComponentPropsWithRef<typeof motion.div>) {
  const shouldReduceMotion = useReducedMotion();

  return (
    <motion.div
      {...props}
      initial={{ opacity: 0, y: shouldReduceMotion ? 0 : 24 }}
      whileInView={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.5, ease: "easeOut" }}
      viewport={viewport}
    />
  );
}

// 複数要素を連動してFadeInさせたいときに使うProvider
export function FadeInStagger({ children }: { children: React.ReactNode }) {
  return (
    <StaggerContext.Provider value={true}>
      <motion.div
        initial="hidden"
        whileInView="visible"
        viewport={viewport}
        variants={{
          hidden: {},
          visible: {
            transition: {
              staggerChildren: 0.2,
            },
          },
        }}
      >
        {children}
      </motion.div>
    </StaggerContext.Provider>
  );
}

src/chakraComponents/ui/CardList.tsx
import {
  Box,
  SimpleGrid,
  Heading,
  Text,
  Card,
} from "@chakra-ui/react";
import { FadeIn,FadeInStagger } from "@/framerMotionComponents/fadeInWithScroll";

const cards = [
  { title: "Card 1", text: "This is the first card." },
  { title: "Card 2", text: "This is the second card." },
  { title: "Card 3", text: "This is the third card." },
  { title: "Card 4", text: "This is the fourth card." },
];

export const CardList = () => {
  return (
    <Box p={6}>
      <FadeInStagger>
        <SimpleGrid columns={[1, 2, 2, 4]}>
          {cards.map((card, i) => (
            <FadeIn key={i}>
              <Card.Root boxShadow="md" borderWidth="1px" borderRadius="lg" overflow="hidden">
                <Card.Body>
                  <Heading size="md" mb={2}>
                    {card.title}
                  </Heading>
                  <Text>{card.text}</Text>
                </Card.Body>
              </Card.Root>
            </FadeIn>
          ))}
        </SimpleGrid>
      </FadeInStagger>
    </Box>
  );
};

さいごにApp.tsxの実装です。

App.tsx
import React from 'react';
import { ChakraProvider, Box, Flex, defaultSystem,Heading } from '@chakra-ui/react';
import { CardList } from './chakraComponents/ui/CardList'; 

const App: React.FC = () => {
  return (
    <React.StrictMode>
      <ChakraProvider value={defaultSystem}>
      <Box textAlign="center" py={16}>
        <Heading mb={8}>Scroll Down to See Fade-In Cards ✨</Heading>
        <CardList />
      </Box>
      </ChakraProvider>
    </React.StrictMode>
  );
};

export default App;

サイト

motion公式サイト

ChakraUI Cardコンポーネント

framer-motionの使い方

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?