技术图解动画制作
把"讲不清的硬件原理"做成 15 秒黑底线稿动画。纯代码逐帧渲染:Canvas 出帧 → 无头浏览器截图 → ffmpeg 合成,不用任何素材图,不用 AI 生图。
这类片子的说服力来自两件事:一张剖面图和一个数字。不是情绪,不是运镜。
何时使用
适用:
- 用户要把一个反常识的硬件原理 / 工艺卖点 / 参数讲明白
- 参考风格是 Vibe知识大赏、工程拆解、剖面动画、黑底线稿科普
- 有真实参数(MPa、mm、℃、μm、%、天)可以落成画面
不适用(改用口播 / 数字人 / 图文):
- 纯情绪或品牌宣言
- 需要真人信任背书(招聘、招商)
- 一个数字都拿不出来的"理念"
开工前必须问清的三件事
- 一个反常识 + 一个数字分别是什么?(例:泡沫不为遮味 / 飞溅 −92%)
- 时长与画幅:默认 15s、1920×1080;视频号/抖音要不要 1080×1920 竖版
- 参数真值:压力、尺寸、角度、浓度……没有就问,绝不编造。
参数表里宁可写"示例参数,替换为真实工况",也不能给一个假数。
一次问完,别挤牙膏。用户答完再动笔。
工作流
Step 1 · 先出分镜表,别先画
按 6 镜结构写一张表交给用户确认(模板见 references/storyboard.md):
| 镜 | 时间 | 职能 | 画面 | 中文文案 |
|---|---|---|---|---|
| 1 | 0.0–2.6 | 立问题 | 剖面描出 + 引线 | 为什么,罐顶要空一段? |
| 2 | 2.6–4.9 | 否定直觉 | chip + 红叉 | 你以为,是怕溢出来? |
| 3 | 4.9–8.4 | 真答案 | 双面板 + −92% | 那 120 mm,是压力缓冲腔 |
| 4 | 8.4–11.4 | 落参数 | 射流 + SPEC | 同一段空间,还决定射流落在哪 |
| 5 | 11.4–13.4 | 收束 | 三环 | 缓冲靠它,导向也靠它 |
| 6 | 13.4–15.0 | 抛问题 | 大字 | 这是省料,还是余量? |
用户点头再写代码。分镜表都不过,码代码是白干。
Step 2 · 建项目
PY=/Users/apple/.workbuddy/binaries/python/envs/default/bin/python
SK=~/.workbuddy/skills/tech-diagram-animation/scripts
$PY "$SK/new_project.py" --out ~/Desktop/workbuddy/<项目名> --title "<片名>" --dur 15
# 竖版:--size 1080x1920
# 想从既有片子改:--example toilet-section-15s
产出:index.html(模板拷贝)+ project.json(尺寸/时长/fps/输出名)。
Step 3 · 只改三处
打开 index.html,改 A、B、C,其余不要动:
| 位置 | 改什么 |
|---|---|
A. META |
顶栏胶囊文字、章节名、右上规格标签 |
B. G + outerPath/innerPath |
主体几何。模板示例是通用罐体剖面,换成你的对象 |
C. SC + TIMELINE |
六镜的绘制代码与中英字幕;时间按字数重排 |
图元不够用时查 references/drawing-recipes.md,16 个函数可直接抄。
Step 4 · 先预览,再全片
$PY "$SK/build.py" --dir <项目目录> --preview # 每镜 55% 抽一帧拼图,约 20 秒
$PY "$SK/build.py" --dir <项目目录> # 全片,约 1–2 分钟
预览拼图看着不对就改,别直接渲全片。判断标准:每格截图单独看,能否在 1 秒内说出它在讲什么。
Step 5 · 自检并交付
ffprobe -v error -show_entries stream=codec_type,codec_name,width,height,r_frame_rate,duration \
-of default=nw=1 <成片>.mp4
ffmpeg -hide_banner -i <成片>.mp4 -af volumedetect -f null - 2>&1 | grep -E "mean_volume|max_volume"
交付:成片.mp4 + index.html(可改的下一条)+ 一句话说明改了哪三处。
present_files 一起抛出,视频在前。
视觉铁律(五条,违反任何一条就不像了)
- 纯黑占面积 86% 以上。一帧线稿铺满 30%,立刻从工程图纸掉成 PPT。
- 只用两个色相:青
#5FD0F0说事、琥珀金#F2B455说差异。金色不是纯橙(#FF8000会让画面变综艺)。 - 零转场特效。只有硬切 + 0.18–0.22s 淡出。动效全部花在元素"进场"。
- 一帧只讲一件事。超了就拆帧 —— 平均 2.5 秒一镜,有的是时间。
- 平均 2.6 秒一次构图重置。开头 2.0–2.6s、论证 2.8–3.4s、收尾静止 1.6–5s。
细节(字号网格、安全边距、竖版改法)见 references/visual-language.md。
管线(为什么不用 Remotion)
index.html 里的 renderFrame(frame) → Playwright 无头 Chrome 逐帧截图 → ffmpeg 合成
纯函数,可任意 seek 4 并发,450 帧约 60s 加颗粒/暗角/混 BGM
- 零 npm 依赖,改一行刷一下就能看
renderFrame必须是纯函数:t = frame/fps,不许有跨帧状态- 随机一律
mulberry32(seed),否则同一帧两次渲染不一样,视频会闪 - BGM 用 numpy 现算(
scripts/make_bgm.py),段落电平自动跟 TIMELINE 的切点换档
资源索引
| 文件 | 什么时候读 |
|---|---|
references/storyboard.md |
写分镜表、选题、文案句式、节奏表 |
references/visual-language.md |
配色、字号网格、构图、竖版 9:16 怎么改 |
references/drawing-recipes.md |
画剖面/水花/射流/尺寸线/角弧/波形/参数表时 |
references/pitfalls.md |
出黑帧、闪帧、音画不同步、字糊了 |
assets/template/index.html |
母版:通用罐体剖面,可运行,6 镜齐活 |
assets/examples/toilet-section-15s/index.html |
真实成片源码:泡沫防溅 + 扇形射流,两卖点合一 |
scripts/new_project.py |
建项目 |
scripts/render.py |
只渲帧(--frames 可指定帧号) |
scripts/build.py |
一键出片(--preview 只出拼图) |
scripts/make_bgm.py |
单独重做 BGM(可传 --hits 加撞击音) |
交付前最后一眼
- [ ] 6 个分镜每格都能一句话说清
- [ ] 有 1 个金色数字(−92% / 120 mm / 0.08 MPa)
- [ ] 字幕中英双语,
foot写了口径或出处 - [ ] 剖面有引线标注(4 条以内,右侧对齐一列)
- [ ] 全片零转场,只有硬切 + 淡出
- [ ] 时长与 project.json 一致(ffprobe 校验)
- [ ] 音量 max 不到 0dB