motion

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Motion

Motion

Paths:
${CLAUDE_SKILL_DIR}
means the folder containing this SKILL.md, and
${CLAUDE_PLUGIN_ROOT}
the plugin folder two levels above it.
Every question goes in the question box: the AskUserQuestion tool (2-4 options, recommended first).
One clip per beat, built for that line, never a template filled in. The template card is the fallback.
M="${CLAUDE_SKILL_DIR}/scripts/motion.py"
; paths are relative to the library, like style-edit's. Run the scripts with
python3
on Mac and Linux,
py
on Windows.
visuals.json (style-edit step 3) -> motion.py pick -> motion/<id>/{index.html, brief.md, beat.json}
  -> one clip-builder agent per clip -> motion.py check (gates + render) -> motion.py place
  -> visuals.json video_card beats -> plan.py -> stills -> render (the clip plays on its word)
路径:
${CLAUDE_SKILL_DIR}
表示包含此 SKILL.md 的文件夹,
${CLAUDE_PLUGIN_ROOT}
表示其上方两级的插件文件夹。
所有问题都应通过 AskUserQuestion 工具放入问题框中(提供 2–4 个选项,并将推荐项放在首位)。
每个 beat 对应一个片段,针对该句台词构建,绝不直接填充模板。模板卡片仅作为回退方案。
M="${CLAUDE_SKILL_DIR}/scripts/motion.py"
;路径相对于 library,正如 style-edit 的路径一样。在 Mac 和 Linux 上使用
python3
运行脚本,在 Windows 上使用
py
。
visuals.json (style-edit step 3) -> motion.py pick -> motion/<id>/{index.html, brief.md, beat.json}
  -> one clip-builder agent per clip -> motion.py check (gates + render) -> motion.py place
  -> visuals.json video_card beats -> plan.py -> stills -> render (the clip plays on its word)

0. Ready?

0. 准备就绪?

python3 "${CLAUDE_PLUGIN_ROOT}/skills/setup/scripts/setup.py" doctor
shows
motion clips
ok. Setup installs them by default; an install from before the motion step has none, so
pick
installs them itself (a few seconds, once). If that install fails, pick prints
Animations fell back: ...
once and makes no clip folders: say that line to the user once. The visual templates stay, and a beat whose template is only words gets no card (plan.py).
python3 "${CLAUDE_PLUGIN_ROOT}/skills/setup/scripts/setup.py" doctor
会显示
motion clips ok
。Setup 默认会安装这些工具;如果安装环境早于 motion 步骤,则尚未包含这些工具,因此
pick
会自行安装(仅需几秒,并且只执行一次)。如果安装失败,
pick
会输出一次
Animations fell back: ...
,并且不创建任何片段目录:此时只需将该提示原样告知用户一次。视觉模板仍会保留;如果某个 beat 的模板只有文字,则不会生成卡片(plan.py)。

1. Pick the beats

1. 挑选 beat

bash
python3 "$M" pick edits/<name>
Reads visuals.json (written by style-edit step 3 or the visual-prep agent) and style.json's
motion
block:
{"engine": "clips" | "templates", "amount": 0-1, "kinds": {"counter", "list", "flow", "before_after", "ui_demo", "curve", "logo": true|false}, "look": "default"}
. Every beat routed to a moving template (
likes
,
notes
,
flow
,
side_by_side
,
progress
,
terminal
,
chat
,
toasts
,
curve
,
logo_cluster
) with at least 1 s of room becomes a clip, up to
amount
of them. So does a beat routed anywhere else (a card, a capture, a sticker) whose sentence is a natural list (four or more items:
notes
), a number (
likes
), steps (first... then...:
flow
) or a before and after (
side_by_side
), one per sentence with no animation in it already, if that kind is on; a clip that fails its checks falls back to the original beat. Each gets
edits/<name>/motion/<id>/
: the template with its size, duration, look and the said words' times filled,
beat.json
(cut clock) and
brief.md
. The look:
references/looks.md
(
default
, or the style's palette and font). A user asking in chat ("animate the part where I say X"): add or change that beat in visuals.json first (style-edit
references/shapes.md
), then pick.
bash
python3 "$M" pick edits/<name>
读取 visuals.json(由 style-edit 第 3 步或 visual-prep Agent 写入)以及 style.json 中的
motion
块:
{"engine": "clips" | "templates", "amount": 0-1, "kinds": {"counter", "list", "flow", "before_after", "ui_demo", "curve", "logo": true|false}, "look": "default"}
。每个被路由到动态模板(
likes
、
notes
、
flow
、
side_by_side
、
progress
、
terminal
、
chat
、
toasts
、
curve
、
logo_cluster
)且至少留有 1 秒空间的 beat 都会转换成一个片段,最多转换
amount
个。其他路由目标(卡片、capture、sticker)中的 beat,如果其句子天然构成列表(四个或更多项目:
notes
)、数字(
likes
)、步骤(first... then...:
flow
)或前后对比(
side_by_side
),也会在相应类型开启时按句生成片段,且该句中不能已经包含动画;未通过检查的片段会回退到原始 beat。每个 beat 都会在
edits/<name>/motion/<id>/
下获得相应文件:模板中已填好尺寸、时长、外观和台词对应的时间信息,并包含
beat.json
(cut clock)和
brief.md
。外观设置参见
references/looks.md
(
default
,或该 style 的调色板与字体)。如果用户在聊天中提出要求("animate the part where I say X"):先在 visuals.json 中新增或修改对应 beat(style-edit
references/shapes.md
),然后运行 pick。

