【chakra ui】framer-motionにてスクロール連動型フェードインを実装する方法

【chakra ui】framer-motionにてスクロール連動型フェードインを実装する方法

chakra uiに標準で入っているframer-motiondeでよくあるスクロール連動型ふわっとフェードインを実装する方法

NEXT.js
chakra ui

こんにちは。
エンジニア歴7ヶ月目のざまです。

本日は、chakra uiに標準で依存している、framer-motionにて
よくあるふわっとフェードインを実装しようとした時にあんまり記事がなかったので自分のメモがてら書きます。

別のライブラリを入れても良かったのですが、せっかく入っているのだし、結構便利そうだったので
使うことにしました。

正直、css animation、transtionについてはそんなにまだわかっていないですw

完成版

親コンポーネント

//index.tsx
import { motion, Variants } from "framer-motion";
...

export default function Home() {

//バリアンと設定

//親motion 
  const topVariants: Variants = {
    offscreen: {
      opacity: 0,
    },
    onscreen: {
      opacity: 1,
      y: [50, 0],
      transition: {
        ease: [0.17, 0.55, 0.55, 1],
        duration: 0.9,
        delay: 0.5,
       //↓子(motion.liなど)を一括指定できる
        delayChildren: 0.3,  //子の遅延時間を変更
        staggerChildren: 0.3, // 子の間隔を変更
      },
    },
  };

//子motion
  const childrenVariants: Variants = {
    offscreen: {
      opacity: 0,
    },
    onscreen: {
      opacity: 1,
    },
  };

  return (
    <>
...
    <motion.div
      variants={topVariants}
      initial="offscreen"
      whileInView="onscreen"
      viewport={{ once: true, amount: 0.8 }}
    >
      <Center h={{ base: "xl", lg: "4xl" }}>
        <Image
          // style={{
          //   transform: isInview ? "none" : "translateY(100px)",
          //   opacity: isInview ? 1 : 0,
          //   transition:
          //     "all 0.9s cubic-bezier(0.17, 0.55, 0.55, 1) 0.5s",
          // }}
       ...
        />
      </Center>
    </motion.div>

...
    <Concept
      topVariants={topVariants}
      childrenVariants={childrenVariants}
    />
   



子コンポーネント

//Concept.tsx

import { motion } from "framer-motion";
import { Variant } from "../types/framer-motion";

const Concept = ({ topVariants, childrenVariants }: Variant) => {
  return (
...
    <motion.ul
      initial="offscreen"
      whileInView="onscreen"
      style={{ listStyle: "none" }}
      viewport={{ once: true, amount: 0.8 }}
      variants={topVariants}
    >
      <Stack
        direction={{ base: "column", lg: "row" }}
        justifyContent="space-between"
        align="center"
        spacing={{ base: "7", lg: "2" }}
    >
      <Box>
        <motion.li variants={childrenVariants}>
          <Image
         ...
          ></Image>
        </motion.li>
      </Box>
      <Box>
        <motion.li variants={childrenVariants}>
          <Image
         ...
          ></Image>
        </motion.li>
      </Box>
      <Box>
        <motion.li variants={childrenVariants}>
          <Image
           ...
          ></Image>
        </motion.li>
      </Box>
    </Stack>
  </motion.ul>
);
};


motionのprops、
initial="offscreen"
whileInView="onscreen"
を使えば、簡単にスクロール時に入った時にアニメーションを発火する様にできます。

他にも、useInViewとuseRefでドムを所得して変更する方法などもありましたが、スクロール時に合わせて発火するやり方がわからなかったです。
スクロール時に発火しなくても良ければuseInViewとuseRefの方が実装は簡単でした。

個人的には、
delayChildren
staggerChildren
が親から一括指定で子の遅延時間とか変更できるので非常に便利だと思いました。

誰かの参考になれば。

ブログ内検索