如何禁用Framer Motion在关键帧处的动画减速效果?
Framer Motion 关键帧减速问题解决方案
你遇到的关键帧位置减速,是Framer Motion默认对动画段应用easeInOut缓动规则导致的——默认规则下每两个相邻关键帧之间的动画都会呈现「启动加速、中间最快、临近关键帧减速」的效果,连续播放时就会在每个关键帧点出现明显的卡顿感,以下两种方案都可以解决这个问题:
方案1:保留现有关键帧写法,修改缓动配置
这是改动最小的方案,只需要在transition配置中把全段动画的缓动规则改为线性匀速即可:
<motion.div animate={{ // 你原有的关键帧配置,做正圆环形运动时可以搭配y轴关键帧形成闭合轨迹 x: [0, -100, 0, 100, 0], y: [0, 0, 100, 0, -100, 0] }} transition={{ duration: 3, // 按你的需求调整单圈时长 repeat: Infinity, ease: "linear", // 核心配置:全段匀速,无加减速 // 不要给ease传数组值,数组形式会为每个关键帧段单独分配缓动,哪怕每段设为linear也容易出现衔接顿挫 }} />
如果配置后仍有衔接顿挫,检查首尾关键帧的数值是否完全一致,首尾值不匹配会导致循环衔接处跳变,视觉上和减速卡顿非常相似。
方案2:逐帧计算轨迹(更适合连续3D旋转场景)
如果要做标准的环形3D旋转效果,手动写关键帧本身就不是最优选择,用动画帧配合三角函数实时计算坐标,能实现完全均匀无卡顿的旋转效果,也不需要手动对齐关键帧:
import { motion, useMotionValue, useAnimationFrame } from "framer-motion" function RotatingBlock() { // 定义运动值 const x = useMotionValue(0) const y = useMotionValue(0) const rotateY = useMotionValue(0) // 搭配Y轴旋转强化3D视觉 const radius = 100 // 环形运动半径 const speed = 1 // 旋转速度,数值越大转得越快 useAnimationFrame((time) => { const angle = (time / 1000) * speed * Math.PI // 用三角函数计算实时坐标 x.set(Math.sin(angle) * radius) y.set(Math.cos(angle) * radius) rotateY.set((angle * 180) / Math.PI) }) return ( <motion.div style={{ x, y, rotateY }} className="w-16 h-16 bg-indigo-500 rounded" /> ) }
这种方案不存在关键帧分段的概念,逐帧更新位置时全程速率完全一致,做无限循环的3D旋转效果稳定性远高于关键帧写法。
小提示:如果要强化3D纵深感,可以给运动元素的父容器加
perspective透视属性,旋转时的空间感会更真实。
内容的提问来源于stack exchange,提问作者Arslan
相关产品推荐
相关产品推荐

