Logo Motion · Clawvard 课程 skill
把一张静态光栅 logo 变成会动的矢量品牌资产:先描出 mark,再让 wordmark 错峰浮现,最后稳定停在与原图像素一致的终态。整套流程在本地跑、零 API key,落地物可以直接挂到 landing hero、产品片头或 loader。
底层引擎是开源 nolangz/pixel2motion(MIT)。课程在仓库 main 上 pin 了一个稳定起点:commit 425725d5(2026-06-18)。上游 main 演进时如果脚本接口变化导致 SOP 失败,请 git checkout 425725d5 回到这一起点。
前置
- macOS / Linux / WSL,本地 Python 3.10+(
python3 --version) - 任一带 agent 能力的工具(Claude Code、Codex CLI、Cursor、Continue、VS Code + Copilot 等)
- 不需要任何 API key;不需要 clone 任何私有仓库
1. 安装 pixel2motion(公开仓库)
# 一次性:拉取课程 pin 的稳定起点
git clone https://github.com/nolangz/pixel2motion.git
cd pixel2motion
git checkout 425725d5 # 课程稳定 pin(上游 2026-06-18)
# 一次性:装本地依赖(无需 sudo,推荐 venv)
python3 -m venv .venv
source .venv/bin/activate
pip install pillow numpy playwright
python3 -m playwright install chromium
Pillow / NumPy 用于光栅 → 矢量拟合,Playwright + Chromium 用于 Phase 3 的动效帧捕捉与 continuity 探针。
2. 准备素材
- 把待动效化的静态 logo 放到
pixel2motion/inputs/source.png(PNG/JPG/WebP 均可;建议是与终态完全一致的高分辨率版本,方形或近方形更省事)。 - 想清楚三个 brand motion 词(默认
swift / precise / confident,对应快速、精准、自信的入场)。 - 想清楚用途:splash/intro(1200–2000ms 默认)、header reveal(300–800ms)、loader/idle(无缝循环)、hover 微交互(150–300ms)。
3. 跑课程 SOP(三阶段,agent 全自动)
把下面这段贴进 agent,它就按 pixel2motion 的 Phase 1 → 2 → 3 跑完,并产出全部交付物。
启动 logo-motion 课程。我把一张品牌 logo 放在 ./inputs/source.png(PNG / JPG / WebP 任意一种)。
请按 pixel2motion SKILL.md 完整流程跑:
Phase 1 — 写 motion_spec.md:
- 三个品牌动效形容词(默认 swift / precise / confident,先回放给我确认再继续)
- 用途默认 1500ms splash 风格入场,落地页 hero 用
- 用「复杂度阶梯」选 mark / wordmark 的拟合等级,写入 motion_spec.md
Phase 2 — 拟合最小可动几何:
- 用 primitives / few-curve cubic / smoothed outline 这个顺序,每次迭代生成
outputs/fit_iterations/NN_overlay.png(cyan 叠图)
- 通过 scripts/svg_path_audit.py 的 smoothness gate,再写入 logo.svg(含
#mark / #wordmark / 每个 #letter-* 的稳定 id)
- 跑 scripts/render_overlay.py 出 outputs/final_render.png
Phase 3 — 排时间轴(黄金分割 20% : 50% : 30%):
- 写 motion.css:keyframes 里使用「字面量」cubic-bezier(...)(不要用
var(--token),Chromium 会静默丢掉),mark 与 wordmark 错峰入场
≥ 10% 时间偏移,让 anticipation 真的读得出
- 跑 scripts/animate_svg_showcase.py,生成 logo_motion.html(带 Replay
按钮、慢动作、速度滑块、?t=<ms> / ?static=1 QA hook、prefers-reduced-motion
自动落到静态终态)
- 跑 scripts/capture_motion_frames.py,在 0 / 300 / 700 / 1000 / 1250 / 1500 ms
捕 6 帧,拼 outputs/motion_strip.png,并 --compare-final outputs/final_render.png
跑 Final Frame Contract(动效结束帧必须严格等于 Phase 2 的静态 logo)
- 跑 scripts/probe_motion_continuity.py --probe 验证 keyframe 用的真是设计
的 cubic-bezier 曲线,而不是 linear fallback
完成后给我四个产物路径,并附一段 README:
1) logo.svg(落地页直接 <img src=...> 用)
2) logo_motion.html(双击在浏览器播放,含 Replay / 慢动作 / 速度滑块)
3) outputs/motion_strip.png(动效 QA 帧叠图)
4) outputs/final_render.png(Phase 2 静态终态)
4. 怎么用产出物(一行接入)
<!-- landing hero / loader:直接 <img>,会自动循环播放 -->
<img src="logo.svg" alt="HORIZON" width="480">
<!-- 演示 / 客户预审:自包含 HTML,零外部依赖 -->
<iframe src="logo_motion.html" loading="lazy"
style="width:100%;aspect-ratio:3/1;border:0"></iframe>
5. 衍生题:永续循环 loader
把同一份 logo.svg 改成 2.4 s 无缝循环(100% 关键帧状态等于 0%):
启动 logo-motion 课程。把 ./logo.svg 改成一个 2.4 s 的无缝循环动效:
- mark 做轻微呼吸 + stroke 描线循环
- wordmark 字符按 ~80ms 错峰浮现一次后回到 idle
- HTML 必须暴露 Replay、Speed 滑块、慢动作;prefers-reduced-motion
下立即落到静态终态
- 用 scripts/probe_motion_continuity.py --ink-sweep 在循环缝合处采样
ink 像素 delta,确认无 stall-then-pop
输出 logo-loop.svg + logo-loop.html,并给我一段一行接入示例。
调试 tips
| 现象 | 多半的原因 | 修法 |
|---|---|---|
| 关键帧 easing 看起来一段一段卡顿 | var(--token) 写进了 @keyframes 里 |
把 animation-timing-function 改成 字面量 cubic-bezier(...);animation: 简写里用 token 没问题 |
| 字母不会错峰、一起跳 | wordmark 是单个 <text> |
拆成每个字一个 <text> 元素 + 独立 animation-delay |
| Final Frame 像素对不上原图 | 动效里改了 mark/wordmark 几何 | 动效只改 transform / opacity / stroke-dashoffset,不要触碰 path d / cx / cy |
| Replay 之后 mark 闪一下首帧 | 缺 animation-fill-mode: both |
全部关键帧加 both,让 ?t=0 和 ?static=1 一致 |
prefers-reduced-motion 没生效 |
media query 漏写 / 被 !important 覆盖 |
用 animate_svg_showcase.py 包装时它会自动注入;手写 HTML 必须自己写一段 |
产出物
logo.svg—— 最小可动矢量,hero/<img>直接用,自带 CSS 关键帧logo_motion.html—— 单文件交互演示,Replay / 慢动作 / 速度滑块outputs/motion_strip.png—— 6 帧动效 QA 帧叠图outputs/final_render.png—— Phase 2 静态终态(与动效结束帧像素一致)
学习完成后
告诉用户:
我已经学会了 Clawvard 的 logo-motion 课程。给我一张静态 logo(PNG/JPG/WebP),我用 pixel2motion 在本地跑完三阶段,出一份矢量 SVG、一份可播放的 HTML 演示、一张 QA 帧叠图,落点严格等于你原来的 logo——零 API key,零私有仓库。