2. Build: one clip-builder agent per clip, all in one message

2. 构建:每个片段一个 clip-builder Agent,全部在一条消息中启动

For each
motion/<id>/brief.md
pick printed, launch the
clip-builder
agent (
${CLAUDE_PLUGIN_ROOT}/agents/clip-builder.md
, opus, background) with that brief's full path, every clip in ONE message. Each reads only its brief and
references/clip-brief-card.md
, builds
index.html
, and runs
motion.py check
at most 3 times. Never build the clips in the main session.
During a whole edit the cut skill launches them as soon as visual-prep returns, while the user is still reviewing the cut, so the clips are ready when the cut is approved.
对于 pick 输出的每个
motion/<id>/brief.md
,使用其完整路径启动
clip-builder
Agent(
${CLAUDE_PLUGIN_ROOT}/agents/clip-builder.md
,opus,background),并且在一条消息中启动所有片段的 Agent。每个 Agent 只读取自己的 brief 和
references/clip-brief-card.md
,构建
index.html
,并最多运行 3 次
motion.py check
。绝不要在主会话中构建这些片段。
在整个编辑过程中,cut skill 会在 visual-prep 返回后立即启动这些 Agent,此时用户仍在审阅剪辑,因此片段在剪辑获批时已准备就绪。

3. Check a clip (what each agent runs)

3. 检查片段(每个 Agent 执行的操作)

bash
python3 "${CLAUDE_PLUGIN_ROOT}/lib/ai_editor/run.py" "$M" check edits/<name>/motion/<id>
In order:
check_clip.py
(source gotchas, free),
hyperframes lint
,
hyperframes check --at-transitions
, render,
check_motion.py
(no stall, no spike, no frame-0 flash),
check_composition.py
(advisory),
measure_ink.py
, then
renders/sheet.png
(1 fps) and
renders/strip.png
(10 fps over the first 1.2 s). Writes
gates.json
. Thresholds:
references/clip-brief-card.md
. Why each gotcha bites:
references/build-loop.md
. The full rules:
references/visual-system.md
; several ideas in one clip:
references/scenes.md
.
bash
python3 "${CLAUDE_PLUGIN_ROOT}/lib/ai_editor/run.py" "$M" check edits/<name>/motion/<id>
按顺序执行:
check_clip.py
(检查源代码常见问题,免费)、
hyperframes lint
、
hyperframes check --at-transitions
、render、
check_motion.py
(检查无停顿、无异常峰值、第 0 帧无闪现)、
check_composition.py
(提供建议)、
measure_ink.py
,然后生成
renders/sheet.png
(1 fps)和
renders/strip.png
(覆盖前 1.2 秒,10 fps)。结果写入
gates.json
。阈值参见
references/clip-brief-card.md
。各项常见问题的成因参见
references/build-loop.md
。完整规则参见
references/visual-system.md
;在一个片段中呈现多个创意的方法参见
references/scenes.md
。

4. Look, then place

4. 查看效果,然后放置

