使用Framer Motion与Styled Components实现Div逐个入场动画故障排查
问题诊断与修正方案
核心问题
你的代码里有两个关键错误导致动画延迟不生效:
- 延迟参数语法错误:
transition中的delay: {item}把item包裹成了对象,但Framer Motion要求delay必须是数字类型,这种写法会被框架忽略,直接导致延迟失效。 - 目标位置设置不合理:
whileInView={{ y: 200 }}会让元素最终停在向下偏移200px的位置,不符合「进入视图后归位」的预期,应该让元素回到正常布局位置。
修正后的代码
import styled from "styled-components"; import { motion } from "framer-motion"; const TestItem = styled(motion.div)` width: 300px; height: 300px; background-color: red; margin: 20px 0; /* 增加间距,方便观察逐个动画效果 */ `; const Test = ({item}) => { return ( <TestItem initial={{ y: -200, opacity: 0 }} /* 初始状态:从上方隐藏+完全透明 */ whileInView={{ y: 0, opacity: 1 }} /* 进入视图后:回到原位+完全显示 */ viewport={{ once: true, margin: "-100px" }} /* 提前触发动画,避免等待元素完全进入视图 */ transition={{ type: "spring", bounce: 0.4, duration: 1, delay: item * 0.2 /* 修正:直接传数字,用系数控制逐个元素的延迟间隔 */ }} /> ) }; export default Test;
额外优化说明
- 给初始和目标状态增加了
opacity属性,让入场动画更平滑自然。 - 调整
viewport的margin为-100px,元素还没完全进入视图时就会触发动画,提升交互体验。 - 用
item * 0.2控制延迟,四个元素的延迟分别是0.2s、0.4s、0.6s、0.8s,实现连贯的逐个入场效果(如果觉得间隔不合适,可以自行调整系数大小)。
内容的提问来源于stack exchange,提问作者Peter Staal
相关产品推荐
相关产品推荐

