You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Framer Motion中修改无限动画时长且不重置动画进度

解决方案

方案1:调整动画播放速率(最优解,无动画断层)

核心逻辑是不要每次修改时长就销毁重建动画,直接通过Framer Motion动画控制器提供的setRate方法调整播放速度,等效实现修改duration的效果,全程不会打断动画,循环范围也能保持1~2不变:

const [count, setCount] = useState(1);
const scale = useMotionValue(1);
// 存储动画控制器,避免重复创建动画
const controlsRef = React.useRef(null);

// 仅初始化时创建一次动画
React.useEffect(() => {
  controlsRef.current = animate(scale, [1, 2], {
    repeat: Infinity,
    ease: "linear",
    duration: 1 // 固定基础时长,用速率控制实际时长
  });
  return () => controlsRef.current.stop();
}, [scale]);

// 时长参数变化时仅调整播放速率
React.useEffect(() => {
  if (controlsRef.current) {
    // 播放速率与目标时长成反比:目标时长越长,播放速度越慢
    controlsRef.current.setRate(1 / count);
  }
}, [count]);

方案2:重建动画时手动补偿进度

如果必须每次修改时长都重建动画,可以在重建前计算当前动画的完成进度,通过负延迟让新动画直接跳到对应进度开始播放,避免重置或循环范围偏移:

const [count, setCount] = useState(1);
const scale = useMotionValue(1);

React.useEffect(() => {
  // 计算当前动画进度
  const currentScale = scale.get();
  const progress = (currentScale - 1) / (2 - 1);

  const controls = animate(scale, [1, 2], {
    repeat: Infinity,
    ease: "linear",
    duration: count,
    // 负延迟会直接跳过对应时长的动画,从进度匹配的位置开始播放
    delay: -progress * count
  });
  return controls.stop;
}, [scale, count]);

内容的提问来源于stack exchange,提问作者Bastien Robert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:06:06