算法与数据结构 / 动画引擎原理 · 从插值到播放控制 / SVG 转 Lottie:补关键帧并导出 JSON 待审核 46 / 47
svg→lottie · 关键帧 IR · lottie-web

SVG 转 Lottie:补关键帧并导出 JSON

动画即数据那页说清了 Lottie 的本质——把关键帧这套「时间到值」的中间表示序列化成 JSON,交给运行时渲染器逐帧插值。本页把这个结论做成可运行的工具:粘贴一张静态 SVG,选一个预设自动补上关键帧,即时生成一份真正的 Lottie JSON,交给工业渲染器 lottie-web 当场播放并可导出。

这一页刻意走出系列其余各页坚持的手写 @vega/anim,目的正是产出一份工业格式的真实产物,把「SVG 到补关键帧到序列化到工业渲染器播放」这个实战环节补齐。

1 · 从静态图到可播放动画

解析时把 SVG 的每个顶层元素拆成一个 Lottie 图层。circle / ellipse / rect / line / polygon 与只含 M/L/H/V/C/S/Q/T/Zpath 直接转成原生矢量 shape layer;遇到椭圆弧 A、渐变、滤镜、带 transform 的元素或 <g> 整组,则把那一块降级为内嵌 SVG 的 image layer。

图 1-1 · 从静态 SVG 到可播放 Lottie 的完整链路。可改左侧 SVG、换预设与帧参数,右侧由 lottie-web 播放,下方是生成的 JSON。

2 · 字段从哪来

表 2-1 · 生成的 Lottie 字段与其 SVG 来源。
Lottie 字段 含义 从 SVG 或预设推出
w / h / fr / op 画布尺寸、帧率、总帧数 viewBox 定尺寸,其余由滑块给
layers[].ty 图层类型 可矢量化元素为 4,回退元素为 2
el / rc / sh 椭圆、矩形、任意路径 元素几何;path 段转 bezier 顶点
fl / stc 填充与描边色 fill / stroke 解析成 0–1 的 RGBA
ks 里的锚点与位置 变换中心与落点 元素 getBBox() 形心
kso/p/s/r 关键帧 透明度、位移、缩放、旋转轨 预设按层号加 stagger 自动填
tm 路径自绘 Draw 预设,等价于 dashoffset 自绘

锚点取形心这一条容易漏。Lottie 的缩放与旋转绕锚点进行,锚点默认在画布原点;不把 a 设成元素形心,Pop 预设的缩放会从画布左上角展开而非从元素自身中心。

3 · 转换的实质是补关键帧

静态 SVG 只有形状,没有时间维度;Lottie 等于形状加关键帧动画轨。所以转换器里真正「无中生有」的是动画,形状部分只是把几何从一种矢量表示搬到另一种。

警示 · 本页转换器只覆盖常见 icon 的子集。椭圆弧 A、渐变、滤镜、带 transform 的元素与 <g> 整组都走 image 回退——它们仍能播,但不再是逐形状矢量,缩放与旋转以画布中心而非元素形心为轴。这个边界是明示的:读数会给出有几层走了回退。工业级转换处理面要全得多。

注 · pathToShapes 遇到 A 直接返回 null 而非试着近似。椭圆弧转三次贝塞尔需要按角度分段(每段不超过 90°),逼近误差随弧长增长——与其给出一条形状略有偏差的矢量路径,不如整层退回 image,让它至少像素级正确。这是「明示降级」与「静默失真」之间的取舍。

生成的不是截图也不是视频,而是一份矢量的关键帧数据。改任意一个数即改动画,任意分辨率不糊;因为它编译成一条可被纯函数采样的时间轴,lottie-websetSpeedgoToAndStop 全部免费。

每条轨的值怎么插见插值,逐段快慢见缓动,多轨多层排到一条轴见关键帧与编排;手写解释器播同类数据见动画即数据,真实工业流程见 CSS 之外的动画做法