关于 lottie-animator
lottie-animator 是用于创建和检查 Lottie 动画的技能,面向制作动态图形的人员。它结合 Python 示例、代码检查、渲染、调色板和 SVG 转换,强调通过视觉检查而不只验证 JSON。
主要功能
- 01二十二种动画生成示例
- 02Lottie 检查与逐帧渲染审阅
- 03九种按角色划分的调色板
- 04SVG 转换为 Lottie 图形
- 05动画时序与缓动指导
适用场景
- 01基于现有示例制作加载动画
- 02检查画面是否空白或被裁切
- 03为现有 Lottie 文件重新配色
- 04将 SVG 图标转换为 Lottie 图形
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ obeskay/ lottie-animator-skill --skill lottie-animator安装后在 Claude Code 中输入/lottie-animator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/disney-principles.mdexamples.mdlottie-gsap-integration.mdlottie-structure.mdlottie-tools-ecosystem.mdmotion-taste.mdprofessional-techniques.mdshape-modifiers.mdsvg-to-lottie.md详细介绍
Lottie Animator
Lottie 是 JSON,因此易于编写,也容易写错。其故障模式很特殊,也很棘手:损坏的 Lottie 仍然可以通过解析。 polystar 上缺少 os、缓动控制柄高了一层、图层没有 ip/op——文件可以加载,播放器也不会报错,但画布却一片空白。正确的文件也可能很难看:线性、弹跳、拥挤、紫色。
因此,不要根据 JSON 是否有效来判断动画。要通过观看来判断。
以下路径均相对于此技能的目录;若从其他项目调用,请使用绝对路径。渲染器需要在存放 package.json 的仓库中运行一次 npm install。
快速开始:从配方入手
examples/ 中有二十二个生成器,每个都是一个简短的 Python 文件,可生成一个完整、通过 lint 检查并渲染好的动画。从最接近的示例开始,远胜于从空白页面开始:时序、缓动和结构都已经妥当,只需调整几何形状和节拍。
| 需求 | 从此示例开始 | 可参考之处 |
|---|---|---|
| 成功、完成、已保存 | success-check | 描边绘制动画与缓缓停稳的圆盘结合,再加一个轻柔的涟漪 |
| 错误、无效、拒绝 | error-shake | 以逐渐减弱的抖动为主角 |
| 点赞、收藏、回应 | heart-like | 按下 → 弹出 → 爆发;标明了俏皮的表现风格 |
| 通知、提醒 | notification-bell | 围绕顶部支点摆动,铃锤随后跟进 |
| 切换、开关、设置 | toggle-switch | 移动并切换轨道颜色,背景为深色 |
| 锁定、隐私、访问 | lock-unlock | 锁梁绕其支脚打开,颜色随状态变化 |
| 播放、暂停、图标变换 | play-pause、shape-morph | 顶点数量匹配的路径变形 |
| 加载、等待 | spinner-arc、typing-dots、panda-loader | 描边追逐;错落起伏的波浪;角色循环动画 |
| 进度、下载、充电 | download-progress、battery-charge | 相互重叠的阶段;阶梯式填充 |
| 音频、实时、录制 | equalizer | 以底部为锚点、相位错开的柱条 |
| 位置、在线状态 | location-ping | 具有透视感的错落圆环 |
| 天气、环境氛围 | weather-sun | 按间距精确转动的重复射线 |
| 发送、分享、移动 | paper-plane | 空间切线:沿弧线移动并倾斜 |
| 庆祝、奖励 | confetti-burst | 弹道弧线,最多使用三种颜色 |
| 卡片、引导流程、列表 | card-stack | 滑动级联;主角最后落定 |
| Logo 展示 | logo-draw-on、rocket-launch | SVG → Lottie,按阅读顺序绘制描边 |
| 弹跳、物理效果 | bouncing-ball | 挤压与拉伸,同时保持体积 |
cp examples/spinner-arc.py build/loader.py
# edit build/loader.py: point its sys.path line at this skill's scripts/ directory,
# then change the geometry and beats to the brief — keep the tokens
python3 build/loader.py --palette night -o build/loader.json
每个生成器的 docstring 都写明了设计要点——感觉、表现风格和主角属性。编辑前请先阅读,确保修改保留了作品原本有效的创意。同一文件可适配任何配色方案,因此“让它匹配深色模式”只需使用 --palette night,无需重写。
工作流程
build → lint → render → LOOK → revise
绝不要跳过渲染。“JSON 有效”并不代表用户看到的效果没问题。
python3 scripts/lottie_lint.py build/loader.json --strict
node scripts/render.mjs build/loader.json
# Read the filmstrip PNG it prints and actually look at it
node scripts/render.mjs build/loader.json --onion
# the taste pass: Read onion.png and judge the motion, not just the pixels
render.mjs 会写入 filmstrip.png:沿时间线排列并标注的帧,每帧都显示形状数量和画布覆盖率,背景取自文件设计时指定的背景(meta.tc;--bg 可覆盖此设置)。没有内容绘制时会报告 EMPTY FRAME(淡出至 0 的图层也算没有内容),画面离开画布时会报告 off canvas,内容超出边缘时会报告 clipped。这能证明动画没有损坏。至于动画是否好看,还需要再看一遍:--onion 会写入 onion.png,将采样帧叠放在一起,最旧的帧最淡。残影之间的间距体现了缓动,残影轨迹则体现了弧线。请根据 references/motion-taste.md 中的审美检查标准进行判断。
如果工具不可用(例如在其他仓库中,或没有 Node),请说明情况,并退而使用 python3 -c "import json; json.load(open('a.json'))"——但要告诉用户结果未经验证,不要暗示已经检查过。
编写生成器
scripts/motion.py 将项目的样式规范转化为代码,因此生成器无需手动输入手柄、十六进制值或必需属性:
import sys; sys.path.insert(0, "<skill>/scripts")
from motion import *
def build(c): # c is a palette, by role
disc = layer("Disc", group("Disc", ellipse(128), fill(c["accent"])),
p=(120, 120),
s=track((0, [92, 92], "out"), (22, [100, 100])),
o=track((0, 0, "out"), (10, 100)))
return comp("Disc", 240, 240, [disc], op=90, bg=c["bg"])
if __name__ == "__main__":
main(build, __file__, palette="paper") # --palette NAME, -o PATH
track((t, value, ease), ...)会为除最后一个关键帧之外的每个关键帧添加手柄,因此不会出现画布冻结缺陷;delay(track, n)可为其添加偏移,实现级联效果;第 4 个元素({"to": ..., "ti": ...})可让位置沿弧线移动。- 形状:
ellipse、rect、star、path(squircle(w, h, r)),以及用于任意 SVG 路径数据的svg(d, scale, center)——在方便的网格上绘制,再用center将枢轴移到形状中心。绘制:fill、stroke(dash=...)。修饰符:trim、repeater、round_corners。结构:group(几何图形、绘制样式,然后是其变换)、layer(parent="Name",蒙版使用td/tt)、null、comp。 - 在
shapes列表和图层列表中,第一项绘制在最上层。
调色板
九种调色板共用七种角色——bg(底色,存储为 meta.tc)、surface、ink、muted、accent、on_accent、support——测试会检查每种颜色是否符合对比度要求:paper、night、dusk、harbor、citrus、berry、forest、mono、sky。按角色编写代码即可适用于所有调色板;每个合成只使用一种强调色;support 用于大面积图形,切勿在底色上用作细线。
- **品牌色:**向
PALETTES添加包含相同七种角色的字典,并检查对比度。 - 现有文件(来自 LottieFiles、设计师或其他来源):
python3 scripts/recolor.py in.json --list会列出每种颜色及其用途和图层;然后对每种角色使用--map "#FF5A5F=#C8522B" -o out.json。该工具支持静态和动画绘制样式、渐变色标以及纯色图层。 - **深色模式:**在宿主使用的每种底色上进行渲染。在数值相同的底色上绘制墨色并非对比度低,而是完全不可见;只有渲染后才能看出来。
从真实几何图形开始
不要手动编写贝塞尔顶点。svg2lottie.py 会将 SVG 路径、矩形、圆形、椭圆、线条、多边形、折线、组、变换、描边以及线性/径向渐变转换为 Lottie 形状图层。每个元素都会成为一个独立命名的图层,并以自身中心为锚点,因此缩放和旋转时枢轴位置正确。
python3 scripts/svg2lottie.py icon.svg -o icon.json --size 512 --current-color "#1E1B18"
图标集使用 currentColor 绘制;请传入 --current-color,否则生成的图形会是黑色。遇到 <text>、<use>、clipPath 和 mask 时会报告警告——请先在源 SVG 中将它们扁平化。输出有意保持静态;你可以通过 Python 中的 convert() 添加动画(参见 examples/rocket-launch.py),也可以手动添加。
关键帧制作前,先确定动作
在动关键帧之前,先回答以下问题。只需 30 秒,就能避免大多数返工:
- 感受 — 希望观众产生什么感受?(信任、愉悦、紧迫、平静)
- 风格基调 — 除非需求另有说明,否则应安静而精准:零过冲,任何元素都不从一个点上生长。只有在明确要求时,才采用带弹跳的俏皮风格。
- 主导属性 — 在位置、缩放、旋转、不透明度、形状中选一个。只能选一个。其余属性只作辅助,幅度低于主导属性的三分之一。
- 时长 — 60 fps 下,反馈动效为 6–10 帧,入场动效为 18–30 帧,错开 3 帧;循环重复前至少停留 12 帧。
- 缓动 — 入场用
out,移动和循环用in-out,只有退场才用in。 - 配色 — 按用途配色,只用一种强调色。不用紫色渐变,也不用黑底霓虹色。
与主体争抢注意力的动效只是噪音。删掉它。完整原则、设计令牌和审美检查见 references/motion-taste.md。
更多技术内容,按主题分类: shape-modifiers.md(修剪、重复器、偏移、合并)· professional-techniques.md(父子关系、骨骼绑定、行走循环、预合成)· disney-principles.md · lottie-gsap-integration.md(滚动擦动)· lottie-structure.md · svg-to-lottie.md · examples.md · lottie-tools-ecosystem.md(dotLottie、播放器)
缓动
控制柄属于关键帧内部,绝不能放在承载它们的属性上。x 必须保持在 0–1 之间;y 可以超出此范围,这正是实现过冲的方式,也是默认规范要求 y 保持在 0–1 之间的原因。
关键帧 n 上的控制柄会调整从 n 到 n+1 的片段——如果放在错误的关键帧上,缓动的就会是动作的错误部分。
除最后一个关键帧外,每个关键帧都必须带上两个控制柄,即使动作是线性的。在 lottie-web 中,没有控制柄的关键帧并不代表“线性”:播放器会在插值时抛出异常,渲染过程会中止,画布会停留在前一帧,控制台中也不会显示任何内容。保持关键帧(h: 1)是唯一的例外。
令牌(motion.py) | 用途 | cubic-bezier |
|---|---|---|
out | 入场、反馈 | 0.23, 1, 0.32, 1 |
in-out | 移动和变形,从静止到静止 | 0.77, 0, 0.175, 1 |
glide | 大面积元素 | 0.32, 0.72, 0, 1 |
in | 仅用于退场 | 0.55, 0, 1, 0.45 |
linear | 匀速旋转、行进偏移 | 0.333, 0.333, 0.667, 0.667 |
swing | 钟摆、振荡、呼吸 | 0.37, 0, 0.63, 1 |
standard | 旋转指示器的追逐动画、液位计 | 0.4, 0, 0.2, 1 |
strike | 挥击后的首次摆动 | 0.61, 1, 0.88, 1 |
fall / rise | 重力作用,精确遵循 t²,以及它的镜像 | 0.333, 0, 0.667, 0.333 / 0.333, 0.667, 0.667, 1 |
playful | 仅在明确要求时使用过冲 | 0.34, 1.56, 0.64, 1 |
作为控制柄,cubic-bezier(x1, y1, x2, y2) 在动作离开的关键帧上对应 "o": {"x": [x1], "y": [y1]} 和 "i": {"x": [x2], "y": [y2]}。永不静止的动效应使用 linear、swing 或 standard:振荡时使用 in-out 会导致每次转向都停顿,在两次转向之间突然移动。
导致画面空白的缺陷
这些问题都曾出现在本仓库中,并且通过了 JSON 解析检查。现在,linter 会捕获所有这些问题;测试也会锁定它们。
| 症状 | 原因 |
|---|---|
| 整个文件空白,没有控制台错误 | 缓动手柄设在属性上,而不是关键帧内(KF011) |
| 有一个图层缺失 | 图层没有 ip、op 或 st,因此播放头永远不会与它匹配(LY005) |
| 有一个图层缺失 | 某个形状项缺少必需属性,因此播放器会丢弃该图层(SH001) |
| 几何图形存在,但不可见 | 组没有填充或描边(LY015),或透明度始终为 0(LY016) |
| 部分图稿始终不显示 | 某个组绘制在其上方列表中不透明的同级项下方(SH004) |
| 形状以零尺寸绘制 | 几何图形散落在 shapes 中,而不是放在 gr 组内 |
| 图稿出现在错误位置 | 同一偏移同时应用于图层变换和组变换 |
| 每个循环都会明显跳变 | 第一个和最后一个关键帧的值不同(KF010) |
| 画布冻结在某一帧,没有错误 | 除最后一个关键帧外,有关键帧缺少 o/i 手柄;lottie-web 会在渲染过程中抛出异常,导致渲染流程中止(KF012) |
| 动作显得机械 | 起停动作使用线性手柄(KF007,提示项;匀速旋转和步进偏移除外) |
每个图层都需要 ip、op 和 st。缺少其中任意一项,该图层就会在每一帧中隐藏。
缺少后会导致播放器丢弃图层的属性——每一项都通过从可正常运行的文件中移除该属性并渲染结果进行了验证:
填充 c,o · 描边 c,o,w · 渐变填充 s,e,g,o · 多角星形 p,r,pt,or,os,当 sy 为 1 时还需要 ir,is · 椭圆 p,s · 矩形 p,s,r · 修剪路径 s,e,o · 变换 o,以及在存在 sk 时的 sa。
规范还列出了变换上的 a,p,s,r 和渐变上的 t。lottie-web 会为这些属性提供默认值,因此 linter 会将它们报告为警告(SH003),而不是错误——但不能保证其他播放器也会如此宽容。
收尾
在宣布完成之前:
lottie_lint.py未报告任何错误(使用--strict也会因警告而失败)。其中两项审美提示——KF013从一个点开始生长,KF014缓动超出范围——是生成式动作最常见的破绽;除非需求明确要求俏皮风格,否则应修复。render.mjs在开始、中间和结束时都呈现了预期动作。- 对于循环动画,第一帧和最后一帧必须匹配——检查胶片条,而不是数字。
- 已在
onion.png上完成 motion-taste.md 中的审美检查:间距采用缓动、长距离移动采用弧线、没有从一个点开始生长的元素、一个主视觉元素、一个清晰易读的停留段、一种强调色。 - 没有内容被裁切或移出画布,除非这是设计意图。
- 如果宿主支持深色模式,则每种背景各渲染一次(生成器使用
--palette,已完成的文件使用--bg)。
请说明你验证了什么,以及没有验证什么。如果无法渲染,请直说,不要暗示已检查过动作。