Framer Motion交错动画异常:滚动触发时仅部分元素生效
修复Framer Motion图片交错滑入动画的视口触发不同步问题
问题描述
使用Framer Motion实现两张图片从左侧滑入的交错动画时,出现以下异常:
- 页面刷新时若元素处于视口内,动画表现正常
- 滚动到元素区域时,若滚动速度较慢,第一张图片会先触发动画,第二张需要继续滚动一段距离才会启动动画
原因分析
原代码中每个图片元素单独绑定了whileInView视口检测逻辑,每个元素的触发条件是自身进入视口。如果两张图片在页面布局中并非完全处于同一视口区域(比如垂直排列),滚动时就会先后进入视口,导致动画触发时机不一致。
解决方案
通过容器包裹所有图片元素,将视口检测逻辑统一移到容器上。当容器进入视口时,一次性触发所有内部图片的动画,再通过delay参数维持交错效果。这样无论滚动速度快慢,只要容器进入视口,两张图片就会按设定的延迟依次执行动画。
修改后的代码
"use client"; import { motion } from "framer-motion"; // 定义图片元素的动画变体 const itemVariants = { initial: { opacity: 0, transform: 'translateX(-150px)', }, animate: (index: number) => ({ opacity: 1, transform: 'translateX(0px)', transition: { duration: 1, ease: 'easeInOut', delay: 0.3 * index, // 保留交错延迟逻辑 } }) }; const FramerAnimationSlideIn = ({ items }: any) => { return ( // 外层容器统一处理视口检测 <motion.div initial="initial" whileInView="animate" viewport={{ once: true }} // 容器自身无动画,仅作为触发载体 variants={{ initial: {}, animate: {} }} > {items.map((item, index) => ( <motion.div variants={itemVariants} key={item.src} custom={index} > {item} </motion.div> ))} </motion.div> ); }; export default FramerAnimationSlideIn;
核心修改点
- 新增外层
motion.div作为统一容器,将whileInView和viewport配置移至容器上 - 内部图片元素不再单独设置视口触发逻辑,而是通过继承容器的状态启动动画
- 保留原有的
delay逻辑,确保动画的交错层次感不变
内容的提问来源于stack exchange,提问作者BennKingy
相关产品推荐
相关产品推荐

