animate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Animate

Animate

You make short animated videos in code: one
<canvas>
, drawn and scored procedurally, deterministic frame by frame, rendered with a headless browser and ffmpeg. The story follows a grammar studied from strong short-form animation; the look is a style — a plug-in kit chosen from styles/ or made from the user's references with new-style.md.
Requirements: Node 18+, Playwright with Chromium (
npm i -g playwright && npx playwright install chromium
), ffmpeg on PATH. Check them first; if one is missing, tell the user the install command and stop. For a voice-over, Python with
faster-whisper
(
pip install faster-whisper
) times every word; without it the word times are estimated.
All paths below are relative to this skill's base directory. Pieces live in the user's project at
pieces/<name>/
(create
pieces/
if needed); styles the user makes live in
<project>/styles/<name>/
.
你可以用代码制作短动画视频:单个
<canvas>
元素,通过程序化方式绘制画面与配乐,逐帧生成确定性结果,通过无头浏览器和ffmpeg渲染输出。故事遵循从优质短动画中总结的叙事语法;视觉效果由风格套件决定——你可以从styles/目录中选择预设的插件式风格套件,也可以根据用户的参考图按照new-style.md的说明创建新风格。
环境要求: Node 18+、安装了Chromium的Playwright(
npm i -g playwright && npx playwright install chromium
)、PATH中配置了ffmpeg。请先检查环境;如果缺少依赖,请告知用户安装命令并终止流程。如果需要旁白,需要安装带
faster-whisper
的Python环境(
pip install faster-whisper
)来逐词计时;没有的话则会估算词的时间点。
以下所有路径均相对于本技能的根目录。动画项目存放在用户项目的
pieces/<name>/
目录下(如需要请创建
pieces/
目录);用户创建的风格存放在
<project>/styles/<name>/
目录下。

Non-negotiables

硬性规则

  1. No animating before the storyboard is approved. The check-ins exist because a wrong story or look costs a full build.
  2. Look at references before drawing anything — the user's, or the style's
    sample.png
    and demo. Then check every key frame against grammar/FRAME.md and the style's own checklist in its
    STYLE.md
    .
  3. Every factual claim on screen is checked with a web search and listed with its source in the brief. Never claim "first" without a source.
  4. Single file, all code: one
    index.html
    ; everything is drawn and synthesized in code — no image/audio/video files, no
    data:
    URIs, no URLs, no web fonts in the code.
    tools/build.mjs
    enforces it. Two opt-in exceptions, both the user's own: assets (screenshots and logos in
    <piece>/assets/
    , embedded by the build) and a music track (joined at export). See Assets and Music below.
  5. Deterministic: seeded randomness only (
    RNG(...)
    ), the boil index
    B
    for per-step variation. Never
    Math.random()
    or wall-clock time.
  6. Reference media stays local. Never commit it, copy its code, or name its artist in published output unless the user asks to credit them.
  7. "Done" is measured:
    tools/review.mjs
    passes and you have looked at the contact sheets. Report the numbers, not "looks good".
  8. Ask with options. Use AskUserQuestion with a recommended default first, so the user can answer in one click.
  1. 分镜未通过审批前不得开始动画制作。 设置确认环节是因为故事或视觉风格出错会导致整个构建工作白费。
  2. 绘制任何内容前先查看参考资料——可以是用户提供的参考,或是对应风格的
    sample.png
    和演示示例。然后对照grammar/FRAME.md以及该风格
    STYLE.md
    中的检查清单,逐一检查每个关键帧。
  3. 屏幕上的所有事实性表述都必须通过网络搜索验证,并在需求说明中列出来源。没有来源的情况下绝对不能声称“首个”“第一”。
  4. 单文件、纯代码: 仅一个
    index.html
    文件;所有画面和音效都通过代码绘制与合成——代码中不得包含图片/音频/视频文件、
    data:
    URI、外部URL、网页字体。
    tools/build.mjs
    会强制执行此规则。有两个可选的例外,且都必须是用户自有内容:资源文件(assets)(存放在
    <piece>/assets/
    中的截图和logo,构建时会嵌入)和音乐轨道(导出时合并)。详见下文的资源与音乐部分。
  5. 确定性: 仅使用带种子的随机数(
    RNG(...)
    ),通过波动指数
    B
    实现逐步骤变化。绝对不能使用
    Math.random()
    或系统时间。
  6. 参考媒体仅保存在本地。 除非用户要求署名,否则不得提交参考内容、复制其代码,或是在公开输出中提及原作者。
  7. “完成”需量化验证: 必须通过
    tools/review.mjs
    检查,且你已查看过联系表。要汇报具体数据,而不是“看起来不错”。
  8. 提问时提供选项。 使用AskUserQuestion时优先给出推荐的默认选项,这样用户可以一键回答。

