Next.js 中优雅地使用 Lottie 动画
前言:
在现代 Web 开发中,动画效果对于提升用户体验起着重要作用。Lottie 是 Airbnb 开发的一个强大的动画库,它可以解析通过 Adobe After Effects 创建并导出为 JSON 格式的动画。今天我们来看看如何在 React 项目中优雅地封装和使用 Lottie 动画。安装依赖:
# npm npm install lottie-react # yarn yarn add lottie-react # pnpm pnpm add lottie-react
Lottie 常用配置项
interface LottieOptions { loop?: boolean; // 是否循环播放 autoplay?: boolean; // 是否自动播放 initialSegment?: [number, number]; // 播放片段范围 speed?: number; // 播放速度 direction?: 1 | -1; // 播放方向:1 正向,-1 反向 style?: React.CSSProperties; // 样式 onComplete?: () => void; // 播放完成回调 onLoopComplete?: () => void; // 每次循环完成回调 onClick?: () => void; // 点击事件 onMouseEnter?: () => void; // 鼠标进入事件 onMouseLeave?: () => void; // 鼠标离开事件 }
实现思路:
1. 基础结构设计
src/components/LottieAnimation/ ├── animations.ts // 动画配置文件 ├── index.tsx // 组件主文件 ├── types.d.ts // 类型声明文件 └── json/ // 存放动画 JSON 文件 └── friendly-vehicles.json
2. 类型声明
为了支持导入 JSON 文件,我们需要添加类型声明:
declare module '*.json' { const value: any export default value }
3. 动画配置管理
创建一个统一的动画配置文件,方便管理所有动画资源:
export const animations = { 'friendly-vehicles': () => import('./json/friendly-vehicles.json') // 在这里添加更多动画 // 'animation-name': () => import('./json/animation-name.json'), } as const export type AnimationName = keyof typeof animations
4. 组件实现
封装 Lottie 动画组件,支持动态加载和错误处理:
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<Props> = ({ size = 120, name }) => { const [animationData, setAnimationData] = useState<any>(null) const [loading, setLoading] = useState(true) useEffect(() => { const loadAnimation = async () => { try { setLoading(true) const module = await animations[name]() setAnimationData(module.default) } catch (error) { console.error('Failed to load animation:', error) } finally { setLoading(false) } } loadAnimation() }, [name]) if (loading || !animationData) { return <div style={{ width: size, height: size }}></div> } return ( <div style={{ width: size, height: size, margin: '0 auto' }}> <Lottie animationData={animationData} loop={true} autoplay={true} /> </div> ) } export default LottieAnimation
组件特点:
- 类型安全:使用 TypeScript 确保类型安全,避免运行时错误。
- 动态加载:采用动态导入方式加载动画文件,优化首屏加载性能。
- 统一管理:通过 animations.ts 统一管理所有动画资源,方便维护和扩展。
- 简单易用:封装了常用的配置项,使用时只需传入必要参数。
- 错误处理:内置错误处理机制,确保组件不会因加载失败而崩溃。
使用示例:
import LottieAnimation from '@/components/LottieAnimation' const MyComponent = () => { return ( <div> <h1>Lottie 动画示例</h1> <LottieAnimation name="friendly-vehicles" size={200} /> </div> ) }
如何添加新动画:
- 官网:https://iconscout.com/
- 将动画 JSON 文件放入 json 文件夹
- 在 animations.ts 中注册新动画:
export const animations = { 'friendly-vehicles': () => import('./json/friendly-vehicles.json'), 'new-animation': () => import('./json/new-animation.json') } as const
愿你走出半生,归来仍是少年