- 引入lottie.json即可
- 可配置加载完成后索要循环的片段
- 帧数看json文件开头就可
- 我看到动画文件的信息:
“fr”:30 - 帧率30fps
“ip”:0 - 起始帧0
“op”:124 - 结束帧124

'use client'import { useEffect, useRef } from 'react'
import lottie from 'lottie-web'interface LottieAnimationProps {path?: stringanimationData?: unknownclassName?: stringwidth?: number | stringheight?: number | stringrenderer?: 'svg' | 'canvas' | 'html'startFrame?: numberendFrame?: numberspeed?: numberspeedLoop?: number
}export default function LottieAnimation({path,animationData,className = '',width = 500,height = 500,startFrame = 58,endFrame = 124,speed = 1,speedLoop = 1,renderer = 'canvas',
}: LottieAnimationProps) {const containerRef = useRef<HTMLDivElement>(null)const animationRef = useRef<any>(null) // eslint-disable-line @typescript-eslint/no-explicit-anyconst isInitializedRef = useRef(false)// 使用useRef存储参数,避免依赖变化const paramsRef = useRef({path,animationData,startFrame,endFrame,speed,speedLoop,renderer})useEffect(() => {if (!containerRef.current || isInitializedRef.current) {return;}isInitializedRef.current = trueconst params = paramsRef.currentlet animation: any = null; // eslint-disable-line @typescript-eslint/no-explicit-any// 创建动画实例animation = lottie.loadAnimation({container: containerRef.current!,renderer: params.renderer,loop: false,autoplay: false,...(params.path ? { path: params.path } : { animationData: params.animationData }),});animationRef.current = animation// 播放状态管理let isFirstPlay = true;let isLooping = false;let currentDirection = -1; // -1: 反向(124→54), 1: 正向(54→124)// 数据准备完成animation.addEventListener('data_ready', () => {animation.setSpeed(params.speed);// 第一次播放:0-124帧animation.goToAndStop(0, true);animation.play();});// 双向循环播放函数const startLoop = () => {if (!isLooping) return;if (currentDirection === -1) {// 反向播放:124→54animation.playSegments([params.endFrame, params.startFrame], true);} else {// 正向播放:54→124animation.playSegments([params.startFrame, params.endFrame], true);}};// 监听播放完成animation.addEventListener('complete', () => {if (isFirstPlay) {isFirstPlay = false;isLooping = true;animation.setSpeed(params.speedLoop);startLoop();} else if (isLooping) {// 循环播放完成,切换方向currentDirection *= -1;startLoop();}});return () => {isInitializedRef.current = falseif (animation) {animation.removeEventListener('data_ready');animation.removeEventListener('complete');animation.destroy();animationRef.current = null}};}, [])return (<divref={containerRef}className={className}style={{ width, height }}/>)
}
<LottieAnimationpath="/lottie_home.json"width={500}height={500}renderer="canvas"/>