The flow

工作流程

0. Intake

0. 需求收集

Ask the questions in intake.md — only the ones you can't infer. For the look, build the gallery (
node tools/gallery.mjs <out.png> [<project>/styles]
, ~3s), show it and ask: which of these, or show me a reference? Then study the references yourself against FRAME.md and the style's checklist.
提出intake.md中的问题——只问你无法推断的问题。关于视觉风格,先生成风格画廊(命令:
node tools/gallery.mjs <out.png> [<project>/styles]
,耗时约3秒),展示给用户并询问:选择其中一种,还是提供参考图? 然后你需要对照FRAME.md和对应风格的检查清单,仔细研究参考资料。

1. Story check (text, fast)

1. 故事确认(文本形式,快速完成)

Pick the format from grammar/FORMATS.md — the plot engine decides it (a history is a chronology joined by morphs; a mission cuts on the beat; a list is a catalogue). Read grammar/STORY.md. Web-check the facts. Then show the user:
  • the one-line idea and the sayable device ("the spark gains a ray each era and ends as the answer")
  • the format and why, the style, length, BPM
  • a numbered beat table: time, what happens, the bridge into the next beat, the sound's role (where the silence is, where the loudest hit is)
Ask: approve / change beats / different angle. Revise until approved. This is where "I meant X, not Y" gets caught cheaply.
从grammar/FORMATS.md中选择叙事格式——由剧情引擎决定(历史类是通过变形衔接的时间线;任务类是按节拍切换;列表类是目录式呈现)。请先阅读grammar/STORY.md。通过网络核查事实。然后向用户展示:
  • 一句话创意和核心叙事手法(例如“火花在每个时代获得一道光芒,最终化作答案”)
  • 选择的叙事格式及理由、视觉风格、时长、BPM
  • 带编号的节拍表:包含时间点、事件、到下一个节拍的过渡方式、音效的作用(静默位置、最强重拍位置)
询问用户:确认通过 / 修改节拍 / 换个角度。 反复修改直到获得批准。这个阶段能以最低成本发现“我要的是X不是Y”这类理解偏差。

2. Look check (2–4 style frames)

2. 视觉风格确认(2-4张风格帧)

Start the piece at
pieces/<name>/
: copy
piece.json
and
src/
from the style's demo (
styles/<name>/demo/
) — it already speaks the style's kit and joins eras with a morph — or from templates/beat-cut/ for a piece that cuts hard on the beat (8ths, a 16th-note rush on odd frames, one era per shot, framings from cameras), or templates/piece/ for the plainest cut-paper morph. Set
"style"
in
piece.json
, then write
brief.md
and
LOG.md
fresh (the template's are placeholders).
  • A shipped style: read its
    STYLE.md
    and demo and draw with its kit.
  • The user's references: follow new-style.md. Measure the references first (
    tools/measure/refs.mjs
    ); the piece's own style frames are the matched frames, so this is one check-in: the compare sheets and the frames together. Save the style folder after the piece is approved (the piece becomes its "proven on").
Draw 2–4 of the most different beats as full-size frames. Each must pass FRAME.md and the style's checklist. Render them side by side with
node tools/still.mjs pieces/<name> 2.25,9.75,16.5 look.png --scale 0.5
(or
tools/storyboard.mjs
with
TIMELINE.board
set to those beats), and show the image. Ask: thumbs up per frame / change the look / try another style.
在
pieces/<name>/
目录下创建动画项目:从对应风格的演示目录(
styles/<name>/demo/
)复制
piece.json
和
src/
目录——演示项目已经适配了该风格的套件,并且用变形效果衔接不同时代——如果是按节拍硬切的项目(八分节拍,奇数帧有十六分音符快切效果,每个镜头对应一个时代,采用相机取景),则从templates/beat-cut/复制;如果是最简单的剪纸变形项目,则从templates/piece/复制。在
piece.json
中设置
"style"
字段,然后重新编写
brief.md
和
LOG.md
(模板中的内容只是占位符)。
  • 内置风格: 阅读其
    STYLE.md
    和演示示例,使用对应的套件进行绘制。
  • 用户提供的参考图: 遵循new-style.md的说明。首先测量参考图(使用
    tools/measure/refs.mjs
    );项目的风格帧本身就是匹配后的帧,因此这是一次确认:同时展示对比表和风格帧。项目获批后保存风格文件夹(该项目将成为此风格的“验证案例”)。
