如何在视口中为多个成帧器运动元素设置动画

Sai*_*jje 3 animation reactjs react-animations react-hooks framer-motion

我正在使用成帧器运动来为一页中的多个元素设置动画。由于成帧器运动没有一种简单的方法可以在元素进入视口后对其进行动画处理,因此我使用此方法:

const controls = useAnimation();
const { ref, inView } = useInView();

useEffect(() => {
    if (inView) {
      controls.start("visible");
    }
    if (!inView) {
      controls.start("hidden");
    }
  }, [controls, inView]);

const fadeFromBottom = {
    hidden: {
      opacity: 0,
      y: -5,
    },
    visible: {
      opacity: 1,
      y: 0,
      transition: {
        type: "spring",
        delay: 0.4,
      },
    },
  };

return (
<motion.section
  ref={ref}
  variants={fadeFromBottom}
  initial='hidden'
  animate={controls}
>
   <img src={image} alt='image'>
</motion.section>

Run Code Online (Sandbox Code Playgroud)

然而,这种方法只允许我为每个 .jsx 文件中的一个元素设置动画。如果我想在两个部分进入视口时使用不同的动画为其设置动画,我该怎么做?例如,我如何在不同时间使用不同的动画来制作这两个部分的动画?

<motion.section
  ref={ref}
  variants={fadeFromBottom}
  initial='hidden'
  animate={controls}
>
   <img src={image} alt='image'>
</motion.section>
<motion.section
  ref={ref}
  variants={fadeFromLeft}
  initial='hidden'
  animate={controls}
>
   <img src={image} alt='image'>
</motion.section>
Run Code Online (Sandbox Code Playgroud)

Jos*_*onn 5

您可以创建一个钩子,将动画组件的逻辑包装在“视图中”

const useAnimateOnInView = () => {
    const controls = useAnimation();
    const { ref, inView } = useInView();
    
    useEffect(() => {
        if (inView) {
          controls.start("visible");
        }
        if (!inView) {
          controls.start("hidden");
        }
      }, [controls, inView]);
    

     return { ref, controls };
}
Run Code Online (Sandbox Code Playgroud)

使用钩子来处理所有你想要动画的东西

const { ref: bananaRef, controls: bananaControl } = useAnimateOnInView();
const { ref: appleRef, controls: appleControl } = useAnimateOnInView();
Run Code Online (Sandbox Code Playgroud)

然后将 refs 连接到相关的 dom 元素。

<motion.section
  ref={bananaRef}
  variants={fadeFromBottom}
  initial='hidden'
  animate={bananaControl}
>
   <img src={image} alt='banana'>
</motion.section>
<motion.section
  ref={appleRef}
  variants={fadeFromLeft}
  initial='hidden'
  animate={appleControl}
>
   <img src={image} alt='apple'>
</motion.section>
Run Code Online (Sandbox Code Playgroud)

您也可以复制useInViewhook 的现有使用并向 useEffect 添加一些逻辑。我认为这个钩子可以稍微清理一下。