frontend-lottie

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Lottie

Lottie

Lightweight vector animations. Just plays and loops — no complex logic.
轻量级矢量动画。仅支持播放和循环——无复杂逻辑。

When to Use

使用场景

  • Loading spinners
  • Success/error checkmarks
  • Empty state illustrations
  • Decorative micro-animations
  • Animated icons
  • 加载动画
  • 成功/错误校验标识
  • 空状态插图
  • 装饰性微动画
  • 动画图标

When NOT to Use

不适用场景

  • Animation reacts to input → Rive
  • Multiple states/transitions → Rive
  • Complex interactivity → Rive
  • 动画需要响应用户输入 → 使用Rive
  • 包含多种状态/过渡效果 → 使用Rive
  • 复杂交互 → 使用Rive

Process

实施流程

FIND → ADD → INTEGRATE
  1. Find animation: https://lottiefiles.com
  2. Download .lottie or .json
  3. Place in
    public/animations/
  4. Use component
查找 → 添加 → 集成
  1. 查找动画:https://lottiefiles.com
  2. 下载 .lottie 或 .json 文件
  3. 放置到
    public/animations/
    目录下
  4. 使用组件

Quick Start

快速开始

bash
npm install @lottiefiles/dotlottie-react
tsx
import { DotLottieReact } from '@lottiefiles/dotlottie-react';

// Simple autoplay
<DotLottieReact
  src="/animations/loading.lottie"
  autoplay
  loop
  style={{ width: 200, height: 200 }}
/>
bash
npm install @lottiefiles/dotlottie-react
tsx
import { DotLottieReact } from '@lottiefiles/dotlottie-react';

// 简单自动播放
<DotLottieReact
  src="/animations/loading.lottie"
  autoplay
  loop
  style={{ width: 200, height: 200 }}
/>

Common Patterns

常见用法

tsx
// Loading spinner
<DotLottieReact src="/spinner.lottie" autoplay loop style={{ width: 48 }} />

// Success feedback (plays once)
<DotLottieReact src="/success.lottie" autoplay loop={false} />

// Empty state
<div className="flex flex-col items-center py-16">
  <DotLottieReact src="/empty.lottie" autoplay loop style={{ width: 200 }} />
  <h3>No results found</h3>
</div>

// Loading button
{isLoading ? (
  <DotLottieReact src="/button-loader.lottie" autoplay loop style={{ width: 24 }} />
) : (
  "Submit"
)}
tsx
// 加载动画
<DotLottieReact src="/spinner.lottie" autoplay loop style={{ width: 48 }} />

// 成功反馈(仅播放一次)
<DotLottieReact src="/success.lottie" autoplay loop={false} />

// 空状态
<div className="flex flex-col items-center py-16">
  <DotLottieReact src="/empty.lottie" autoplay loop style={{ width: 200 }} />
  <h3>No results found</h3>
</div>

// 加载中按钮
{isLoading ? (
  <DotLottieReact src="/button-loader.lottie" autoplay loop style={{ width: 24 }} />
) : (
  "Submit"
)}

Decision: Lottie vs Rive

选型对比:Lottie vs Rive

Animation TypeUse
Just plays/loopsLottie ✓
Reacts to hover/clickRive
State machineRive
Data-drivenRive
Simple loaderLottie ✓
动画类型推荐方案
仅播放/循环Lottie ✓
响应 hover/click 交互Rive
状态机Rive
数据驱动Rive
简单加载动画Lottie ✓

Finding Animations

查找动画资源

yaml
LottieFiles:   https://lottiefiles.com/free-animations
Lordicon:      https://lordicon.com (animated icons)
useAnimations: https://useanimations.com (micro-interactions)
yaml
LottieFiles:   https://lottiefiles.com/free-animations
Lordicon:      https://lordicon.com (animated icons)
useAnimations: https://useanimations.com (micro-interactions)

Playback Control

播放控制