选择2-4个差异最大的节拍,绘制为全尺寸帧。每个帧都必须通过FRAME.md和风格检查清单的要求。使用命令
node tools/still.mjs pieces/<name> 2.25,9.75,16.5 look.png --scale 0.5
将它们并排渲染(或者使用
tools/storyboard.mjs
,将
TIMELINE.board
设置为这些节拍),然后展示图片。询问用户:逐帧点赞确认 / 修改视觉风格 / 尝试其他风格。

3. Storyboard check (every beat)

3. 分镜确认(覆盖所有节拍)

Draw every beat in the approved look. Fill
TIMELINE.board
with one key time per beat (
{ t, title, sound, next }
) and render the board. Ask for thumbs up/down by panel number and notes; redraw what's down; repeat. The panels are the video's own scene functions, so nothing is redrawn later.
使用已确认的视觉风格绘制所有节拍的画面。在
TIMELINE.board
中为每个节拍填写一个关键时间点(格式为
{ t, title, sound, next }
),然后渲染分镜。请用户按面板编号点赞/点踩并给出备注;重画未通过的面板;重复此过程直到全部通过。这些面板就是视频本身的场景函数,因此后续无需重画任何内容。

4. Build

4. 构建

  1. Write
    pieces/<name>/brief.md
    (spec, style, beats, bridges, sound plan, claims + sources). Keep a
    LOG.md
    .
  2. Animate the scenes: timed actions with
    TT
    ,
    ev(t, d)
    ,
    popS(t)
    , write-ons (see craft.md → Motion). Wire eras, cameras and bridges in
    src/bridges.js
    (morph-joined formats) or leave
    BRIDGES = []
    for hard cuts.
  3. node tools/build.mjs pieces/<name>
    →
    index.html
    (the style's kit is pulled in from
    piece.json
    "style"
    ).
  4. Test tiles while building:
    node tools/tile.mjs pieces/<name> tile.png <frames...>
    — look at them; tile across every morph and cut.
  5. Score in
    src/score.js
    (see craft.md → Sound).
  6. node tools/export.mjs pieces/<name> --share
    → frames,
    audio.wav
    , stems,
    renders/final.mp4
    ,
    renders/share.mp4
    (
    --formats 9:16,1:1,16:9
    for every format;
    --blur 4
    for motion blur on 1s styles). Iterate the mix with
    --only-audio
    (re-renders the score and remuxes it, ~4× faster).
  7. node tools/review.mjs pieces/<name>
    → contact sheets per shot, cut grid, morph grid, story arc, anchor, text (cut off / overlapping / under the phone UI) and sound (the loudest moment, the silence before it, LUFS). Fix until it passes, view the sheets, write a per-shot PASS table in
    LOG.md
    . Trust the text check over your eye: a cropped label looks fine on a contact sheet.
  1. 编写
    pieces/<name>/brief.md
    (包含规格、风格、节拍、过渡、音效方案、事实声明+来源)。维护
    LOG.md
    日志。
  2. 制作场景动画:使用
    TT
    、
    ev(t, d)
    、
    popS(t)
    、手写出现效果等实现定时动作(参见craft.md → 动效部分)。在
    src/bridges.js
    中连接不同时代、相机和过渡效果(变形衔接格式),如果是硬切则设置
    BRIDGES = []
    。
  3. 执行
    node tools/build.mjs pieces/<name>
    → 生成
    index.html
    (风格套件会从
    piece.json
    的
    "style"
    字段引入)。
  4. 构建过程中测试拼接图:执行
    node tools/tile.mjs pieces/<name> tile.png <frames...>
    ——查看拼接效果;每个变形和切分处都要生成拼接图检查。
  5. 在
    src/score.js
    中编写配乐(参见craft.md → 音效部分)。
  6. 执行
    node tools/export.mjs pieces/<name> --share
    → 生成帧序列、
    audio.wav
    、分轨文件、
    renders/final.mp4
    、
    renders/share.mp4
    (添加
    --formats 9:16,1:1,16:9
    可导出所有比例的版本;添加
    --blur 4
    可为1帧风格添加运动模糊)。使用
    --only-audio
    迭代调整混音(仅重新渲染配乐并重新封装,速度约为原来的4倍)。
  7. 执行
    node tools/review.mjs pieces/<name>
    → 生成每个镜头的联系表、切分网格、变形网格、故事弧线、锚点、文本检查(是否被截断/重叠/被手机UI遮挡)和音效检查(最响时刻、之前的静默、LUFS响度)。修复问题直到通过检查,查看联系表,在
    LOG.md
    中编写每个镜头的PASS表格。要相信文本检查结果而不是肉眼:被裁剪的标签在联系表上可能看起来没问题。

5. Deliver

5. 交付

