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

如何在Framer Motion中实现单个组件动画序列的无限循环

如何在Framer Motion中实现单个组件动画序列的无限循环

嘿,我明白你现在的需求啦——你已经写好了一段连贯的动画序列,但希望它能一直循环播放,对吧?其实实现起来很简单,咱们可以利用递归调用的方式,让动画序列在完成后自动重启。

你现在的runAnimation函数只会在组件挂载时执行一次,执行完整个序列就结束了。要让它无限循环,只需要在所有动画步骤完成后,再次调用runAnimation本身就行。

修改后的代码示例

const [scope, animate] = useAnimate();

const runAnimation = async () => {
  await animate(scope.current, { x: 300 }, { duration: 2 });
  await animate(scope.current, { scaleX: -1 }, { duration: 0.2 });
  await animate(scope.current, { x: -200 }, { duration: 2 });
  await animate(scope.current, { scaleX: 1 }, { duration: 0.2 });
  // 动画序列完成后递归调用自身,触发下一轮循环
  runAnimation();
};

useEffect(() => {
  runAnimation();
}, []);

这样一来,每当四个动画步骤全部执行完毕,函数就会立刻重新启动整个序列,形成无限循环的效果。

进阶:可控的循环(可选)

如果之后你需要手动控制循环的启停,可以添加一个状态变量来管理:

import { useState } from 'react';
import { useAnimate } from 'framer-motion';

// ...

const [scope, animate] = useAnimate();
const [isLooping, setIsLooping] = useState(true);

const runAnimation = async () => {
  // 如果已经停止循环,直接退出
  if (!isLooping) return;
  
  await animate(scope.current, { x: 300 }, { duration: 2 });
  await animate(scope.current, { scaleX: -1 }, { duration: 0.2 });
  await animate(scope.current, { x: -200 }, { duration: 2 });
  await animate(scope.current, { scaleX: 1 }, { duration: 0.2 });
  
  // 再次检查循环状态,确保只有在开启状态下才继续
  if (isLooping) {
    runAnimation();
  }
};

useEffect(() => {
  runAnimation();
  // 组件卸载时停止循环,避免内存泄漏
  return () => setIsLooping(false);
}, []);

// 之后可以通过按钮等触发setIsLooping(true/false)来控制循环

这种递归的方式非常适合你这种多步骤的序列动画,能完美保持动画的顺序和连贯性,而且几乎不需要改动原有代码逻辑。

备注:内容来源于stack exchange,提问作者abhi jain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 15:00:32