lottie-web — 把 AE 动画变成网页可播放的 JSON
待复核lottie-web 是一个在网页里播放 After Effects 动画的 JavaScript 播放器。设计师用 AE 做动画,再用 bodymovin 插件导出一份 JSON,前端用 lottie-web 把这份 JSON 画成 SVG、Canvas 或 HTML。
日常类比:它像一台会读乐谱的自动钢琴。AE 工程是音乐家的演奏,bodymovin 把演奏写成乐谱,lottie-web 在浏览器里按乐谱一拍一拍弹出来。
所以 Lottie 不只是”一个动画库”。更准确地说,它是一种动画交付格式 + 播放器生态:同一份 JSON 可以给 Web、iOS、Android 等平台各自的播放器使用。
最小用法长这样:
const anim = lottie.loadAnimation({ container: document.querySelector("#logo"), renderer: "svg", loop: true, autoplay: true, path: "/animations/logo.json",});不理解 lottie-web,下面这些事会很难解释:
- 为什么很多 app 的开屏、空状态、loading 动效不再交 GIF,而是交一份
.json文件。 - 为什么设计师可以在 AE 里做复杂时间线,工程师不用照着一帧帧重写 CSS keyframes。
- 为什么同一段品牌动画能同时放到 Web、iOS、Android,核心不是代码相同,而是中间格式相同。
- 为什么 Lottie 有时比 GIF 小很多,但有时又因为播放器本身变重:省的是素材体积,不一定省运行时代码。
-
JSON 是乐谱:Lottie JSON 记录帧率、尺寸、图层、关键帧、形状、文字和图片资源。类比:乐谱不发出声音,但它规定了每个音什么时候出现、持续多久、用什么力度。
-
播放器是乐手:lottie-web 读取 JSON 后,每一帧计算当前位置、透明度、旋转、路径形状,再交给 SVG 或 Canvas 画出来。类比:同一份谱子,小提琴和钢琴都能演,但音色和限制不同。
-
工作流比 API 更关键:它解决的是”设计师交付动画”这件事,而不是替代所有动画代码。类比:快递单统一了包裹信息,仓库和配送车才能协作;Lottie JSON 统一了动画信息,设计和工程才能协作。
案例 1:网页里播放一个 loading 动画
Section titled “案例 1:网页里播放一个 loading 动画”<div id="loading" style="width:160px;height:160px"></div><script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.13.0/lottie.min.js"></script><script>const loading = lottie.loadAnimation({ container: document.getElementById("loading"), renderer: "svg", loop: true, autoplay: true, path: "/loading.json",});</script>逐部分解释:
container是舞台,lottie-web 会往这里插入 SVG 或 Canvas。renderer: "svg"表示用 DOM 里的<svg>节点画,清晰、可缩放,也便于调试。path指向 bodymovin 导出的 JSON 文件,不是视频文件。- 返回的
loading是动画实例,后面可以pause()、play()、destroy()。
案例 2:用进度条控制动画帧
Section titled “案例 2:用进度条控制动画帧”<input id="seek" type="range" min="0" max="100" value="0" /><script>seek.addEventListener("input", () => { const frame = Number(seek.value); loading.goToAndStop(frame, true);});</script>逐部分解释:
goToAndStop(value, true)的第二个参数表示value是帧号,不是秒数。- 拖到第 40 帧,播放器就计算第 40 帧所有图层的状态,然后停在那里。
- 这就是 Lottie 比 GIF 强的地方:GIF 只能播放,Lottie 可以暂停、跳帧、分段播放。
案例 3:切换 SVG 和 Canvas renderer
Section titled “案例 3:切换 SVG 和 Canvas renderer”lottie.loadAnimation({ container: document.querySelector("#hero"), renderer: "canvas", loop: 3, autoplay: true, path: "/hero.json",});逐部分解释:
renderer: "canvas"只留下一个<canvas>,适合图层很多、无需单层交互的动画。loop: 3表示循环 3 次后停止,不是只能传布尔值。- 如果动画里的文字需要被复制、屏幕阅读器读取,SVG 通常比 Canvas 更合适。
- 如果页面里同时挂很多复杂动画,Canvas 可能更稳,但仍要实测低端机。
-
把 Lottie 当视频用:只想播一次开屏可以,但如果要实时改数字、图表或进度,应该用 SVG/Canvas 自己画,原因是 Lottie 更像预录时间线。
-
AE 特效不是全支持:motion blur、粒子、复杂表达式、视频和音频等能力可能导出后失效,原因是 JSON 播放器只实现了 AE 的一部分。
-
没锁 bodymovin 和播放器版本:设计师插件升级后可能导出新字段,旧播放器不一定认识,原因是格式和运行时是两条发布线。
-
忘记销毁实例:SPA 页面切换后动画还挂着 RAF 或资源,原因是
loadAnimation创建了真实运行时对象,离开页面要anim.destroy()。
适用 vs 不适用场景
Section titled “适用 vs 不适用场景”适用:
- 开屏、空状态、loading、成功反馈、品牌插画这类线性或半线性的动效。
- 设计师已经在 AE 里完成时间线,工程团队只负责接入和触发。
- 同一份动效要给 Web、iOS、Android 多端复用。
- 需要比 GIF 更清晰、更可控,并且愿意接受一个播放器运行时。
不适用:
- hover、drag、layout transition 这类组件级交互动画 → 用 framer-motion 或 CSS。
- 多段精细编排、滚动联动、复杂时间轴 → 用 gsap 更合适。
- 带状态机的互动角色或仪表盘 → 看 rive。
- 大量粒子、3D、物理碰撞或游戏场景 → 用 threejs、pixi 或游戏引擎。
历史小故事(可跳过)
Section titled “历史小故事(可跳过)”- 2015 年前后:设计师在 AE 做动效,工程师常见交付物是 GIF、视频,或者一堆需要手工复刻的关键帧。
- 2017 年:Lottie 对外被广泛介绍,核心口号是让设计师创建并交付动画,不再让工程师痛苦复刻。
- 后来几年:Web、iOS、Android、React Native 等播放器围绕同一份 JSON 生态成长,Lottie 变成跨端动效交付的默认选项之一。
- 2022 年以后:lottie-web 维护节奏明显放缓,但项目仍有大量存量使用;生产环境更应该锁版本、做回归测试。
- Lottie 的真正价值不是”动画更炫”,而是把设计稿变成机器可读、跨端可播放的格式。
- JSON 里保存的是图层和关键帧,播放器每帧做插值和渲染,所以它能暂停、跳帧、分段。
- SVG、Canvas、HTML renderer 没有绝对优劣;选择取决于图层数量、交互需求、可访问性和性能预算。
- 用 Lottie 等于引入一条设计工程流水线:AE 约束、导出版本、播放器版本、低端机性能都要一起管。
- 官方仓库:airbnb/lottie-web —— Web 播放器、bodymovin 插件和 README 示例。
- 官方文档:Lottie Docs —— API、导出说明、FAQ 和示例入口。
- 介绍文章:Introducing Lottie —— 了解这个项目最初想解决的设计交付问题。
- AE 导出说明:bodymovin / lottie wiki —— 查支持哪些 AE 特性。
- framer-motion —— React 组件级动画,对照 Lottie 的素材播放边界。
- gsap —— 时间轴和滚动动画,对照 Lottie 的设计稿交付边界。
- framer-motion —— 工程师在 React 里声明组件状态,Lottie 更偏设计师导出的时间线。
- gsap —— GSAP 擅长命令式编排,Lottie 擅长播放已设计好的动效素材。
- rive —— Rive 把状态机和数据绑定放进动画文件,补上 Lottie 交互弱的地方。
- svg —— lottie-web 默认常用 SVG renderer,矢量缩放和 DOM 可调试性都来自它。
- canvas —— Canvas renderer 适合复杂图层但牺牲单个元素的 DOM 交互。
- react —— React 项目里常用 wrapper 接 Lottie,同时要处理组件卸载时的销毁。
- anime —— anime.js — 一行 JS 让网页元素按时间线动起来
- cocos2d-x —— Cocos2d-x — 一份 C++ 代码把 2D 手游跑遍 iOS / Android
- d3 —— D3.js — 不是图表库,是写图表库的乐高
- dragonbones —— DragonBones — 国产开源 2D 骨骼动画运行时
- echarts —— Apache ECharts — 给一个 JSON 就能画图的可视化库
- gsap —— GSAP — GreenSock 高性能动画
- mlt —— MLT — 藏在 Kdenlive 和 Shotcut 背后的视频编辑引擎
- motion-one —— Motion One — 把动画交给浏览器自己跑
- pixi —— PixiJS — 浏览器里画 2D 的高性能 GPU 引擎
- rive —— Rive — 把矢量动画做成可交互组件的运行时
- shaka-player —— Shaka Player — Google 流媒体播放器
- spine-runtimes —— Spine Runtimes — 2D 骨骼动画运行时