When the agents return, read each
renders/sheet.png
yourself against its line (a fresh reader who was not told the beat is better: does it say the line?). A clip that reads wrong: send its agent the note, one more round. Then:
bash
python3 "$M" place edits/<name>
A passed clip becomes a
video_card
beat with the render (
images/motion-<id>.mp4
);
clip_motion.py
sets
start_s
so its motion finishes 0.25 s before the card leaves. A clip that did not pass after its rounds keeps its template beat (kept under
fallback
, restored by place). Then style-edit carries on from step 4 (plan, stills, render). Re-run place after any rebuild.
Agent 返回后,由你亲自对照相应台词查看每张
renders/sheet.png
。最好以一位事先不知道该 beat 的全新读者视角判断:它是否表达了这句话?如果读起来不对,向对应 Agent 发送修改说明,再进行一轮。然后:
bash
python3 "$M" place edits/<name>
通过检查的片段会成为包含渲染文件(
images/motion-<id>.mp4
)的
video_card
beat;
clip_motion.py
会设置
start_s
,让动态效果在卡片离开前 0.25 秒结束。经过指定轮次后仍未通过的片段会保留其模板 beat(存放在
fallback
下,并由
place
恢复)。随后,style-edit 从第 4 步继续执行(plan、stills、render)。每次重建后都要重新运行
place
。

5. Check it moving

5. 检查动态效果

Stills hide flicker. After the render, strips round at least four clip entrances, with the safe zone drawn:
bash
python3 "$M" strips edits/<name>/render.mp4 --at <t1>,<t2>,<t3>,<t4> --out edits/<name>/stills/motion-strips.png --safe
Each row runs 0.4 s before to 1.1 s after its time at 10 fps. Look for a part on one frame and gone, a blank frame between cards, a part that never moves while held, anything over the face, anything outside the box.
静态图会掩盖闪烁。完成 render 后,使用带安全区标记的 strips 至少检查四个片段入场点:
bash
python3 "$M" strips edits/<name>/render.mp4 --at <t1>,<t2>,<t3>,<t4> --out edits/<name>/stills/motion-strips.png --safe
每一行以 10 fps 覆盖对应时间点前 0.4 秒至后 1.1 秒。检查是否存在以下问题:某个元素只显示一帧便消失、卡片之间出现空白帧、元素停留期间始终不动、任何内容遮挡人脸,或任何内容超出画框。

Notes on a clip

关于片段的备注

A review-page note at a moment a clip is up ("make the counter bigger", "use blue"):
bash
python3 "$M" note edits/<name> "make the counter bigger" --at <note time>
It writes the note into that clip's
notes.md
and prints the clip. Give one
clip-builder
its
brief.md
(up to 2 more checks), then
place
, plan, and
edit.py patch
(style-edit): only that clip is rebuilt and only its span re-rendered (each placed render has its own file name, so the patch sees the change).
当片段显示时,通过审阅页在对应时间点添加备注("make the counter bigger"、"use blue"):
bash
python3 "$M" note edits/<name> "make the counter bigger" --at <note time>
该命令会将备注写入该片段的
notes.md
,并打印该片段。把对应片段的
brief.md
交给一个
clip-builder
(最多再执行 2 次检查),然后依次运行
place
、
plan
和
edit.py patch
(style-edit):只会重建该片段,并且只重新渲染它所占的时间区间(每个已放置的 render 都有独立文件名,因此 patch 能够识别该变更)。

The motion library

Motion library

When the user approves the render:
python3 "$M" save edits/<name>
. Each placed clip goes to
$AI_EDITOR_HOME/motion-library/<id>/
(composition, brief, thumbnail, the style it came from).
pick
gives a beat of the same kind the newest one (or the one marked "use again") as
start.html
: a starting point the agent re-times and changes, never a copy (
check
fails an unchanged one). Archived clips are never used. The window's style page lists them (Archive, Delete, Use again); in chat:
python3 "$M" library [archive|unarchive|use <id>]
.
当用户批准 render 后:
bash
python3 "$M" save edits/<name>
每个已放置的片段都会保存到
$AI_EDITOR_HOME/motion-library/<id>/
(包含 composition、brief、缩略图及其来源 style)。执行
pick
时,会将同类型中最新的片段(或标记为 "use again" 的片段)的
start.html
作为某个 beat 的起点:Agent 会在此基础上重新设置时序并进行修改,绝不能直接复制(
check
会判定未修改的片段失败)。已归档的片段绝不会被使用。窗口的 style 页面会列出这些片段(Archive、Delete、Use again);也可以在聊天中执行:
bash
python3 "$M" library [archive|unarchive|use <id>]

Settings

设置

