今回は、ReactアプリにMotion(旧 Framer-motion)を使ってCardコンポーネントがフェードインする方法について記載します。
完成イメージ
使用する技術スタック
| 技術スタック | バージョン |
|---|---|
| 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の使い方
