独自行走的犀牛 發表於 2025-3-7 12:50:00

Next.js 中优雅地使用 Lottie 动画

<h2>前言:</h2>
在现代 Web&nbsp;开发中,动画效果对于提升用户体验起着重要作用。Lottie 是&nbsp;Airbnb 开发的一个强大的动画库,它可以解析通过 Adobe&nbsp;After Effects 创建并导出为&nbsp;JSON 格式的动画。今天我们来看看如何在&nbsp;React 项目中优雅地封装和使用&nbsp;Lottie&nbsp;动画。
<h2>安装依赖:</h2>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;"># npm
npm install lottie-react

# yarn
yarn add lottie-react

# pnpm
pnpm add lottie-react</pre>
</div>
<h2>Lottie&nbsp;常用配置项</h2>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">interface LottieOptions {
loop?: boolean;            // 是否循环播放
autoplay?: boolean;          // 是否自动播放
initialSegment?: ; // 播放片段范围
speed?: number;             // 播放速度
direction?: 1 | -1;         // 播放方向:1 正向,-1 反向
style?: React.CSSProperties; // 样式
onComplete?: () =&gt; void;    // 播放完成回调
onLoopComplete?: () =&gt; void; // 每次循环完成回调
onClick?: () =&gt; void;       // 点击事件
onMouseEnter?: () =&gt; void;// 鼠标进入事件
onMouseLeave?: () =&gt; void;// 鼠标离开事件
}</pre>
</div>
<h2>实现思路:</h2>
<h3>1. 基础结构设计</h3>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">src/components/LottieAnimation/
├── animations.ts // 动画配置文件
├── index.tsx // 组件主文件
├── types.d.ts // 类型声明文件
└── json/ // 存放动画 JSON 文件
└── friendly-vehicles.json</pre>
</div>
<h3>2. 类型声明</h3>
<p>为了支持导入 JSON 文件,我们需要添加类型声明:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">declare module '*.json' {
const value: any
export default value
}
</pre>
</div>
<h3>3. 动画配置管理</h3>
<p>创建一个统一的动画配置文件,方便管理所有动画资源:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">export const animations = {
'friendly-vehicles': () =&gt; import('./json/friendly-vehicles.json')
// 在这里添加更多动画
// 'animation-name': () =&gt; import('./json/animation-name.json'),
} as const

export type AnimationName = keyof typeof animations
</pre>
</div>
<h3>4. 组件实现</h3>
<p>封装&nbsp;Lottie&nbsp;动画组件,支持动态加载和错误处理:</p>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">import Lottie from 'lottie-react'
import { useState, useEffect } from 'react'
import { animations, AnimationName } from './animations'

interface Props {
size?: number
name: AnimationName
}

const LottieAnimation: React.FC&lt;Props&gt; = ({ size = 120, name }) =&gt; {
const = useState&lt;any&gt;(null)
const = useState(true)

useEffect(() =&gt; {
    const loadAnimation = async () =&gt; {
      try {
      setLoading(true)
      const module = await animations()
      setAnimationData(module.default)
      } catch (error) {
      console.error('Failed to load animation:', error)
      } finally {
      setLoading(false)
      }
    }

    loadAnimation()
}, )

if (loading || !animationData) {
    return &lt;div style={{ width: size, height: size }}&gt;&lt;/div&gt;
}

return (
    &lt;div style={{ width: size, height: size, margin: '0 auto' }}&gt;
      &lt;Lottie animationData={animationData} loop={true} autoplay={true} /&gt;
    &lt;/div&gt;
)
}

export default LottieAnimation
</pre>
</div>
<h2>组件特点:</h2>
<ul>
<li value="1">类型安全:使用&nbsp;TypeScript 确保类型安全,避免运行时错误。</li>
</ul>
<ul>
<li value="2">动态加载:采用动态导入方式加载动画文件,优化首屏加载性能。</li>
</ul>
<ul>
<li value="3">统一管理:通过 animations.ts&nbsp;统一管理所有动画资源,方便维护和扩展。</li>
</ul>
<ul>
<li value="4">简单易用:封装了常用的配置项,使用时只需传入必要参数。</li>
</ul>
<ul>
<li value="5">错误处理:内置错误处理机制,确保组件不会因加载失败而崩溃。</li>
</ul>
<h2>使用示例:</h2>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">import LottieAnimation from '@/components/LottieAnimation'

const MyComponent = () =&gt; {
return (
    &lt;div&gt;
      &lt;h1&gt;Lottie 动画示例&lt;/h1&gt;
      &lt;LottieAnimation
      name="friendly-vehicles"
      size={200}
      /&gt;
    &lt;/div&gt;
)
}</pre>
</div>
<h2>如何添加新动画:</h2>
<ul>
<li value="1">官网:https://iconscout.com/</li>
<li value="1">将动画&nbsp;JSON 文件放入 json&nbsp;文件夹</li>
<li value="2">在 animations.ts 中注册新动画:</li>
</ul>
<div class="cnblogs_Highlighter">
<pre class="brush:csharp;gutter:true;">export const animations = {
'friendly-vehicles': () =&gt; import('./json/friendly-vehicles.json'),
'new-animation': () =&gt; import('./json/new-animation.json')
} as const
</pre>
</div>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    愿你走出半生,归来仍是少年<br><br>
来源:https://www.cnblogs.com/yz-blog/p/18757491
頁: [1]
查看完整版本: Next.js 中优雅地使用 Lottie 动画