当元素在视野中时(滚动到元素时),Framer Motion会进行动画处理。

17

是否有内置的方法可以使动画在元素进入视图时开始(例如,当我们滚动到元素时)?

Framer Motion 有一个装载动画(mount animations)部分,其中说:

当组件安装时,如果animate中的值与style或initial中定义的值不同,则它们将自动动画化。

所以我真的找不到一个简单明了的方法来使动画在进入视图时开始。

然而,我目前看到的唯一选项是使用动画控制,这意味着我必须手动在滚动上实现监听器并触发control.start(),如果有更简单的方法,我会非常感激。

2个回答

66

framer-motion自5.3版本以来已经内置了支持此用例的功能。

这里是演示该模式的 CodeSandbox:https://codesandbox.io/s/framer-motion-animate-in-view-5-3-94j13

相关的代码:

function FadeInWhenVisible({ children }) {
  return (
    <motion.div
      initial="hidden"
      whileInView="visible"
      viewport={{ once: true }}
      transition={{ duration: 0.3 }}
      variants={{
        visible: { opacity: 1, scale: 1 },
        hidden: { opacity: 0, scale: 0 }
      }}
    >
      {children}
    </motion.div>
  );
}

使用方法:

<FadeInWhenVisible>
  <Box />
</FadeInWhenVisible>

之前的版本:

您可以使用命令式动画控件来实现此效果。Intersection observers可用于检测元素是否当前可见。

这是一个演示该模式的CodeSandbox:https://codesandbox.io/s/framer-motion-animate-in-view-gqcc8

相关代码:

function FadeInWhenVisible({ children }) {
  const controls = useAnimation();
  const [ref, inView] = useInView();

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

  return (
    <motion.div
      ref={ref}
      animate={controls}
      initial="hidden"
      transition={{ duration: 0.3 }}
      variants={{
        visible: { opacity: 1, scale: 1 },
        hidden: { opacity: 0, scale: 0 }
      }}
    >
      {children}
    </motion.div>
  );
}

1

你也可以使用这个

<motion.div
 initial={{ opacity: 0 }}
 whileInView={{ opacity: 1 }}
 viewport={{ once: true, amount: 0.5 }}
 >
   hello
</motion.div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接