tsx
'use client'
import { useState, useCallback } from 'react'
import { DotLottieReact, DotLottie } from '@lottiefiles/dotlottie-react'

function ControlledLottie() {
  const [dotLottie, setDotLottie] = useState<DotLottie | null>(null)

  return (
    <div
      onMouseEnter={() => dotLottie?.play()}
      onMouseLeave={() => dotLottie?.pause()}
    >
      <DotLottieReact
        src="/animation.lottie"
        loop
        dotLottieRefCallback={setDotLottie}
      />
    </div>
  )
}

// Methods: play(), pause(), stop(), setSpeed(n), goToAndPlay(frame)
tsx
'use client'
import { useState, useCallback } from 'react'
import { DotLottieReact, DotLottie } from '@lottiefiles/dotlottie-react'

function ControlledLottie() {
  const [dotLottie, setDotLottie] = useState<DotLottie | null>(null)

  return (
    <div
      onMouseEnter={() => dotLottie?.play()}
      onMouseLeave={() => dotLottie?.pause()}
    >
      <DotLottieReact
        src="/animation.lottie"
        loop
        dotLottieRefCallback={setDotLottie}
      />
    </div>
  )
}

// 可用方法:play(), pause(), stop(), setSpeed(n), goToAndPlay(frame)

SSR & Hydration

SSR 与 Hydration

tsx
// Always 'use client'
'use client'

// Dynamic import
const DotLottieReact = dynamic(
  () => import('@lottiefiles/dotlottie-react').then(m => m.DotLottieReact),
  { ssr: false }
)

// Or mounted check
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])
if (!mounted) return <Skeleton />
tsx
// 始终添加'use client'
'use client'

// 动态导入
const DotLottieReact = dynamic(
  () => import('@lottiefiles/dotlottie-react').then(m => m.DotLottieReact),
  { ssr: false }
)

// 或者检查组件是否已挂载
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])
if (!mounted) return <Skeleton />

Performance

性能优化

tsx
// Pause when not visible
import { useInView } from 'react-intersection-observer'

const { ref, inView } = useInView({ threshold: 0.1 })

useEffect(() => {
  inView ? dotLottie?.play() : dotLottie?.pause()
}, [inView, dotLottie])
tsx
// 当动画不可见时暂停播放
import { useInView } from 'react-intersection-observer'

const { ref, inView } = useInView({ threshold: 0.1 })

useEffect(() => {
  inView ? dotLottie?.play() : dotLottie?.pause()
}, [inView, dotLottie])

File Structure

文件结构

public/animations/
  loaders/spinner.lottie
  feedback/success.lottie, error.lottie
  empty-states/no-data.lottie
  illustrations/hero.lottie
public/animations/
  loaders/spinner.lottie
  feedback/success.lottie, error.lottie
  empty-states/no-data.lottie
  illustrations/hero.lottie

Troubleshooting

常见问题排查

yaml
"Animation not loading":
  → Check file path in public/
  → Verify .lottie or .json extension

"Animation not playing":
  → Add autoplay={true}
  → Add loop={true}

"Hydration mismatch":
  → Add 'use client'
  → Use dynamic(() => ..., { ssr: false })

"Too fast/slow":
  → speed={0.5} for slower
  → speed={2} for faster
yaml
"动画无法加载":
  → 检查public目录下的文件路径
  → 验证文件后缀为.lottie或.json

"动画无法播放":
  → 添加autoplay={true}
  → 添加loop={true}

"Hydration 不匹配":
  → 添加'use client'
  → 使用dynamic(() => ..., { ssr: false })

"动画速度过快/过慢":
  → 设置speed={0.5}来减慢速度
  → 设置speed={2}来加快速度

References

参考资料

  • patterns.md — Controlled playback, events, visibility pause, hover/click triggers
  • patterns.md — 受控播放、事件监听、不可见时暂停、hover/click 触发

External Resources

外部资源