reactjs - 如何在视口中为多个帧运动元素设置动画
问题描述
我正在使用 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>
解决方案
您可以创建一个挂钩,将动画组件的逻辑包装在“视图中”
const useAnimateOnInView = () => {
const controls = useAnimation();
const { ref, inView } = useInView();
useEffect(() => {
if (inView) {
controls.start("visible");
}
if (!inView) {
controls.start("hidden");
}
}, [controls, inView]);
return { ref };
}
将钩子用于您想要动画的所有事物
const { ref: bananaRef } = useAnimateOnInView();
const { ref: appleRef } = useAnimateOnInView();
然后将 refs 连接到相关的 dom 元素。
<motion.section
ref={bananaRef}
variants={fadeFromBottom}
initial='hidden'
animate={controls}
>
<img src={image} alt='banana'>
</motion.section>
<motion.section
ref={appleRef}
variants={fadeFromLeft}
initial='hidden'
animate={controls}
>
<img src={image} alt='apple'>
</motion.section>
您也可以只复制现有的useInView
钩子使用并为 useEffect 添加一些逻辑。我认为这个钩子虽然有点清理它。
推荐阅读
- jenkins - 无需插件即可从 Jenkins 将 git repo 上传到 S3 存储桶
- vb.net - 视觉工作室。将数字添加到最终结果
- sql - 插入或更新的值过高或过低时的 SQL 触发器
- javascript - 如何在类中将事件作为对象值发出?
- c++ - 有什么方法或想法来保护或签署源代码?
- angular - AG-Grid /w Angular 11 错误:目标入口点“ag-grid-angular”缺少依赖项
- typescript - 如何在 typescript 中为包含 yield* 委托的 redux-saga 生成器函数编写类型
- firebase - Android 上的 Flutter/Firebase verifyPhoneNumber() 总是调用 recaptcha “验证你不是机器人”
- javascript - 如何在 Javascript 中设置对象属性的样式?我收到“未捕获的类型错误:无法设置未定义的属性 'fontWeight'”
- html - 如何防止用户从演示中下载 HTML 模板?