动画风格
十种视觉风格,每一种都是一份真实的代码文件,Claude 可以将其指向任何故事。这里不调用任何图像或视频模型,因此同一个故事每次渲染方式相同,且无需任何成本。
模板附带一个完整的 22 秒示例:克劳德乘坐自制火箭飞向月球,在每个节拍切换一种新风格。先运行它看看每种效果的运动方式,然后替换故事。
风格
| 文件 | 风格 | 一句话描述 |
|---|---|---|
pixel.js | 像素艺术 | 约 120 像素宽绘制,无平滑缩放。小调色板、抖动天空、游戏 HUD |
ps2.js | PS2 风格 | 少多边形、泥泞小纹理、雾、拉伸的低分辨率画面、任务 HUD |
comic.js | 漫画艺术 | 粗墨线、平涂色彩、本戴点、动作线、说明框、一个巨大的 BOOM |
brick.js | 乐高风格 | 所有物品均为带有凸点的塑料砖块,置于柔和阳光下 |
clay.js | 黏土动画 | 带有拇指印的柔软形状、柔光、每秒 12 帧 |
paper.js | 纸艺剪裁 | 多层剪裁卡片带小阴影、纸纤维、每秒 8 帧 |
anime.js | 复古动漫 | 80 年代赛璐珞:渐变天空、大太阳盘、速度线、击中时的反色帧、胶片颗粒 |
poly.js | 低多边形 3D | 扁平表面和硬光,无圆润形状 |
riso.js | 孔版印刷 | 两种油墨在米白纸上,每种带有独立半色调网点,印刷略有错位 |
mini.js | 微缩立体模型 | 桌上手工制作的小场景,纸板和棉花,移轴模糊 |
styles.md 包含了每种风格的规则:是什么让它看起来像那种风格、更换主题时需更改什么、以及什么会破坏它。在编写场景之前,请阅读对应风格的部分。
步骤
- 获取需求。 故事或应用程序是什么?竖屏(Reels、TikTok)还是横屏(X、YouTube)?以及使用哪些风格?无偏好则选择 3 到 5 种适合节拍的风格,或全部 10 种以展示效果。整个视频使用一种风格也可以。
- 编写故事 使用
copywriter.md。每拍一行。向用户展示每行及其对应的风格,并等待确认。 - 复制模板:
cp -r ~/.claude/skills/claude-animation-styles/template ~/my-video && cd ~/my-video && npm i。在更改任何内容之前先运行检查:node render.cjs stills 2,6,12并打开生成的图片。这些图片显示的是示例故事,因此在开始您的故事前请删除stills/目录。 - 编写 story.json。
format为vertical或wide。每个节拍包含style(文件名)、seconds和line。同一风格可用于多个节拍,每个节拍获得自己的场景(见下文)。 - 重写您使用的每个风格文件中的场景。 保持外观,替换主题。请参阅“更换主题”部分。
- 在每种风格完成后检查静态帧:
node render.cjs stills 1,3.5,6。数字是整个视频的时间点(秒),而非节拍内的秒数,命令会打印每张图片的文件名。打开每张图片。关闭声音后主题是否可识别?是否看起来像那种风格?是否有任何部分被画面裁剪? - 如果用户需要,添加语音:
ELEVENLABS_API_KEY=... python3 voice.py [voice_id]。它会读取台词,写入voice.mp3并根据语音重新调整 story.json 中的节拍时间。没有 API 密钥则无语音,此时需手动设置秒数并添加音乐。 - 渲染:
node render.cjs video --audio voice.mp3,或纯node render.cjs video不带音频。输出文件为out/video.mp4。一个 20 秒的视频需要几分钟。 - 在交付前查看完整视频:
ffmpeg -i out/video.mp4 -vf "fps=1,scale=240:-1,tile=8x4" -frames:v 1 out/sheet.jpg(每秒一张图片,因此末尾的空格是正常的)。您无法听到声音,所以请告知用户检查音频。
在语音下方添加音乐,音量比语音低 14 dB:
ffmpeg -i voice.mp3 -i music.mp3 -filter_complex "[1]volume=0.2[m];[0][m]amix=inputs=2:duration=first:normalize=0" audio.wav
使用 -af ebur128 测量两者并调整音量,因为不同曲目的响度差异很大。
更换主题
每个风格文件都有一个 create 函数用于构建世界一次,以及一个 render(t, ctx, dur) 函数用于绘制任意时刻,其中 t 是节拍内的时间(秒),dur 是节拍的时长。它只查看 t,因此任何帧都可以按任意顺序绘制。
一种风格使用两次。 create 接收 index(节拍在 story.json 中的位置)、line 和 beat。保存 this.index = index 并为每个节拍绘制不同的场景。不要为此使用 start 测试,因为当时间变化时它会改变。
2D 风格(像素、漫画、纸艺、动漫、孔版印刷)。 主题通过一个小型绘制器绘制:paint.fill(path, key) 和 paint.lines(segments, width, key),每种风格决定这些函数的具体行为。在漫画风格中,它们添加墨线。在纸艺风格中,它们添加阴影。在孔版印刷风格中,它们放置油墨密度。lib/common.js 包含示例主题 drawClaude 和 drawRocket。以相同方式编写 drawCat、drawPhone 或 drawFounder,在每种风格中使用相同的部件名称,即可免费获得每种外观。新的部件名称(如 fur、apron)必须添加到该风格的调色板中(漫画、纸艺和动漫中是 PAL,孔版印刷中是 toneA 和 toneB),否则会使用错误的颜色绘制且无错误提示。像素艺术绘制自己的精灵,因此需手动编写。
3D 风格(PS2、乐高、黏土、低多边形、微缩)。 lib/three-claude.js 使用简单形状构建主题,通过 kit 决定多边形数量及材质。以相同方式构建主题:makeCat(kit)。乐高风格是例外,因为所有物体都必须用砖块构建,因此需复制其 add 辅助函数。
在每个风格中保持主题一致。 相同轮廓、相同两到三种颜色。这样才能使风格切换读起来像是同一个故事,而非新片段。一个简单易识别的形状胜过细节丰富的角色。
成功的关键
- 在硬切处切换风格。 直接切换到下一个外观。这种惊喜感本身即是过渡。
- 中间有一个大的移动物体。 观众需要在不到一秒内理解每个节拍,通常是在手机上且关闭声音。
- 每个节拍持续 1.5 到 3 秒。 足够长以看清外观,足够短以吸引他们观看下一个。
- 让故事在切换中保持连贯。 如果一个节拍结束时火箭在上升,下一个节拍开始时它仍在上升。
- 文字属于风格本身。 游戏外观中的 HUD,漫画外观中的说明框。不要在顶部添加字幕。
如果出现问题
- 缺少 Puppeteer 或 Three.js: 在包含
render.cjs的文件夹中运行npm i。 - 缺少 ffmpeg: 在 Mac 上运行
brew install ffmpeg。静态帧无需它,视频需要。 - 3D 帧为黑色或渲染极慢: 渲染在 Mac 上使用 GPU,在其他地方使用软件渲染器(
render.cjs中的gl行)。软件渲染也能工作,但耗时更长。 - 标题字体错误: 页面加载来自 Google Fonts 的 Inter Tight 和 Bangers 字体,因此渲染时需要网络连接。
- 漫画风格中的文字出现延迟: 倒计时在有语音时从
voice.json读取单词时间。在comic.js中更改它查找的单词。
保持原创
复制这些外观,并创建您自己的主题。不要在屏幕上使用品牌的标志、游戏的角色或真实公司的场景道具,也不要逐帧复制其他创作者的作品。