Skip to content

Lottie 在 Web 开发中的应用

Lottie 是由 Airbnb 开源的一套跨平台动画解决方案。它极大地简化了设计师和开发者之间的协作流程 - 设计师可以在 After Effects (AE) 或 Figma 等设计软件中创建动画,导出为 JSON 格式后,开发者便可以在各个平台上实现一致的动画效果。

作为前端开发者,Lottie 的出现显著降低了实现复杂动画的门槛。无需手写复杂的 CSS 动画或 Canvas 绘制代码,通过简单的配置就能完美还原设计稿中的动画效果。

设计工作流

Figma 工作流

  1. 安装 LottieFiles for Figma 插件
  2. 使用 Figma 创建动画
  3. 通过插件导出为 JSON 格式

After Effects 工作流

  1. 安装 LottieFiles for After Effects 插件
  2. 使用 AE 制作动画
  3. 通过插件导出为 JSON 格式

Web 端实现方案对比

在前端开发中,主要有三种实现方案:

1. Lottie Web (官方 SDK)

  • 优点
    • 官方维护,更新及时
    • 性能优化,直接使用 Canvas/SVG 渲染
    • 提供完整的动画控制 API
  • 缺点
    • 需要手动处理与框架的集成
    • API 偏底层,使用相对复杂

2. React Lottie

  • 优点
    • 专为 React 设计的封装
    • API 简单易用
  • 缺点
    • 基于较早期的 bodymovin.js
    • 使用 Class Components,不完全适配现代 React
    • TypeScript 支持有限

3. Lottie React

  • 优点
    • 基于最新的 Lottie Web
    • 完整的 TypeScript 支持
    • 支持函数组件和 Hooks
    • 提供声明式和命令式两种使用方式
  • 推荐使用场景
    • 现代 React 项目
    • 需要 TypeScript 支持
    • 简单动画展示需求

实战应用

Lottie Web 使用示例

安装

bash
# NPM
npm install lottie-web

# 或使用 CDN
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.4/lottie.min.js"></script>

基础使用

html
<div id="lottie-container" style="width: 400px; height: 400px"></div>

<script>
  const animation = lottie.loadAnimation({
    container: document.getElementById('lottie-container'),
    renderer: 'svg',  // 可选: 'svg' | 'canvas' | 'html'
    loop: true,
    autoplay: true,
    path: 'animation.json'  // 动画文件路径
  });
</script>

React 集成示例

tsx
import { useEffect, useRef } from 'react';
import lottie, { AnimationItem } from 'lottie-web';
import animationData from './animation.json';

const LottieAnimation = () => {
  const containerRef = useRef<HTMLDivElement>(null);
  const animationRef = useRef<AnimationItem>();

  useEffect(() => {
    if (!containerRef.current) return;

    animationRef.current = lottie.loadAnimation({
      container: containerRef.current,
      renderer: 'svg',
      loop: true,
      autoplay: true,
      animationData,
    });

    return () => animationRef.current?.destroy();
  }, []);

  return <div ref={containerRef} style={{ width: 400, height: 400 }} />;
};

export default LottieAnimation;

Lottie React 使用示例

安装

bash
npm install lottie-react
# 或
pnpm add lottie-react

组件式使用

tsx
import Lottie from 'lottie-react';
import animationData from './animation.json';

const Animation = () => (
  <Lottie 
    animationData={animationData}
    loop={true}
    autoplay={true}
    style={{ width: 400, height: 400 }}
  />
);

export default Animation;

Hook 式使用

tsx
import { useLottie } from 'lottie-react';
import animationData from './animation.json';

const Animation = () => {
  const { View, play, pause, stop } = useLottie({
    animationData,
    loop: true,
    autoplay: false,
  });

  return (
    <div>
      {View}
      <button onClick={() => play()}>播放</button>
      <button onClick={() => pause()}>暂停</button>
      <button onClick={() => stop()}>停止</button>
    </div>
  );
};

export default Animation;

高级功能

动画控制

tsx
import { useRef } from 'react';
import Lottie, { LottieRefCurrentProps } from 'lottie-react';
import animationData from './animation.json';

const ControlledAnimation = () => {
  const lottieRef = useRef<LottieRefCurrentProps>(null);

  const handleComplete = () => {
    console.log('动画播放完成');
  };

  return (
    <div>
      <Lottie
        lottieRef={lottieRef}
        animationData={animationData}
        loop={false}
        onComplete={handleComplete}
      />
      <button onClick={() => lottieRef.current?.setSpeed(2)}>
        2倍速播放
      </button>
      <button onClick={() => lottieRef.current?.goToAndPlay(30, true)}>
        跳转到第30帧并播放
      </button>
    </div>
  );
};

export default ControlledAnimation;

性能优化建议

  1. 选择合适的渲染器

    • SVG: 适用于小型、交互性强的动画
    • Canvas: 适用于大型、复杂的动画
  2. 优化动画资源

    • 压缩 JSON 文件
    • 移除未使用的关键帧
    • 适当降低动画帧率
  3. 按需加载

    • 使用动态导入延迟加载动画资源
    • 考虑在适当时机销毁动画实例
  4. 缓存策略

    • 对频繁使用的动画进行缓存
    • 考虑使用 Service Worker 缓存动画资源

最佳实践

  1. 文件管理

    src/
    ├── assets/
    │   └── animations/     # 存放动画JSON文件
    ├── components/
    │   └── animations/     # 存放动画组件
  2. 组件封装

    tsx
    // src/components/animations/AnimationWrapper.tsx
    import Lottie, { LottieProps } from 'lottie-react';
    
    interface Props extends Partial<LottieProps> {
      name: string;
      size?: number;
    }
    
    const AnimationWrapper = ({ name, size = 200, ...props }: Props) => (
      <Lottie
        animationData={require(`@/assets/animations/${name}.json`)}
        style={{ width: size, height: size }}
        {...props}
      />
    );
    
    export default AnimationWrapper;
  3. 错误处理

    tsx
    const Animation = () => {
      const handleError = (err: Error) => {
        console.error('Lottie 动画加载失败:', err);
        // 显示后备UI
      };
    
      return (
        <ErrorBoundary fallback={<FallbackUI />}>
          <Lottie
            animationData={animationData}
            onError={handleError}
          />
        </ErrorBoundary>
      );
    };

Lottie 为 Web 开发带来了设计与开发的无缝衔接,大幅提升了动画开发效率。通过合理选择实现方案、遵循最佳实践,我们可以轻松地在 Web 应用中实现高质量的动画效果。

Last updated: