Claude Opus 5.5 写代码画出一支手绘 MV:拆解做法,教你用开源模板自己做
推特用户 NotinReality 把歌词和音频交给 Claude Opus 5.5,它写 JavaScript 逐帧画出一支 156 秒的水彩手绘 MV,全程没用生图或生视频模型。本文拆解两轮生成的差别、模型怎么分章节并行干活,再手把手教你用作者开源的 ClaudeAnimationBase 做自己的动画。
这支动画 MV 是 Claude 写代码画出来的:不调用任何现成的 AI 视频生成模型,而是让 Claude Opus 5.5 直接写 JavaScript 代码,利用网页画布引擎逐帧画出 156.6 秒的手绘水彩动画。
这支 MV 叫《I'm Upping My P(doom)》。P(doom) 是 AI 圈的说法,指“AI 给人类带来灭顶之灾的概率”,歌名意思就是“我在调高我的末日概率”。MV 出自推特用户 NotinReality(原推文,YouTube 版)。画面是老式绘本的质感:水彩纸纹理、微微抖动的毛笔墨线、踩着节拍的动作和很多表情戏。
这首歌原本配的是另一位创作者 @slimer48484 发的 3D MV,舞者是向日葵头的人形角色。NotinReality 的版本是拿同一首歌翻做的:
作者 NotinReality 沿用了原版的音轨,直接把歌词和音频交给 Claude,只要求使用 Clawd 角色、给每句歌词有趣画面和转场,没指定任何场景创意,仓库里所有东西均由模型生成(源码见 PDoomVideo)。随后,作者还把整套动画生产管线开源成了起步模板 ClaudeAnimationBase。
哪怕你平时不写代码,只要跟着本教程在电脑上配置好基础工具,也能借助 Claude Code(或其他编程 Agent)做出属于你自己的手绘风动画。
一、幕后拆解:这支手绘 MV 是怎样诞生的?
作者公布的过程只有两轮,代码全部由模型写。
1. 从 Flash 风到水彩绘本
第一代版本(Gen 1,代码保留在仓库的 legacy/ 目录)诞生时,作者只把歌词和音频文件粘贴给 Claude,让它做一个“可爱的动画”,开启的是 Medium(中等)推理能力。
模型很快返回了一套基础动画:画面呈现出扁平纯色块、粗描边,以及大量文字标签和气泡(比如“AGI?”、“LOSS”、“don't eat me!”),整体接近 2000 年代的 Flash 风格。
第二轮,作者提了这几条要求:
- 将推理能力调到最高档(xhigh reasoning)。
- 使用 p5 笔刷风格(
p5.brush,给 p5.js 加水彩和毛笔笔触的库)。 - 场景更有趣、每个场景都有看头。
- 每个场景都转场过渡到下一个。
第二轮中,Opus 自己写的分镜 STORYBOARD.md 里定了:画面少用字,全片只用少量拟声大字(FOOM、CHOMP 之类),不做标签和说明文字,也不做重复歌词的牌子,因为卡拉 OK 字幕已经有了。所以成片里的字主要是底部歌词字幕和 P(DOOM) 道具牌。
据作者说,这一轮跑了约 45 分钟。对比同一句歌词的画面:
2. 第二轮的制作结构:分镜构思、拆章与子 Agent 并行
第二轮的活是这样分的:Opus 先写 STORYBOARD.md,将整片构思为一场失控的舞台剧,由幕布开场、幕布谢幕,Clawd 从显示器里的小涂鸦逐步成长为星球大小,拖着研究员穿梭在歌词里的各种 AI 末日梗中;P(doom) 温度计作为舞台实体道具,每次副歌被打气筒打高(8→34→61→86→99.9);直到最后一句“Was it all for show?”揭示一切只是一场舞台演出。随后,Opus 把整首歌拆成 9 个章节,每章对应一个代码文件;并写了一份 ANIMATION_GUIDE.md 给并行的子 Agent 做简报,每个子 Agent 只改自己负责的那一章,在共享文件中发现 bug 只报告不改;最后由 render.mjs 在无界面 Chrome 里逐帧渲染,通过 ffmpeg 合成为 MP4。
3. 起步包里的规则书
MV 做完后,作者又发布了一个起步包。包里的《动画制作指南》(ANIMATION_GUIDE.md)基于这支 MV 的代码,以及对“模型哪些做得好、哪些做得不好”的分析整理而成。它先定了三个目标:
- 手工感:像有人一帧帧手画的,笔刷笔触、会轻微抖动的墨线、平面 2D、不写字。
- 活着:画面里一直有东西在动、有事在发生,表情是演出来的,角色要够大。
- 一个整体:是一部短片,不是一堆片段拼起来,先规划再画,每个场景都连到下一个。
三个目标之下还有一条底线:观众得能看懂。指南特别提醒,节奏是模型最常出错的地方。下面是具体规则里最关键的几条:
规则一:纯粹的平面手工质感(Solid Medium & Boil)
- 绝不用常规几何图形:严禁用 p5.js 原生的
rect()、ellipse()或普通纯色填充,那样画出来会像 2000 年代的 Flash 动画;全部使用p5.brush绘制,角色和道具用平涂色块(wash)加墨线轮廓,天空、山丘、阴影用带晕染边缘和颜料纹理的水彩(fill)。 - 让墨线“沸腾”起来(Boiling Linework):传统手绘逐帧动画中,由于每一帧线条都是手画的,笔触边缘会有轻微的抖动。模板让线条的随机抖动每秒换 12 次(
BOIL),所有线条都会轻轻颤动,看起来像一帧帧手画的。 - 坚决不搞 3D 投影:不做三维透视旋转,不使用 WebGL 3D 假装立体。角色转身完全模仿传统手绘设定集,只依靠绘制好的正面、四分之三侧面、正侧面、四分之三背面和正背面等 5 个关键视角(Key Views)进行切帧过渡。
- 颜色按颜料混:p5.brush 的颜色像真颜料一样混合,黄色涂在蓝色上会变绿。所以发光的东西统一用
glow(),它是真的叠加光,不会被混成脏绿色。
规则二:严禁画面文字(No Text)
- 大语言模型生成动画时极度依赖“文字标签”(角色迷路了就举个牌子写“我迷路了”)。指南直接将这种做法定为典型失败案例。
- “展示它,而不是写出它”:所有的情绪必须靠角色的动作、眼神、道具以及视觉符号(如汗滴、问号、爱心、头顶灯泡、乌云)来表达,严禁在画面里打对话泡泡。
- 例外:真的需要字时(比如一个名字、一块本身就是笑点的招牌),可以用
letter()把一两个词画进场景,只用一次。用户明确要求加字幕时,也照用户的来。
规则三:为观众的眼球设计节奏(Timing: Model the Viewer)
代码生成的动作最容易犯的毛病是“机械感”:所有东西以匀速移动,所有事件一股脑堆在一起,观众还没看清就结束了。指南提出了一个核心原则:“在设计时,脑子里要时刻为观众建模(Timing: model the viewer)”。
- 拆解认知单元(Write the reads):一个镜头里观众需要看懂几件事?一次只能发生一件事。
- 动作要快,意义要慢(Fast actions, slow meanings):动作本身可以一闪而过(如挥棒、摔倒),但在动作前必须有“预备动作”(Anticipation,比如出拳前的后仰引臂),在动作结束后必须有足够的“停留时间”(Hold),让观众看清结果并产生情绪共鸣。
- 实战案例:指南在结尾给出了一个实际例子——示例片结尾的第一版把掷星星、星星飞回、闪光、爱上、挥手告别、星星回应、收尾全挤在约 1.3 秒里,没人看得懂;后来改成依次出现的 6 个信息点,拉长到约 4 秒(6.95–11.0 秒),让每个信息点都有足够时间被观众看清。
其余四条规则
- 每个镜头都要发生一件事:镜头开头和结尾之间要有变化,比如想要、发现、尝试、失败、反应、得到。“Clawd 站在草地上卖萌”不算一个镜头。先有原因再有反应,埋下的伏笔要有交代。
- 画面要活着:永远有东西在动,比如待机小动作、镜头缓慢推移、草在摆,完全静止的画面看起来像 bug。中景里 Clawd 要够大,所有动作共用一个节拍。
- 每个接缝都要转场:开头、镜头之间、结尾都要有,不能硬切,也不能突然停。转场要跟剧情有关,别每次都用同一种,可选笔刷擦除、圆形遮罩、甩镜、形状匹配剪辑、动作中剪切等。
- 先有整体构思再写代码:动手前先写分镜,想清楚整片讲什么、反复出现什么、结尾怎么呼应开头。
二、动手实操:用 ClaudeAnimationBase 制作你的第一段手绘动画
作者在完成 MV 后,将整套精炼的动画引擎抽离出来,整理成了任何人都可以直接拿来玩的脚手架:ClaudeAnimationBase。
你不需要自己去调教 p5.js 或写复杂的底层渲染逻辑,模板里已经准备好了角色、31 种表情、节拍工具和后台渲染脚本。
1. 环境准备
需要准备四样东西(Mac、Windows、Linux 都能用):
- Node.js(用于运行脚本)
- Google Chrome 浏览器(用于离线逐帧渲染画布)
- ffmpeg(用于将生成的图片序列与音频压制成 MP4 视频)
- Claude Code(或其他支持文件读写与终端命令的 AI 编程工具)
硬件性能提醒: 没有独立显卡时水彩填充会慢到每帧几秒,可让模型换掉水彩填充。我们在 M3 Max(无独立显卡的苹果芯片)上实测示例每帧约 0.16 秒,供参考。
2. 安装与项目目录
打开电脑终端,依次输入以下命令下载模板并安装依赖:
# 1. 克隆起步仓库
git clone https://github.com/JohnHeibel/ClaudeAnimationBase.git
cd ClaudeAnimationBase
# 2. 安装项目依赖(包括 p5.js、p5.brush 和 puppeteer-core)
npm install
项目核心文件一览:
ANIMATION_GUIDE.md:核心制作规范与 API 参考文档(务必让 AI 先读这篇)。src/clawd.js:核心主角 Clawd 的绘制逻辑(包含视角、五官、帽子、动作、情绪)。src/core.js:底层水彩画笔、摄像机推拉、节拍计算与光照辅助工具。src/timeline.js:多镜头串联与转场(如毛刷擦拭转场brushWipe)。src/config.js:全局设置,包括总时长(duration)、歌曲速度(bpm)和音频路径。src/scenes/:你编写的动画镜头文件存放处(自带demo.js)。render.mjs:离线渲染脚本,支持输出缩略图拼图、局部特写检查图以及最终 MP4。studio.html:本地调试网页,用 Chrome 打开就能拖动进度条预览。
3. 主角 Clawd 与 31 种情绪设定
模板默认的主角叫 Clawd(Claude Code 的吉祥物,一个红陶色小方块):身体是宽 10 单位、高 6 单位的红陶色块,长着四条小短腿、两只小手和两只长条缝隙眼睛。
模板已经内置了多达 31 种生动的预设情绪,不需要你手动画表情:
31 种表情从开心、得意到暴怒(盖子像饭盒一样掀开露牙)、晕眩、KO,多数带画出来的小符号(汗滴、问号、爱心、灯泡、zzz、雨云)。
表情切换是演出来的、不是瞬间跳。换表情用 emotions(),给出时间和表情序列,它会自动做预备、眯眼、惊讶反应和回弹,例如 emotions(lt, [[0, 'bored'], [1.2, 'surprised'], [1.7, 'excited']]);而 feel() 是每种情绪自带的待机小动作。
4. 驱动 Claude 制作新动画的提示词模版
准备好之后,在项目目录里启动 Claude Code。作者给的示例其实只有一句话:
Read ANIMATION_GUIDE.md, then make a 15-second video of Clawd trying to catch a butterfly.
(先读 ANIMATION_GUIDE.md,然后做一个 15 秒的视频:Clawd 想抓一只蝴蝶。)
据 README,光这一句,模型就会先写分镜、逐个镜头制作、渲染缩略图拼图自查,最后输出 out/video.mp4。
下面两段是我们按指南扩写的版本,把“先出分镜、你确认后再写代码”拆成两步,方便你在中间改分镜。README 本身也建议可以让模型先给分镜再动手。
第一步:让 Claude 研读指南并产出分镜(Prompt 模板)
请首先完整阅读项目根目录下的 ANIMATION_GUIDE.md,深入理解其中的手绘水彩画风、禁止使用屏幕文字、保持画面始终在动、以及“以观众视角建模时间节奏(Timing: Model the viewer)”等核心规则。
我希望制作一段时长 15 秒的短动画,主题是:“Clawd 在阳光明媚的草地上追逐一只发光的蝴蝶,扑空后摔倒,最后蝴蝶落在了它的鼻尖上,相视一笑。”
请不要直接写代码。先根据规范编写 STORYBOARD.md 分镜文档:
1. 确定一句话剧情主线(Logline)、视觉世界设定(World)和调色板;
2. 规划 Clawd 全片的情绪弧线(Emotional Arc);
3. 拆解具体镜头(A、B、C...),明确标注每个镜头的起止时间、进出场转场方式、镜头焦点事件(Event)、观众认知单元(Reads)以及眼睛引导路径。
分镜写好后向我汇报,等待我确认。
第二步:确认分镜后,生成场景代码
当 Claude 给出合理的分镜后,发送第二条指令:
分镜方案非常棒!现在请开始动手编码:
1. 在 src/config.js 中配置正确的时长;
2. 在 src/scenes/ 下新建一个专属的场景文件(如 butterfly.js),参考 demo.js 的结构,将分镜逐个镜头实现,确保每一帧都是时间 t 的纯函数,并正确使用 boilSeed(key) 保证噪波线稿不发生异常抖动;
3. 将 studio.html 中的脚本引入更新为新的场景文件;
4. 运行缩略图拼图渲染命令,生成几个关键时刻的缩略图拼图(Contact Sheet),自检动作轮廓是否清晰、是否有违规文字、转场是否平滑。
作者在 README 里还建议多试几种玩法:
- 让它先给分镜再写代码;
- 指令给得很宽泛,或者很具体,两种都试。作者发现它用很少的指令就能做出很多东西,要求具体时也做得很准;
- 让它用子 Agent 并行做;
- 让它换掉 Clawd、加新表情或服装;
- 给它你自己的参考图。
5. 质量审查自检循环(The Review Loop)
这是由代码生成动画最核心的秘诀:AI 和人都不能只看代码脑补画面,必须把关键帧渲染成图像来“肉眼复查”。
render.mjs 提供三种检查图,渲染很快(指南说拼图每帧约 0.1–1 秒):
# 1. 缩略图拼图(Contact Sheet):快速查看整部片子的关键节奏点(比如第 1、4、8、12 秒)
node render.mjs --sheet=1.0,4.0,8.0,12.0 --cols=4 --w=320 --out=out/check/sheet.jpg
# 2. 连续动作胶片带(Strip):逐帧检查一次跳跃、转身或表情突变的连贯性(检查 2.0秒 到 2.5秒)
node render.mjs --strip=2.0:2.5 --cols=6 --w=320 --out=out/check/strip.jpg
# 3. 局部高分辨率裁剪(Crop):检查面部表情微动作、脚底是否贴地、手中的道具是否悬空
node render.mjs --sheet=4.5 --crop=760,420,500,400 --w=500 --out=out/check/face.jpg
指南要求模型打开这些图片实际看,Claude Code 能读图片,所以它会自己看图找问题。
6. 本地实测数据与最终压制成片
我们在本机实测(运行环境:搭载 M3 Max 芯片的 MacBook,Node.js v22,自带 Chrome 自动识别):
- 运行 6 帧缩略图拼图抽检:仅耗时 14.3 秒(每帧渲染耗时约 73–307 毫秒)。
- 完整渲染模板自带的 11 秒演示片段(264 帧 @ 24fps)并压制为 MP4:总耗时 47.5 秒(平均每帧 157 毫秒),输出了一份 10.8MB 的高清 MP4 文件。
按照同样速度推算,一首 156.6 秒(约 3758 帧)的完整 MV 离线渲染大约需要 10 分钟(没有实测,场景越复杂越慢)。
当你调试满意后,只需一条命令即可导出终稿:
# 直接离线渲染全部画幅,并使用 ffmpeg 封装成 MP4
node render.mjs --clip --out=out/my_animation.mp4
# 如果有背景音乐,在 src/config.js 中配置好音频,或直接加上参数:
node render.mjs --clip --audio=assets/music.mp3 --out=out/my_mv.mp4
7. 做成 MV:配上你自己的歌
如果想把动画做成一支完整的 MV,可以参考指南的音乐规范与 NotinReality 的做法:
- 步骤:把歌放进
assets/;在src/config.js设bpm(每分钟节拍数)和offset(第一个重拍的秒数),所有待机、蹦跳、舞蹈就踩在拍子上;剪切和大动作落在拍子上,每个乐句配自己的画面。 - 歌词字幕:指南默认“歌词不上屏,用表演表达歌词意思”;想要 NotinReality 那样的卡拉 OK 字幕或歌词动效,要在提示词里明确说,指南写了用户要求优先。
- 授权提醒:公开发布用有授权的歌;这首歌作者自己也只查到来自 2024 年的一个 YouTube 视频。
可复制的 MV 提示词模板:
请先阅读根目录下的 ANIMATION_GUIDE.md。
我想制作一首歌曲的完整手绘动画 MV。音频已放在 assets/music.mp3,以下是带有时间轴的歌词:
[粘贴歌词与时间点]
制作要求与流程如下:
1. 先测算歌曲的 BPM 和第一个重拍秒数 offset,填进 src/config.js;
2. 先写分镜 STORYBOARD.md 给我看,每句歌词都要有有趣的画面,每个场景都转场到下一个;底部保留卡拉 OK 字幕;
3. 确认后按章节拆开,用子 Agent 并行做,每章一个文件;
4. 每章做完渲染缩略图拼图和逐帧条自查,确保动作与连贯性无误;
5. 最后运行渲染脚本合成 MP4。
三、进阶:Donald Jewkes 的混合做法
NotinReality 的 MV 发出后不到一天,Donald Jewkes 引用它,发了自己用 Opus 5.5 做的新版本,并在回复里贴出了完整 prompt:
“我用 Opus 5.5、一个 prompt 做了这个。我对着电脑说了 5 分钟,Claude 干了 12 小时,我醒来就看到了它。”
1. Donald 的 prompt 要了什么
- 拟人化主角与设定:Prompt 要的是“受 Claude 向日葵形象启发、更拟人化、贴合女声演唱的流行歌手主角”,以 K-pop 为视觉参考,别太往皮克斯风靠(Donald 觉得那有点烂大街);用 fal(AI 生图、生视频的 API 平台)生成角色设定、伴舞和场景。
- Seedance 底片与 JS 覆描重建:把歌切段传给 Seedance 2.5(字节的视频生成模型)以对准口型和时间,自己搭验证流程反复生成作为动作与物理背景底片;再让 Claude 以 Seedance 底片为基础,用 JavaScript 从零重建画面作为覆盖层,最终只看到 JS 手绘层、看不到底片,类似先拍实拍再在上面画的转描(rotoscoping)。
- 视听细节与高密度信息:开头歌词要大,做成吸引注意的钩子,构图时给歌词留位置;可以用 ElevenLabs 做音效;要求反复看整片、截图逐段检查;让它把 Claude Max 套餐额度用满,另有约 2000 美元的 fal 额度可用(实际花了多少没公开)。
- 大量上屏文字和圈内梗:和 NotinReality 几乎不放字的做法相反,Donald 要求歌词用大号动态字体,还要把科技圈的时事梗塞进去,prompt 点名了 Navier-Stokes 方程这类“AI 把数学难题吃掉”的推特热议,以及 EVA 真嗣梗,允许用“互联网粗野主义”风格直接贴素材。成片里能看到论文截图、“400,000 GPUs”、保密协议门、“What did Ilya see?” 等画面。
这段 prompt 的目标也写得很直白:观众是旧金山科技圈推特,要做一支推特爆款,更高的目标是“比任何人见过的都好”。Donald 认为上屏文字是留住注意力的最好办法之一,所以开头用大字做钩子,其他地方大字和字幕式小字交替。
prompt 最后附上了 NotinReality 这支 MV 的源码,说它“不错,但还差得远”,让 Claude 以它为基础往上做。也就是说,Donald 版是在 NotinReality 的代码上加码。
值得注意的是,这段 prompt 还引用了 Donald 本机事先准备的 /asic 作品文件夹、叫 mesh 的参考素材库技能、video scoring 技能、Seedance 2.5 文档和 API 密钥,所以“一个 prompt”是站在一整套现成工具链上的,普通读者照抄这段 prompt 跑不起来。
2. 两种创作哲学的对比
| 维度 | NotinReality 路线(纯代码手绘) | Donald Jewkes 路线(多模型混合管线) |
|---|---|---|
| 核心机制 | Claude 写 p5.js/p5.brush 代码逐帧绘制,不用任何生图或生视频模型 | fal 生图、Seedance 生视频做底片,再由 Claude 用 JS 重画覆盖(按 prompt 的设计) |
| 画面风格 | 水彩绘本、舞台剧、水彩晕染、线稿轻微抖动 | 米白纸张、网点、藏青粉橙配色的二次元拼贴风 |
| 文字策略 | 画面里几乎不放字,只有底部歌词字幕,靠动作和表情讲故事 | 大量用字:大号歌词动效、论文截图、技术梗 |
| 控制力与成本 | 同一时间点永远画出同一帧、能改到具体某一帧;除了 Claude 本身不需要额外的生图/生视频费用 | 信息量大、冲击力强;需要 fal、Seedance、ElevenLabs 等额外付费服务和事先搭好的工具,Claude 跑了 12 小时 |
成片能看到大号歌词、梗和纸感,但是否真的是 Seedance 底片加 JS 重描,外人只能看到 prompt 和成片,看不到中间过程。
想自己动手,NotinReality 的 ClaudeAnimationBase 是更现实的起点:代码开源,只需要 Claude 和几样免费软件,模板自带的示例我们已在本机跑通。
四、写在最后:代码手绘动画的核心门道
这套方法真正的门道是“模型写代码画每一帧 + 渲染截图自己看 + 分章节并行”,外加一份把审美和节奏写清楚的规则书。据作者观察,推理档位越高,模型做出的场景越铺张、越注重细节。对读者来说,建议先用 15 秒短片跑通分镜、缩略图拼图自查和渲染流程,再尝试制作整首歌。
实操带走包
滚动查看原始 Markdown,复制后可按团队实际系统与政策修改。
正在载入 Markdown…
