Framer Motion切换关键帧动画时如何实现平滑过渡?
解决Framer Motion变体切换时的瞬间跳转问题
问题场景
定义了两个关键帧动画变体horizontalWiggle和verticalWiggle,切换这两个动画时,元素属性瞬间变化,无法实现平滑过渡。原代码如下:
const variants = { ..., horizontalWiggle: { x: ["40px", "80px"], y: [0, 0], transition: { duration: 0.5, yoyo: Infinity } }, verticalWiggle: { x: [0, 0], y: ["8px", "40px"], transition: { duration: 0.5, yoyo: Infinity } } }
使用方式:
<motion.div className="wiggle" variants={variants} initial="init" animate={vertical ? "verticalWiggle" : "horizontalWiggle"} />
原因分析
当前变体中使用关键帧数组定义动画,Framer Motion默认会直接替换关键帧序列,导致切换时元素瞬间跳转到新动画的起始位置,没有过渡效果。
解决方案
通过以下调整实现平滑切换:
- 将变体中不需要循环的属性(比如
horizontalWiggle的y、verticalWiggle的x)从关键帧数组改为单个静态值,让Motion能识别并处理这些属性的过渡。 - 在变体的
transition配置中,为循环动画属性单独设置循环规则,同时添加default过渡配置处理变体切换时的平滑过渡。
修改后的代码:
const variants = { init: { x: 0, y: 0 }, horizontalWiggle: { x: ["40px", "80px"], y: 0, // 改为静态值 transition: { // 为x属性设置循环动画 x: { duration: 0.5, yoyo: Infinity }, // 变体切换时的默认过渡 default: { duration: 0.3 } } }, verticalWiggle: { x: 0, // 改为静态值 y: ["8px", "40px"], transition: { // 为y属性设置循环动画 y: { duration: 0.5, yoyo: Infinity }, // 变体切换时的默认过渡 default: { duration: 0.3 } } } }
使用方式保持不变:
<motion.div className="wiggle" variants={variants} initial="init" animate={vertical ? "verticalWiggle" : "horizontalWiggle"} />
效果说明
现在切换动画时,元素会先从当前位置平滑过渡到目标变体的静态属性值,同时无缝启动目标变体的循环关键帧动画,实现完全流畅的切换效果。
内容的提问来源于stack exchange,提问作者iamawebgeek
相关产品推荐
相关产品推荐

