lottie-animation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseLottie Animation
Lottie动画
The bridge from After Effects to product: vector animation shipped as JSON (or zipped ), tiny and resolution-independent, played by a runtime on web, iOS, Android, and React Native. This skill covers integrating, controlling, and exporting Lottie.
.lottie连接After Effects与产品的桥梁:以JSON(或压缩的.lottie格式)交付的矢量动画,体积小巧且与分辨率无关,可通过运行时在网页、iOS、Android和React Native上播放。本技能涵盖Lottie的集成、控制与导出。
When to use
适用场景
- Ship a designer's AE animation to web/iOS/Android/React Native
- Looping illustrations, onboarding, empty states, animated icons
- Scroll-driven or interaction-driven vector playback (hover, click, cursor)
- Runtime theming/recoloring instead of re-exporting per brand
- 将设计师制作的AE动画交付至网页/iOS/Android/React Native
- 循环插图、引导页、空状态、动画图标
- 滚动驱动或交互驱动的矢量播放(悬停、点击、光标跟随)
- 运行时主题化/重新着色,无需针对每个品牌重新导出
Formats: .json vs .lottie
格式对比:.json vs .lottie
- — the raw Bodymovin output. Human-readable, larger.
.json - — a zipped container (often 60–80% smaller) that can bundle multiple animations, images, and theming. Preferred for shipping. Player:
.lottie(modern, canvas + WASM) supersedes the older@lottiefiles/dotlottie-web.lottie-web
Prefer the dotLottie runtime for new work; use only for legacy + SVG renderer needs.
lottie-web.json- — Bodymovin的原始输出,人类可读,体积较大。
.json - — 压缩容器(通常比.json小60–80%),可捆绑多个动画、图片和主题配置。是交付时的首选格式。播放器:
.lottie(基于canvas + WASM的现代版本)已取代旧版@lottiefiles/dotlottie-web。lottie-web
新项目优先使用dotLottie运行时;仅在需要兼容旧版.json + SVG渲染器时使用。
lottie-webCore workflow (web, dotLottie)
核心工作流(网页端,dotLottie)
bash
npm i @lottiefiles/dotlottie-web # vanilla
npm i @lottiefiles/dotlottie-react # React wrapperVanilla:
js
import { DotLottie } from "@lottiefiles/dotlottie-web";
const dotLottie = new DotLottie({
canvas: document.querySelector("#lottie"), // a <canvas> element
src: "/hero.lottie", // or .json
loop: true,
autoplay: true,
// speed: 1, mode: "forward" | "reverse" | "bounce", renderConfig: { autoResize: true }
});React:
jsx
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
function Hero() {
return <DotLottieReact src="/hero.lottie" loop autoplay style={{ width: 320 }} />;
}Capture the instance to control it:
jsx
const [dl, setDl] = useState(null);
<DotLottieReact src="/icon.lottie" dotLottieRefCallback={setDl} />;
// dl?.play(); dl?.pause(); dl?.setSpeed(2);bash
npm i @lottiefiles/dotlottie-web # 原生JS
npm i @lottiefiles/dotlottie-react # React封装原生JS示例:
js
import { DotLottie } from "@lottiefiles/dotlottie-web";
const dotLottie = new DotLottie({
canvas: document.querySelector("#lottie"), // 一个<canvas>元素
src: "/hero.lottie", // 也可使用.json格式
loop: true,
autoplay: true,
// speed: 1, mode: "forward" | "reverse" | "bounce", renderConfig: { autoResize: true }
});React示例:
jsx
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
function Hero() {
return <DotLottieReact src="/hero.lottie" loop autoplay style={{ width: 320 }} />;
}捕获实例以进行控制:
jsx
const [dl, setDl] = useState(null);
<DotLottieReact src="/icon.lottie" dotLottieRefCallback={setDl} />;
// dl?.play(); dl?.pause(); dl?.setSpeed(2);Playback control
播放控制
js
dotLottie.play();
dotLottie.pause();
dotLottie.stop();
dotLottie.setSpeed(1.5);
dotLottie.setMode("bounce"); // forward | reverse | bounce | reverse-bounce
dotLottie.setFrame(42); // jump to a frame
dotLottie.setSegment(30, 90); // constrain playback to a frame range (e.g. a "loading" loop)Events drive sequencing and UI:
js
dotLottie.addEventListener("load", () => { /* totalFrames now available */ });
dotLottie.addEventListener("complete", () => { /* non-looping playback finished */ });
dotLottie.addEventListener("frame", ({ currentFrame }) => { /* per-frame */ });State-machine style (e.g. button that plays "checked" segment then idles): play a segment, listen for , then to the idle loop.
completesetSegmentjs
dotLottie.play();
dotLottie.pause();
dotLottie.stop();
dotLottie.setSpeed(1.5);
dotLottie.setMode("bounce"); // forward | reverse | bounce | reverse-bounce
dotLottie.setFrame(42); // 跳转到指定帧
dotLottie.setSegment(30, 90); // 将播放限制在指定帧范围内(例如“加载”循环)通过事件驱动序列与UI:
js
dotLottie.addEventListener("load", () => { /* 此时可获取totalFrames */ });
dotLottie.addEventListener("complete", () => { /* 非循环播放已结束 */ });
dotLottie.addEventListener("frame", ({ currentFrame }) => { /* 逐帧触发 */ });状态机模式(例如:按钮播放“选中”片段后进入 idle 状态):播放指定片段,监听事件,然后调用切换到idle循环。
completesetSegmentScroll-driven Lottie (no GSAP needed)
滚动驱动的Lottie(无需GSAP)
Map scroll progress (0–1) to a frame. Pause autoplay and drive frames yourself.
js
const dotLottie = new DotLottie({ canvas, src: "/scroll.lottie", autoplay: false });
let total = 0;
dotLottie.addEventListener("load", () => { total = dotLottie.totalFrames; });
window.addEventListener("scroll", () => {
const el = canvas.closest(".scrolly");
const rect = el.getBoundingClientRect();
const p = clamp(-rect.top / (rect.height - window.innerHeight), 0, 1); // 0..1 through the section
dotLottie.setFrame(p * (total - 1));
}, { passive: true });
const clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));For richer interaction (hover-to-play, click toggles, cursor-follow) without writing the wiring, use , which maps , , , , and modes to frame ranges declaratively.
@lottiefiles/lottie-interactivityscrollhoverclickplaycursor将滚动进度(0–1)映射到帧。暂停自动播放,自行驱动帧更新。
js
const dotLottie = new DotLottie({ canvas, src: "/scroll.lottie", autoplay: false });
let total = 0;
dotLottie.addEventListener("load", () => { total = dotLottie.totalFrames; });
window.addEventListener("scroll", () => {
const el = canvas.closest(".scrolly");
const rect = el.getBoundingClientRect();
const p = clamp(-rect.top / (rect.height - window.innerHeight), 0, 1); // 滚动过该区域时的0..1进度
dotLottie.setFrame(p * (total - 1));
}, { passive: true });
const clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));若无需编写底层逻辑即可实现更丰富的交互(悬停播放、点击切换、光标跟随),可使用,它能以声明式方式将、、、和模式映射到帧范围。
@lottiefiles/lottie-interactivityscrollhoverclickplaycursorRuntime theming / recoloring
运行时主题化 / 重新着色
Two paths:
- dotLottie themes: a can embed named color themes; switch with
.lottie/dotLottie.setTheme("dark"). Authored in LottieFiles tooling — no re-export to recolor.loadTheme(...) - Manual color override: load the JSON, walk and patch
layers[].shapes[]color arrays (normalized 0–1 RGBA), then init the player with the modified object. Brittle (depends on layer structure) — prefer themes or CSS-driven SVG-renderer (c.klottie-web) when you must restyle by class.rendererSettings
两种实现方式:
- dotLottie主题:.lottie文件可嵌入命名颜色主题;通过/
dotLottie.setTheme("dark")切换。使用LottieFiles工具创建——无需重新导出即可更改颜色。loadTheme(...) - 手动颜色覆盖:加载JSON文件,遍历并修改
layers[].shapes[]颜色数组(归一化0–1的RGBA值),然后使用修改后的对象初始化播放器。这种方式较为脆弱(依赖图层结构)——必须通过类重新样式化时,优先使用主题或CSS驱动的SVG渲染器(c.k的lottie-web)。rendererSettings
Mobile runtimes (parity)
移动端运行时(功能对齐)
- iOS — (
lottie-ios):LottieAnimationView,.play(),.currentProgress..play(fromFrame:toFrame:) - Android — (
lottie-android/ ComposeLottieAnimationView):LottieAnimation,setMinAndMaxFrame.progress - React Native — (
lottie-react-native, drive<LottieView source={...} progress={anim} />withprogress).Animated
The same / plays across all; segments and progress concepts match the web API.
.lottie.json- iOS — (
lottie-ios):LottieAnimationView、.play()、.currentProgress。.play(fromFrame:toFrame:) - Android — (
lottie-android/ ComposeLottieAnimationView):LottieAnimation、setMinAndMaxFrame。progress - React Native — (
lottie-react-native,通过<LottieView source={...} progress={anim} />驱动Animated)。progress
同一.lottie/.json文件可在所有平台播放;片段和进度概念与网页端API一致。
Optimization
优化建议
- Ship (zipped) over raw
.lottie; lazy-load offscreen players and pause when not visible (.json→IntersectionObserver/play).pause - Prefer the canvas/WASM dotLottie renderer for many simultaneous animations; SVG renderer (lottie-web) is fine for one crisp icon but costs more DOM for complex files.
- Keep AE comps small: fewer layers/keyframes, no large embedded rasters; flatten precomps where possible. File size tracks keyframe and path complexity, not duration.
- Recolor at runtime (themes) instead of exporting a file per brand/theme.
- 优先交付.lottie(压缩格式)而非原始.json;延迟加载屏幕外的播放器,当元素不可见时暂停播放(使用控制
IntersectionObserver/play)。pause - 同时播放多个动画时,优先使用canvas/WASM版的dotLottie渲染器;SVG渲染器(lottie-web)适合单个清晰图标,但复杂文件会占用更多DOM资源。
- 保持AE合成文件简洁:减少图层/关键帧数量,不嵌入大型光栅图;尽可能合并预合成。文件大小取决于关键帧和路径复杂度,而非时长。
- 通过运行时主题化(主题)修改颜色,而非为每个品牌/主题导出单独文件。
Deliver & verify (standalone HTML)
交付与验证(独立HTML文件)
Packaged helper ():scripts/freezes thescripts/seek-shot.sh anim.html 0 1.5 3harness and screenshots each moment;?t=Ntiles them for one-glance review. Seescripts/contact-sheet.sh sheet.png frame-*.png.scripts/README.md
For a self-contained Lottie demo (looping illustration, animated icon, empty state) the deliverable is one HTML file that opens directly in a browser — the dotLottie/lottie-web runtime from CDN, a , and your / (a relative file or a data URL). No build step. One file is the right tier for shipping a player; don't reach for a bundler.
<canvas>.lottie.jsonOutput contract:
- One file: the runtime via CDN (
.html), the canvas, and@lottiefiles/dotlottie-webso the frame is yours to drive.autoplay:false - Include the seek harness so any frame can be frozen for a screenshot.
Seek harness — freeze an exact frame. jumps to a frame and holds it so a screenshot lands on a still, deterministic frame. Lottie's playhead is in frames, so stop on the frame directly:
?t=Nhtml
<script>
const dl = new DotLottie({ canvas, src: "/icon.lottie", autoplay: false });
dl.addEventListener("load", () => {
const t = new URLSearchParams(location.search).get("t");
if (t !== null) dl.setFrame(parseFloat(t)); // freeze on frame N (lottie-web: anim.goToAndStop(N, true))
else dl.play();
console.log("totalFrames", dl.totalFrames); // read for end-frame
window.__ready = true;
});
</script>Verify loop — render → freeze → screenshot → check: open the file at first / mid / last frame (, , ; read from the console), screenshot each, and check fidelity (colors/theme correct, segment loops where intended) plus artifacts (canvas blurry from missing /DPR, clipped composition, FOUC before the file loads, jank). Any headless tool works:
?t=0?t=<total/2>?t=<total-1>totalFramesautoResizebash
npx playwright screenshot --wait-for-timeout=600 "file://$PWD/lottie.html?t=42" frame-mid.pngBefore you finish:
- Opens standalone — no console errors, CDN runtime and the /
.lottieload..json - (
?t=N/setFrame) freezes the correct, deterministic frame.goToAndStop - Screenshotted at first / mid / last frame — matches the brief, sharp, no clipping.
- honored — don't
prefers-reduced-motiona loop; show a static frame or offer a play control.autoplay - Easing is intentional — playback speed/segment chosen on purpose, motion baked in AE reads as designed.
打包工具(目录):scripts/可冻结scripts/seek-shot.sh anim.html 0 1.5 3测试工具并截取每个时刻的截图;?t=N将截图拼接成一张预览图,方便快速查看。详见scripts/contact-sheet.sh sheet.png frame-*.png。scripts/README.md
对于独立的Lottie演示(循环插图、动画图标、空状态),交付物应为可直接在浏览器中打开的单个HTML文件——通过CDN引入dotLottie/lottie-web运行时、一个元素,以及你的.lottie/.json文件(相对路径或data URL)。无需构建步骤。单个文件是交付播放器的最佳方式,无需使用打包工具。
<canvas>输出规范:
- 单个文件:通过CDN引入
.html运行时、canvas元素,并设置@lottiefiles/dotlottie-web,以便自行控制帧。autoplay:false - 包含帧定位工具,可冻结任意帧以截图。
帧定位工具——冻结精确帧。可跳转到指定帧并保持静止,确保截图为确定的静态帧。Lottie的播放头以帧为单位,直接停在目标帧即可:
?t=Nhtml
<script>
const dl = new DotLottie({ canvas, src: "/icon.lottie", autoplay: false });
dl.addEventListener("load", () => {
const t = new URLSearchParams(location.search).get("t");
if (t !== null) dl.setFrame(parseFloat(t)); // 冻结在第N帧(lottie-web:anim.goToAndStop(N, true))
else dl.play();
console.log("totalFrames", dl.totalFrames); // 读取总帧数以获取结束帧
window.__ready = true;
});
</script>验证循环——渲染→冻结→截图→检查:在第一帧/中间帧/最后帧打开文件(、、;从控制台读取),分别截图,检查保真度(颜色/主题正确,片段按预期循环)以及** artifacts**(因缺少/DPR导致canvas模糊、合成内容被裁剪、文件加载前出现FOUC、播放卡顿)。任何无头工具均可完成此操作:
?t=0?t=<total/2>?t=<total-1>totalFramesautoResizebash
npx playwright screenshot --wait-for-timeout=600 "file://$PWD/lottie.html?t=42" frame-mid.png完成前检查:
- 可独立打开——无控制台错误,CDN运行时和.lottie/.json文件加载正常。
- (
?t=N/setFrame)可冻结正确的确定帧。goToAndStop - 在第一帧/中间帧/最后帧截图——符合需求,清晰无裁剪。
- 遵循设置——不要自动播放循环动画;显示静态帧或提供播放控件。
prefers-reduced-motion - 缓动效果符合预期——播放速度/片段选择合理,AE中制作的动效与设计一致。
Quick reference
快速参考
| Goal | Call |
|---|---|
| Play a range | |
| Jump to frame | |
| Reverse / bounce | `setMode("reverse" |
| Scroll-drive | |
| Theme swap | |
| Know length | |
| Declarative interactivity | |
| 目标 | 调用方法 |
|---|---|
| 播放指定范围 | |
| 跳转到指定帧 | |
| 反向播放 / 弹跳播放 | `setMode("reverse" |
| 滚动驱动 | |
| 切换主题 | |
| 获取总帧数 | 加载事件后读取 |
| 声明式交互 | |
Reference files
参考文件
- — full dotLottie-web + React setup and event/segment control,
references/integration-and-export.mdmode configs, scroll/cursor patterns, runtime theming details, and the complete After Effects → Bodymovin export checklist with the list of unsupported AE features and how to work around them.lottie-interactivity
- — 完整的dotLottie-web + React设置、事件/片段控制、
references/integration-and-export.md模式配置、滚动/光标交互模式、运行时主题化细节,以及完整的After Effects → Bodymovin导出检查清单,包含不支持的AE功能列表及解决方法。lottie-interactivity