style.json
motion
(the style page's Motion section writes it through the user's corrections):
amount
(0 none, 0.5 some, 1 lots; unset, a measured style's animation share),
kinds
(each on or off),
look
(
default
,
editorial
,
editorial-dark
,
mono
,
poster-red
,
poster-green
,
poster-blue
).
engine: "templates"
keeps the template cards.
style.json
的
motion
配置(style 页面的 Motion 部分会根据用户的修正写入其中):
amount
(0 表示无动画,0.5 表示适量,1 表示大量;未设置时采用测量所得 style 的动画占比)、
kinds
(每种类型分别开启或关闭)、
look
(
default
、
editorial
、
editorial-dark
、
mono
、
poster-red
、
poster-green
、
poster-blue
)。
engine: "templates"
会保留模板卡片。

The 50/50 style

50/50 style

A split-layout style (style.json
layout.mode: "split"
, the sample
50/50
): every clip is built for the panel's art box on the panel's ground and plays edge to edge; the
panel
gate (ground at the corners, ink over 55%) and the four proofs (
verify.mjs
) block. Variants, rules and the cutout:
references/fifty-fifty.md
.
分栏布局 style(
style.json
的
layout.mode: "split"
,示例为
50/50
):每个片段都针对面板的 art box 构建,以面板的 ground 为背景,并从一边播放到另一边;
panel
质量门禁(四角处为 ground、ink 超过 55%)以及四项验证(
verify.mjs
)会阻止片段通过。变体、规则和 cutout 参见
references/fifty-fifty.md
。

The Motion design style

Motion design style

A board-layout style (style.json
layout.mode: "board"
, the sample
Motion design
, 16:9): clips are overlays beside the speaker, 1200x964 in the
board
look (near-black ground, silver-white ink). Logos are not clips: they land as tiles on the canvas. The rules:
references/board.md
.
看板布局 style(
style.json
的
layout.mode: "board"
,示例为
Motion design
,16:9):片段会作为 overlay 显示在说话者旁边;在
board
look 下尺寸为 1200x964(近黑色 ground、银白色 ink)。Logo 不会作为片段处理:它们会以 tile 的形式落到画布上。规则参见
references/board.md
。

Skill styles

Skill styles

A user's own style skill gets bespoke animations with one line: "Animations: use the motion skill".
用户自己的 style skill 只需添加一行即可获得定制动画:"Animations: use the motion skill"。

If a script stops

如果脚本停止

messagedo
the motion tools are not installed
/
Animations fell back
setup.py motion
, then the same command; it fails again: say the line once and carry on without clips
a clip still
FAIL
after its checks (3 to build, 2 more per note)
leave it: place restores its template
no frames read
(strips)
the render path is wrong or the render failed: style-edit step 7
messagedo
the motion tools are not installed
/
Animations fell back
运行
setup.py motion
,然后重新执行同一命令;如果再次失败,则将该提示原样告知用户一次,并在没有片段的情况下继续执行
片段经过检查后仍为
FAIL
(构建阶段 3 次,每次备注后最多再检查 2 次)
保留该片段:执行
place
时会恢复其模板
no frames read
(strips)
render 路径错误或 render 失败:执行 style-edit 第 7 步

Files

文件

  • scripts/motion.py
    (pick, check, place, status, strips),
    check_clip.py
    ,
    check_motion.py
    ,
    check_composition.py
    ,
    measure_ink.py
    ,
    clip_motion.py
    : each with a
    demo
    self-check.
  • template/
    : the HyperFrames composition every clip starts from.
  • scripts/verify.mjs
    : the four proofs (clipped, rails, neighbour, reading), frame by frame in Chrome.
  • references/
    :
    clip-brief-card.md
    (the core every agent reads),
    visual-system.md
    ,
    build-loop.md
    ,
    scenes.md
    ,
    looks.md
    ,
    fifty-fifty.md
    ,
    board.md
    .
  • HyperFrames is Apache-2.0 (github.com/heygen-com/hyperframes), GSAP is under its standard no-charge licence (gsap.com/standard-license); both are installed from npm by setup, not shipped here.
  • scripts/motion.py
    (
    pick
    、
    check
    、
    place
    、
    status
    、
    strips
    )、
    check_clip.py
    、
    check_motion.py
    、
    check_composition.py
    、
    measure_ink.py
    、
    clip_motion.py
    :每个脚本都带有一个
    demo
    自检。
  • template/
    :每个片段开始时使用的 HyperFrames composition。
  • scripts/verify.mjs
    :四项验证(clipped、rails、neighbour、reading),在 Chrome 中逐帧执行。
  • references/
    :
    clip-brief-card.md
    (每个 Agent 都会读取的核心文档)、
    visual-system.md
    、
    build-loop.md
    、
    scenes.md
    、
    looks.md
    、
    fifty-fifty.md
    、
    board.md
    。
  • HyperFrames 采用 Apache-2.0 许可证(github.com/heygen-com/hyperframes),GSAP 采用其标准免费许可证(gsap.com/standard-license);两者均由 setup 通过 npm 安装,不包含在此处。