我使用framer-motion在一个页面中动画多个元素。因为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>
然而,这个方法只允许我为每个.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>
3条答案
按热度按时间xhv8bpkk1#
您可以创建一个钩子,将动画组件的逻辑 Package 在“in view”上
对所有你想动画化的东西使用钩子
然后将引用连接到相关的DOM元素。
你也可以复制
useInView
钩子的现有用法,并在useEffect中添加一些逻辑。mnemlml82#
我遇到了这个问题,这是我如何解决它的任何人谁在这个绊倒。
我们仍然可以使用react-intersection-observer,而不是导入useInView()钩子,我们可以导入InView组件
然后我们可以用那个组件 Package 每个元素
然后我们可以为每个元素创建一个useAnimation钩子控件。
然后在组件上使用onChange引用每个元素中的控件。
我不确定这是否是最好的解决方案,但这是我在处理这个问题时唯一能想到的解决方案。封装在组件中的最后一个元素看起来像这样:
0yg35tkg3#
我不知道这是否已经被添加到帧运动最近,但这是我是如何做到这一点很容易:只需要添加你想应用到
whileInView
中的元素的动画,而不是像这样的animate
:这个
viewport={{ once: true }}
告诉framer motion,你希望这个动画只发生一次,而不是每次元素离开和进入视图时。