关于 lottie-animation
面向需要在产品中集成矢量动画的设计师与开发者的 Lottie 技能,介绍播放控制、滚动交互、主题换色及多端运行时,并说明如何制作和验证独立 HTML 示例。
主要功能
- 01集成 dotLottie 与 Lottie JSON
- 02控制播放、速度、帧和片段
- 03按滚动或交互驱动动画
- 04运行时切换主题与颜色
- 05跨 Web 和移动端播放
- 06优化加载并验证静态帧
适用场景
- 01在产品中加入引导动画或空状态插画
- 02将动画播放进度映射到页面滚动
- 03按交互播放图标或按钮状态
- 04为品牌主题切换动画配色
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ iart-ai/ web-animation-skills --skill lottie-animation安装后在 Claude Code 中输入/lottie-animation确认已加载。
附带文件README.mdreferences/integration-and-export.md
详细介绍
Lottie 动画
连接 After Effects 与产品:将矢量动画以 JSON(或压缩后的 .lottie)形式交付,体积小且与分辨率无关,可通过运行时在 Web、iOS、Android 和 React Native 上播放。本技能介绍 Lottie 的集成、控制和导出。
适用场景
- 将设计师制作的 AE 动画交付到 Web/iOS/Android/React Native
- 循环插画、引导页、空状态、动画图标
- 由滚动或交互(悬停、点击、光标)驱动的矢量动画播放
- 在运行时切换主题/颜色,而不是针对每个品牌重新导出
格式:.json 与 .lottie
.json— 原始 Bodymovin 输出。便于阅读,但体积更大。.lottie— 压缩容器(通常小 60–80%),可打包多个动画、图像和主题。交付时优先使用。播放器:@lottiefiles/dotlottie-web(现代方案,支持 canvas + WASM),可替代较旧的lottie-web。
新项目优先使用 dotLottie 运行时;仅在旧版 .json + SVG 渲染器需求下使用 lottie-web。
核心工作流(Web,dotLottie)
npm i @lottiefiles/dotlottie-web # vanilla
npm i @lottiefiles/dotlottie-react # React wrapper
原生 JavaScript:
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:
import { DotLottieReact } from "@lottiefiles/dotlottie-react";
function Hero() {
return <DotLottieReact src="/hero.lottie" loop autoplay style={{ width: 320 }} />;
}
获取实例以进行控制:
const [dl, setDl] = useState(null);
<DotLottieReact src="/icon.lottie" dotLottieRefCallback={setDl} />;
// dl?.play(); dl?.pause(); dl?.setSpeed(2);
播放控制
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)
通过事件驱动播放顺序和 UI:
dotLottie.addEventListener("load", () => { /* totalFrames now available */ });
dotLottie.addEventListener("complete", () => { /* non-looping playback finished */ });
dotLottie.addEventListener("frame", ({ currentFrame }) => { /* per-frame */ });
状态机风格(例如,按钮播放“已勾选”片段后再进入空闲状态):播放一个片段,监听 complete,然后用 setSegment 设置为空闲循环。
滚动驱动的 Lottie(无需 GSAP)
将滚动进度(0–1)映射到帧。暂停自动播放,手动驱动帧。
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));
如需更丰富的交互(悬停播放、点击切换、跟随光标),且不想自行编写连接逻辑,可使用 @lottiefiles/lottie-interactivity。它可以将 scroll、hover、click、play 和 cursor 模式声明式地映射到帧范围。
运行时主题/颜色调整
有两种方式:
- dotLottie 主题:
.lottie可以嵌入命名颜色主题;通过dotLottie.setTheme("dark")/loadTheme(...)切换。使用 LottieFiles 工具制作,无需重新导出即可调整颜色。 - 手动颜色覆盖:加载 JSON,遍历
layers[].shapes[]并修改c.k颜色数组(归一化的 0–1 RGBA),然后使用修改后的对象初始化播放器。这种方式较脆弱(取决于图层结构)——优先使用主题;必须按类名重新设置样式时,则使用由 CSS 驱动的 SVG 渲染器(lottie-webrendererSettings)。
移动端运行时(对应功能)
- iOS —
lottie-ios(LottieAnimationView):.play()、.currentProgress、.play(fromFrame:toFrame:)。 - Android —
lottie-android(LottieAnimationView/ ComposeLottieAnimation):setMinAndMaxFrame、progress。 - React Native —
lottie-react-native(<LottieView source={...} progress={anim} />,使用Animated驱动progress)。
同一个 .lottie/.json 文件可在所有平台播放;片段和进度的概念与 Web API 一致。
优化
- 优先交付压缩后的
.lottie,而非原始.json;延迟加载屏幕外的播放器,并在不可见时暂停(IntersectionObserver→play/pause)。 - 同时播放多个动画时,优先使用 canvas/WASM dotLottie 渲染器;SVG 渲染器(lottie-web)适合播放一个清晰的图标,但处理复杂文件时会产生更多 DOM。
- 尽量精简 AE 合成:减少图层和关键帧,避免嵌入大型栅格图;尽可能扁平化预合成。文件大小取决于关键帧和路径的复杂度,而非时长。
- 在运行时调整颜色(主题),而不是针对每个品牌/主题导出单独文件。
交付与验证(独立 HTML)
打包的辅助脚本(
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 运行时、一个 <canvas>,以及你的 .lottie/.json(相对路径文件或数据 URL)。无需构建步骤。要交付播放器,一个文件就足够;不要使用打包工具。
输出约定:
- 一个
.html文件:通过 CDN 加载运行时(@lottiefiles/dotlottie-web),包含 canvas,并设置autoplay:false,以便由你控制帧。 - 添加定位测试框架,以便冻结任意帧并截屏。
定位测试框架——冻结准确帧。 ?t=N 会跳转到指定帧并暂停,使截图落在静止且可复现的帧上。Lottie 的播放头以帧为单位,因此应直接停在该帧:
<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>
验证循环——渲染 → 冻结 → 截屏 → 检查: 在第一帧/中间帧/最后一帧打开文件(?t=0、?t=<total/2>、?t=<total-1>;从控制台读取 totalFrames),分别截屏,并检查保真度(颜色/主题是否正确、片段是否按预期循环)以及瑕疵(缺少 autoResize/DPR 导致 canvas 模糊、构图被裁切、文件加载前出现 FOUC、卡顿)。任何无头工具都可以:
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 中制作的动画符合设计预期。
快速参考
| 目标 | 调用 |
|---|---|
| 播放一段范围 | setSegment(start, end) |
| 跳转到某一帧 | setFrame(n) |
| 反向播放/往返播放 | `setMode("reverse" |
| 由滚动驱动 | autoplay:false + setFrame(p*totalFrames) |
| 切换主题 | setTheme("dark") |
| 获取时长 | load 事件后读取 totalFrames |
| 声明式交互 | @lottiefiles/lottie-interactivity |
参考文件
references/integration-and-export.md— 完整的 dotLottie-web + React 设置与事件/片段控制、lottie-interactivity模式配置、滚动/光标模式、运行时主题设置详情,以及完整的 After Effects → Bodymovin 导出检查清单,其中列出了不受支持的 AE 功能及其解决方法。