如何通过lottie-react的useLottieInteractivity实现动画仅触发一次?
解决Lottie动画仅在特定可见范围播放一次的问题
嘿,我明白你的困扰了——用useLottieInteractivity时动画总是循环播放,想要让它只在第一次进入目标可见范围时播放一次对吧?咱们来一步步调整你的代码:
首先,你的代码里有两个小问题:一是在组件内部嵌套定义了LottieAnimation组件,这会导致不必要的重渲染;二是没有标记动画是否已经播放过,所以每次进入可见范围都会触发play动作。另外,别忘了给Lottie本身设置不循环的配置。
下面是修改后的完整代码,我会标注关键改动:
import React, { useState } from "react" import { useLottie, useLottieInteractivity } from "lottie-react" import CMS from "../components/remdash/animations/cms.json" const LottieBlock: React.FC<any> = props => { // 新增状态:记录动画是否已经播放过一次 const [hasPlayed, setHasPlayed] = useState(false) const options = { animationData: CMS, loop: false, // 关键设置:让动画本身不循环 autoplay: false, // 禁止自动播放,交给交互控制 } const lottieObj = useLottie(options) const Animation = useLottieInteractivity({ lottieObj, mode: "scroll", actions: [ { visibility: [0, 0.4], type: "seek", frames: [0], // 只有当动画没播放过时,才重置到第一帧 condition: () => !hasPlayed, }, { visibility: [0.4, 0.5], type: "play", frames: [0, 60], // 仅在动画未播放时执行play,并标记为已播放 condition: () => { if (!hasPlayed) { setHasPlayed(true); return true; } return false; }, }, { visibility: [0.6, 1], type: "seek", // 用seek替代stop,保持在最后一帧 frames: [60], }, ] }) return ( <div className="relative w-full h-full"> {Animation} </div> ) } export default LottieBlock
关键改动说明:
- 添加
hasPlayed状态:用来跟踪动画是否已经完成过一次播放,避免重复触发。 - Lottie基础配置:在
options里设置loop: false和autoplay: false,从根源上禁止动画自动循环。 - 条件化的交互动作:
- 在seek到第0帧的动作里,只有动画没播放过时才执行,避免已经播放完的动画被重置。
- 在play动作里,只有未播放过时才触发播放,并立即将
hasPlayed设为true,确保后续不会再触发。 - 把stop动作改成seek到最后一帧,这样动画播放完后会停在结束画面,而不是中途停止。
这样调整后,动画就只会在第一次进入[0.4, 0.5]的可见范围时播放一次,之后不管怎么滚动,都会保持在最后一帧啦!
内容的提问来源于stack exchange,提问作者PhilippeO
相关产品推荐
相关产品推荐