Send
renders/share.mp4
. Say in a few lines: what it is, the checks' numbers, what the review caught and fixed, the weakest shot, and what you haven't verified (e.g. you can't listen to the score). Ask what should change: story, look, transitions, pacing, sound.
发送
renders/share.mp4
。用几句话说明:这是什么内容、检查的各项数据、审核中发现并修复的问题、最薄弱的镜头,以及你未验证的内容(例如你无法收听配乐)。询问用户需要修改什么:故事、视觉风格、过渡、节奏、音效。

6. Learn

6. 复盘总结

After each run append to the piece's
LOG.md
. If something new went wrong or worked, propose a one-line rule for craft.md, the style's
STYLE.md
or a kit change, and add it when the user agrees.
每次运行后,向项目的
LOG.md
追加内容。如果出现了新的问题或有效的新方法,为craft.md、对应风格的
STYLE.md
或套件修改提议一条单行规则,经用户同意后添加。

Voice-over (optional)

旁白(可选)

Ask at intake (question 3). With a voice, the voice is the clock: each beat starts ~0.3s after the previous sentence ends, and the big moments land on spoken words. The script is the storyboard: one line per beat.
  1. Write the script to
    pieces/<name>/voice/script.json
    :
    { "lead": 1.2, "tail": 1.8, "lines": [{ "id": "open", "text": "As it is spoken.", "after": 0.45 }, ...] }
    . Write numbers and names the way they should be said. Keep it ≤ 3.5 words/s; give a line a longer
    after
    where the picture needs time to land (a count, a caption, the silence before the payoff).
  2. Build before the voice exists:
    node tools/voice.mjs pieces/<name> --scratch
    makes a timing voice with the OS's own speech (never ship it), so the whole piece can be animated and reviewed.
  3. The takes: one file per line, saved as
    voice/<id>.mp3
    with
    "file"
    set on the line.
    • The ElevenLabs connector (if the user has it: Claude's Settings → Connectors → ElevenLabs, signed in with OAuth, no API key): find 2–3 narrators that fit with its voice search, generate one line in each (one variation each, not four), let the user pick, then generate every line once with that voice and model. The generation result gives a short-lived download link per take: save each into
      voice/
      . It costs about one credit per character; say the total before the full run. If the connector was added during the session, its tools may only appear after the app restarts.
    • The user's own recording, one file per line (or cut from one take).
    • Never fetch a voice from a site the user didn't point to, and never clone a voice without its owner's consent.
  4. node tools/voice.mjs pieces/<name>
    →
    voice/voice.wav
    (the lines with their pauses) and
    voice.json
    (every line's and word's start and end, heard in the audio by faster-whisper, locally). The build injects it as
    VOICE
    .
  5. In the head:
    VL(id)
    is a line,
    VW(id, word, n)
    when its n-th
    word
    starts; beats start at the previous line's
    t1 + 0.3
    ;
    TIMELINE.narration
    comes from
    VOICE.lines
    and
    DURATION
    from
    VOICE.duration
    . Cue Writes and flashes on the words that name them. Put the payoff hit in a pause before the line that names it: a hit under speech is ducked away.
  6. piece.json
    :
    "voice": { "file": "voice/voice.wav", "music": -12 }
    . Export mixes the voice over the score (the score at
    music
    dB, ducked further while the voice speaks) to −14 LUFS. Review judges the story arc and the payoff window on the score alone (
    renders/audio-score.wav
    ; a voice is louder than any hit) and the voice with its NARRATION check.
  7. Re-takes and script edits: replace a line's file (or edit its text), rerun
    voice.mjs
    , rebuild: scenes cued from
    VOICE
    move with it. A changed word can orphan a cue that points at it; check those beats.
在需求收集阶段询问(第3个问题)。如果使用旁白,旁白就是时间基准:每个节拍在前一句话结束后约0.3秒开始,重要时刻要落在说出的词语上。脚本就是分镜:每个节拍对应一行。
  1. 将脚本写入
    pieces/<name>/voice/script.json
    :格式为
    { "lead": 1.2, "tail": 1.8, "lines": [{ "id": "open", "text": "As it is spoken.", "after": 0.45 }, ...] }
    。数字和名称要按照朗读的方式书写。语速保持在≤3.5词/秒;如果画面需要时间呈现(比如计数、字幕、高潮前的静默),给对应行设置更长的
    after
    值。
  2. 在旁白生成前先构建: 执行
    node tools/voice.mjs pieces/<name> --scratch
    ,用系统自带的语音生成临时计时旁白(绝对不能随成品交付),这样整个动画项目就可以进行动画制作和审核。
  3. 录制素材: 每行对应一个文件,保存为
    voice/<id>.mp3
    ,并在对应行设置
    "file"
    字段。
    • ElevenLabs连接器(如果用户已配置:Claude设置 → 连接器 → ElevenLabs,通过OAuth登录,无需API密钥):用语音搜索功能找到2-3个合适的朗读者,每个生成一行样本(每个一种变体,不要四种),让用户选择,然后用选定的语音和模型一次性生成所有行。生成结果会提供每个素材的短期下载链接:将每个文件保存到
      voice/
      目录。大约每个字符消耗1个积分;在完整生成前告知用户总消耗。如果是在会话期间添加的连接器,相关工具可能需要重启应用后才会显示。
    • 用户自己的录音,每行一个文件(或从一段录音中剪切)。
    • 绝对不要从用户未指定的网站获取语音,未经所有者同意绝对不要克隆语音。
  4. 执行
    node tools/voice.mjs pieces/<name>
    → 生成
    voice/voice.wav
    (带停顿的各行旁白)和
    voice.json
    (每行、每个词的开始和结束时间,由faster-whisper在本地识别音频得到)。构建时会将其作为
    VOICE
    注入。
  5. 在头部代码中:
    VL(id)
    对应一行旁白,
    VW(id, word, n)
    表示第n个
    word
    开始的时间;节拍从上一行的
    t1 + 0.3
    开始;
    TIMELINE.narration
    来自
    VOICE.lines
    ,
    DURATION
    来自
    VOICE.duration
    。在提到对应内容的词语上触发手写效果和闪烁效果。将高潮重拍放在对应台词之前的停顿中:语音下的重拍会被闪避处理,效果不佳。
  6. 在
    piece.json
    中配置:
    "voice": { "file": "voice/voice.wav", "music": -12 }
    。导出时会将旁白混合到配乐之上(配乐音量为
    music
    分贝,旁白播放时会进一步闪避),最终输出为−14 LUFS。审核会单独基于配乐判断故事弧线和高潮窗口(
    renders/audio-score.wav
    ;旁白话比任何重拍都响),并通过NARRATION检查来评估旁白。
  7. 重录和脚本编辑: 替换某行的文件(或编辑其文本),重新运行
    voice.mjs
    ,然后重新构建:从
    VOICE
    触发的场景会随之调整。修改词语可能会导致指向它的触发点失效;请检查这些节拍。

Music: the user's own track (optional)

音乐:用户自有音轨(可选)

Ask at intake (question 6). Without a track the score is composed in code on a 120 BPM grid. With one:
  1. Put it in the piece:
    pieces/<name>/audio/track.wav
    (WAV, MP3 or M4A), and in
    piece.json
    :
    "music": { "file": "audio/track.wav", "start": 12.0, "gain": 0, "fade": 0.5 }
    (
    start
    = where in the song the piece begins).
  2. node tools/beats.mjs pieces/<name>/audio/track.wav pieces/<name> --start 12 --dur <piece length>
    →
    beats.json
    : the tempo, the first beat, every beat and bar, the strongest hits, the loudest moment and the drops. Pass
    --bpm 128
    if the user knows the tempo; check its "other tempos" line otherwise (double / half / two-thirds time is the usual miss).
  3. The build injects it as
    BEATS
    ; the starter head reads
    BPM
    and
    GRID0
    from it, and
    onBeat(t)
    snaps a time to the song's 8th grid. Put cuts, morphs and cues on
    onBeat(...)
    . The song decides the arc: put the turn on a drop (
    BEATS.quiet
    ) and the payoff on its loudest hit (
    BEATS.loudest
    ,
    BEATS.hits
    ), not where a composed score would have put them.
  4. The score (
    src/score.js
    ) keeps only sound effects (
    to = 's'
    ): export replaces the music bus with the track, mixes the sfx stem on top and normalises to −14 LUFS. Review's grid uses
    TIMELINE.gridOffset
    ; its SOUND section says whether the loudest moment lands in the payoff act.
  5. The browser preview still plays the composed score (no audio files in the page); the export has the track.
在需求收集阶段询问(第6个问题)。如果没有音轨,配乐会以120 BPM的网格在代码中合成。如果使用用户提供的音轨:
  1. 将音轨放入项目目录:
    pieces/<name>/audio/track.wav
    (支持WAV、MP3或M4A格式),并在
    piece.json
    中配置:
    "music": { "file": "audio/track.wav", "start": 12.0, "gain": 0, "fade": 0.5 }
    (
    start
    表示动画从歌曲的哪个时间点开始)。
  2. 执行
    node tools/beats.mjs pieces/<name>/audio/track.wav pieces/<name> --start 12 --dur <项目时长>
    → 生成
    beats.json
    :包含速度、第一个节拍、每个节拍和小节、最强重拍、最响时刻和drop点。如果用户知道速度,传入
    --bpm 128
    ;否则检查其“其他速度”行(通常容易误判为2倍/半速/三分之二速)。
  3. 构建时会将其作为
    BEATS
    注入;启动头部会从中读取
    BPM
    和
    GRID0
    ,
    onBeat(t)
    会将时间对齐到歌曲的八分音符网格。将切分、变形和触发点都放在
    onBeat(...)
    上。歌曲决定叙事弧线: 将转折点放在drop点(
    BEATS.quiet
    ),将高潮放在最响的重拍上(
    BEATS.loudest
    、
    BEATS.hits
    ),而不是按照合成配乐的习惯位置放置。
  4. 配乐文件(
    src/score.js
    )中只保留音效(
    to = 's'
    ):导出时会用用户音轨替换音乐总线,将音效分轨混合在上面,并归一化到−14 LUFS。审核的网格使用
    TIMELINE.gridOffset
    ;其SOUND部分会说明最响时刻是否落在高潮段落。
  5. 浏览器预览仍然播放合成配乐(页面中没有音频文件);导出版本才会包含用户音轨。

Assets: real screenshots and logos (optional)

资源文件:真实截图和logo(可选)

Ask at intake (question 7) when the subject is a product. Then:
  • node tools/capture.mjs <url> pieces/<name>/assets/home.png [--selector "css"] [--full] [--dark] [--hide "css"]
    screenshots the user's own site (a page, a section, the logo). Ask before capturing anything they don't own. Logo files they give you go in
    assets/
    too (PNG, SVG, JPG, WEBP).
  • tools/build.mjs
    embeds everything in
    assets/
    into
    index.html
    (the piece stays one file, and the canvas stays readable by the checks);
    window.renderFrame
    appears once the images are decoded, and every tool waits for it.
  • Draw them with
    drawAsset('home.png', x, y, w, h, { fit: 'cover' | 'contain', r })
    inside the style's own framing (a torn-paper photo, an inked frame, a printed card) so they belong to the look.
    asset(name)
    returns the image.
  • Real product UI only: animate the real screens (crop, push in, reveal, point at them with the hero); never draw a fake screen as if it were the product. Sample brand colours from the screenshots.
当主题是产品时,在需求收集阶段询问(第7个问题)。然后:
  • 执行
    node tools/capture.mjs <url> pieces/<name>/assets/home.png [--selector "css"] [--full] [--dark] [--hide "css"]
    来截取用户自有网站的截图(整个页面、某个部分、logo)。在截取他们不拥有的内容前必须先询问。用户提供的logo文件也放在
    assets/
    目录下(支持PNG、SVG、JPG、WEBP格式)。
  • tools/build.mjs
    会将
    assets/
    中的所有内容嵌入到
    index.html
    中(项目仍然是单文件,canvas仍然可以被检查工具读取);图片解码完成后会出现
    window.renderFrame
    ,所有工具都会等待它。
  • 使用
    drawAsset('home.png', x, y, w, h, { fit: 'cover' | 'contain', r })
    在风格自带的画框中绘制资源(比如撕纸照片、墨线框、印刷卡片),让它们融入整体视觉风格。
    asset(name)
    返回图片对象。
  • 仅使用真实产品UI: 用真实屏幕制作动画(裁剪、推入、揭示、用主角指向它们);绝对不要绘制假屏幕冒充产品。从截图中提取品牌色。

Formats: one piece, several shapes (optional)

格式:一个项目,多种比例(可选)

Ask at intake (question 2, multi-select). List them in
piece.json
"formats": ["9:16", "1:1", "16:9"]
(the first is the main one). The starter's head reads
?format=
and sets
W
,
H
,
SAFE
and
CX
; scenes place things with
LX(fraction)
,
LY(fraction)
and size them with
UNIT
, and choose a different arrangement with
PORTRAIT
/
WIDE
where a shape needs it (a column of three on 9:16, a row of three on 16:9). Never crop a 9:16 render to 16:9.
  • node tools/export.mjs pieces/<name> --formats 9:16,1:1,16:9 --share
    →
    renders/final.mp4
    (main) and
    final-<w>x<h>.mp4
    for the others.
  • Review each:
    node tools/review.mjs pieces/<name> --format 16:9
    (and
    tile
    /
    still
    /
    textcheck
    /
    storyboard
    take
    --format
    too). The text check matters most here: a wide caption that fits 16:9 can run off 9:16.
在需求收集阶段询问(第2个问题,多选)。在
piece.json
的
"formats"
字段中列出(例如
["9:16", "1:1", "16:9"]
,第一个是主格式)。启动头部会读取
?format=
参数并设置
W
、
H
、
SAFE
和
CX
;场景使用
LX(fraction)
、
LY(fraction)
定位元素,用
UNIT
设置尺寸,并在需要时通过
PORTRAIT
/
WIDE
选择不同的布局(9:16下三个元素竖排,16:9下三个元素横排)。绝对不要将9:16的渲染结果裁剪成16:9。
  • 执行
    node tools/export.mjs pieces/<name> --formats 9:16,1:1,16:9 --share
    → 生成
    renders/final.mp4
    (主格式)和其他比例的
    final-<w>x<h>.mp4
    文件。
  • 逐一审核:执行
    node tools/review.mjs pieces/<name> --format 16:9
    (
    tile
    /
    still
    /
    textcheck
    /
    storyboard
    命令也支持
    --format
    参数)。这里文本检查最为重要:适合16:9的宽字幕可能会在9:16下超出屏幕。

Motion: springs and blur

动效:弹簧动画与模糊

  • Springs (
    kit/core.js
    ):
    springMove(t0, a, b, SPRING.snappy)
    moves a value with a little overshoot and a settle;
    springTrack([[t, v], ...])
    follows a value through many targets without a jump. Presets:
    snappy
    (UI),
    smooth
    (cards, camera),
    heavy
    (big type, logos),
    playful
    (mascots). Closed-form, so frames stay deterministic. On-2s styles step them every 2 frames, as they should.
  • Motion blur:
    export.mjs --blur 4
    averages 4 sub-frames per frame — only for styles on 1s (
    STYLE.ones
    : math, isometric); hand-drawn looks on 2s are crisp on purpose (export warns).
  • 弹簧动画(
    kit/core.js
    ):
    springMove(t0, a, b, SPRING.snappy)
    会让值带有一点超调然后稳定下来;
    springTrack([[t, v], ...])
    可以让值在多个目标之间平滑过渡,不会跳变。预设包括:
    snappy
    (适用于UI)、
    smooth
    (适用于卡片、相机)、
    heavy
    (适用于大字体、logo)、
    playful
    (适用于吉祥物)。采用闭式解,因此帧保持确定性。对于2帧风格,弹簧动画会每2帧更新一次,符合风格要求。
  • 运动模糊:
    export.mjs --blur 4
    会为每帧平均4个子帧——仅适用于1帧风格(
    STYLE.ones
    :数学、等距);2帧的手绘风格故意保持清晰(导出时会发出警告)。

Parallel agents (long pieces)

并行代理(长动画项目)

A 45–60s piece has 10–15 scenes; split the drawing across agents once the storyboard is approved:
  • One
    src/
    file per section or era, owned by one agent
    (
    src/era-01.js
    ,
    src/era-02.js
    , …). List them in
    piece.json
    "scenes": [...]
    ; they take the place of
    src/scenes.js
    in the build order.
  • The shared parts stay with you:
    src/head.html
    (TIMELINE, eras, shots, cues),
    src/bridges.js
    , the score, and the kit. Agents read them but never edit them; if a scene needs a kit helper, they write it in their own file under a prefixed name.
  • Brief each agent with the approved board panel(s), the style's
    STYLE.md
    , the era's time range and cue names, its bridge objects (what must be in frame at the boundary), and the rules: deterministic, no new globals without the era prefix, tile its frames and look at them.
  • build.mjs
    joins them
    ; you build, tile across every boundary, and run the review.
45-60秒的项目有10-15个场景;分镜获批后,可以将绘制工作拆分给多个代理:
  • 每个部分或时代对应一个
    src/
    文件,由一个代理负责
    (
    src/era-01.js
    、
    src/era-02.js
    等)。在
    piece.json
    的
    "scenes"
    字段中列出这些文件;它们会在构建顺序中替代
    src/scenes.js
    。
  • 共享部分由你负责:
    src/head.html
    (TIMELINE、时代、镜头、触发点)、
    src/bridges.js
    、配乐和套件。代理只能读取这些文件,绝对不能修改;如果某个场景需要套件辅助函数,代理要在自己的文件中以带前缀的名称编写。
  • 向每个代理下达任务说明,内容包括已批准的分镜面板、风格的
    STYLE.md
    、对应时代的时间范围和触发点名称、过渡对象(边界处必须出现在画面中的内容),以及规则:必须确定性、没有时代前缀不得新增全局变量、生成帧的拼接图并检查。
  • build.mjs
    会合并所有文件
    ;你负责构建、检查每个边界的拼接图,并运行审核。

Files

文件说明

pathwhatread when
intake.mdthe questions and defaultsstep 0
craft.mdthe distilled rules: story, frame, motion, timing, sound, code, reviewbefore step 1, and when building
grammar/FORMATS.md8 story formats (engine × stage × clock), invariants, which are provenstep 1
grammar/STORY.mdbeat-level story rules with evidencestep 1
grammar/FRAME.mdwhat a single key frame must hold, in any stylesteps 2–3
styles/the styles:
STYLE.md
(rules + frame checklist),
kit.js
,
sample.png
,
demo/
; the STYLE hooks contract
steps 0, 2, building
new-style.mdmaking a new style from the user's referencesstep 2
kit/core.js
RNG, easing, geometry, the hand-drawn line (wobble, ink, paint, hatch, pencil, stipple, grain), cameras, time helpersbuilding
kit/morph.js
the renderer: eras, push-ins, zoom bumps, shape-morph bridges, overlays — draws through the style's STYLE hooksbuilding
kit/board.js
the storyboard renderersteps 2–3
kit/score-*.js
synth (pluck, pad, drone, bass, sub, noiseHit, sweep, riser, chime, blip), loudness stagescoring
templates/
piece/
(an 8s cut-paper morph),
beat-cut/
(a 6s hard-cut piece with a 16th rush),
style/
(a blank style kit for new looks)
step 2
tools/
build, tile, still, storyboard, export, review, textcheck, compare (reference vs frame), gallery, framehash (pixel-identity check), beats (a supplied track's beat map), capture (screenshots of the user's site), voice (a voice-over's lines and word times);
measure/
for references (
refs.mjs
for stills,
shotlog.py
for video)
throughout
examples/history-of-ai/a full 60s worked example (cut paper)when unsure how something fits
路径内容何时阅读
intake.md问题和默认值第0步
craft.md提炼的规则:故事、帧、动效、计时、音效、代码、审核第1步之前,以及构建时
grammar/FORMATS.md8种叙事格式(引擎×舞台×时钟)、不变量、已验证的格式第1步
grammar/STORY.md带依据的节拍级故事规则第1步
grammar/FRAME.md任意风格下单个关键帧必须满足的要求第2-3步
styles/风格库:
STYLE.md
(规则+帧检查清单)、
kit.js
、
sample.png
、
demo/
;STYLE钩子契约
第0、2步,以及构建时
new-style.md根据用户参考图创建新风格第2步
kit/core.js
RNG、缓动、几何、手绘线条(抖动、墨水、油漆、排线、铅笔、点画、颗粒)、相机、时间辅助函数构建时
kit/morph.js
渲染器:时代、推入、缩放抖动、形状变形过渡、叠加层——通过风格的STYLE钩子绘制构建时
kit/board.js
分镜渲染器第2-3步
kit/score-*.js
合成器(拨弦、垫音、持续低音、贝斯、超低音、噪声打击、扫频、上升音、风铃、点音)、响度阶段配乐制作时
templates/
piece/
(8秒剪纸变形模板)、
beat-cut/
(6秒硬切模板,带十六分音符快切)、
style/
(用于新风格的空白风格套件)
第2步
tools/
构建、拼接、静态帧、分镜、导出、审核、文本检查、对比(参考图vs帧)、画廊、帧哈希(像素一致性检查)、节拍(用户提供音轨的节拍图)、截图(用户网站截图)、旁白(旁白的行和词的时间);
measure/
目录用于参考图测量(
refs.mjs
用于静态图,
shotlog.py
用于视频)
全程
examples/history-of-ai/完整的60秒示例(剪纸风格)不确定如何实现时

Honesty about what's proven

关于已验证内容的诚实说明

Formats F2 (chronology / morph chain) and F4 (mission) have each produced a piece that passed every check from the card alone; F5 (fixed-hero journey) has several. The others are documented from study but unproven — say so when you pick one. Cut paper and crosshatch have carried full pieces; riso, sketchbook, math and pixel each come from one or two finished pieces plus a demo; isometric was made from references with new-style.md and so far has only its demo; a style made from new references is new ground until it has carried a piece. WebGL motion design (ray-marched 3D, motion blur, bloom) is not a shipped style yet.
F2(时间线/变形链)和F4(任务)格式都已产出过仅靠卡片就能通过所有检查的完整项目;F5(固定主角旅程)有多个成功案例。其他格式是通过研究总结的,但尚未经过验证——选择时请告知用户这一点。剪纸和交叉墨线风格已支撑过完整项目;Riso、速写本、数学、像素风格各有一两个完成项目加一个演示;等距风格是通过new-style.md从参考图生成的,目前只有演示版本;从新参考图生成的风格在支撑完整项目之前都属于全新尝试。WebGL动态设计(光线步进3D、运动模糊、bloom效果)目前还不是内置风格。