HyperFrames Motion Doctrine(Seam Gate)解读:如何让多场景动画看起来像一条连续的长镜头
【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes
本篇指南解析 hyperframes 仓库内置的动效总纲技能——.claude/skills/motion-doctrine/SKILL.md。它是所有 HyperFrames 动画/视频编排前的第一道总入口(GATEWAY):用「矢量定律(Vector Law)」「主线方向(The Current)」「矢量台账(Vector Ledger)」「载体(Carrier)」「因果动效(Causal Motion)」「缝合闸门(Seam Gate)」等一整套可执行规则,解决"多场景视频看起来像一叠互不相关的独立幻灯片"这一核心失败模式。读完你将掌握:如何规划跨场景的切入/切出方向与速度、如何编写并运行缝合闸门脚本对每个切点做数值化审计、以及如何在场景间维持"永不静止"的持续动效。
这套教义管什么:两个层级与一张路由表
motion-doctrine 只回答"每个接缝处该发生什么、每个场景如何表演"的高层决策;具体怎么做由底层技术技能实现。两者通过一张路由表(Route map)衔接,这正是阅读全仓库时最先需要建立的坐标系:
| 决策(本技能负责) | 实现技能(仓库内位置) |
|---|---|
| 接缝转场的选择 + 参数 + 代码 | cut-the-curve§1–5(含完整技法目录) |
| 文字 / 元素的入场级联 | cut-the-curve§6(waterfall entry 瀑布入场) |
| 场景内群组重排(不切镜) | cut-the-curve§7(nudge curve 微调曲线) |
| 光标驱动的动作 / 场景开局 / 变形点火 | oversized-cursor |
| 接缝的渲染机制 / 白闪防护 | seam-craft |
| 产品发布 / 解说 / 字幕工作 | 叠加层技能text-beat-economics、brand-faithful、captions-overlay(其中 captions-overlay 就在本仓库.claude/skills/captions-overlay/) |
按照教义,authoring 的先后顺序是固定的:
先写矢量台账ledger.json→ 用scripts/seam-stamp.mjs从台账盖印主接缝(--write index.html)→ 按阶段分配持续动效路线 → 载体与因果 → 构建合成 → 用scripts/seam-gate.mjs验证。
其中 Tier-A 级的手写 morph/match-cut 需要手工打磨;由台账盖印出的接缝"按构造"天然通过闸门检查。
这套技能在仓库中的实际用途之一,是驱动每周 changelog 视频的编排:参见.claude/skills/README.md,它把 motion-doctrine、cut-the-curve、captions-overlay、seam-craft、oversized-cursor 五者组织为完整的技能路由图,产出受seam-gate verify(0 fail / 0 warn)约束的成片。
Part 1 — 接缝定律(The Seam Law)
矢量定律:怎么出去,就怎么进来
场景 A 如何退场,决定了场景 B 如何进场:同一根轴、同一方向、匹配的速度、两侧都在运动中完成切换。
拆成四条不可违背的规则:
- 轴(Axis)——x 保持 x、y 保持 y、Z 保持 Z,跨越接缝时绝不交换轴。
- 方向(Direction)——绝不镜像。在 Z 轴上,方向 = 缩放变化的正负号:变大 = 推进(push,镜头向前),变小 = 拉远(pull,镜头后退)。一个"退去式退场"却被一个"从小变大式入场"接住,就是镜像矢量——因为 grow-from-small 是元素默认的入场方式,这恰是最常见的违规。
- 速度(Speed)——入场初速度 ≈ 退场末速度。靠镜像缓动实现:退场
power4.in+ 入场power4.out,距离与时长相同;入场侧要在名义路径的中点之后(≥50%)才真正出现。力学细节见cut-the-curve。 - 相位(Phase)——切换发生在两侧都运动到一半时。切前先停下、或切后从静止出发,都是"死拍"(dead beat)。
主线方向(The Current):每个片子只有一个主方向
每部片子必须选出一个主导方向(house 默认是 LEFT)。所有普通接缝都沿这个方向走,其余矢量是保留项——花掉一个就表示"发生了某件事":
| 矢量 | 含义 |
|---|---|
| 主线方向(LEFT) | "下一个节拍"——中性的向前推进 |
| 向上 | 提升(elevation)——一个结论或揭示升到之前内容之上 |
| Z 向前(zoom-through) | 朝同一想法的更深处推进 |
| Z 向后(inverse zoom) | 到达(ARRIVAL)——某个更大的东西落地 |
| 尺寸爆发(explode out) | 离开一个世界——表面炸过镜头 |
配套纪律:
- 绝不在连续接缝中跑相反方向——来回摆(ping-pong)在观众眼里等于错误。
- 方向改变必须有可见的因(点击 / 弹跳 / 撞击)或章节边界。
矢量台账(Vector Ledger):动手写主时间轴之前先落账
在任何主时间轴编排开始前,先把它写成项目根目录的ledger.json(schema 见.claude/skills/motion-doctrine/references/seam-gate.md)。每个接缝一行,记录:切换时刻、退场与入场矢量(轴 + 带符号的方向;Z 行走的行要带缩放的符号)、选择器、技法。退场与入场必须一致;若某一行不一致,修的是计划,而不是缓动。验证器会在任何运行时采样之前,先静态检查台账各行的自洽性。
一个可运行的ledger.json参考(含 match-cut 行与 Z 行):
{ "fps": 30, "seams": [ { "id": "hook→claim", "cut": 4.2, "technique": "cut-the-curve LEFT", "exit": { "selector": "#el-hook", "axis": "x", "dir": -1 }, "entry": { "selector": "#el-claim", "axis": "x", "dir": -1 } }, { "id": "claim→payoff", "cut": 10.2, "technique": "inverse zoom-through", "exit": { "selector": "#el-claim", "axis": "z", "dir": -1 }, "entry": { "selector": "#el-payoff", "axis": "z", "dir": -1, "scanRoot": "#el-payoff" } }, { "id": "ui→player (match cut)", "cut": 60.6, "type": "match-cut", "carrier": { "out": "#resting-card", "in": "#product-video" } } ] }字段语义(来自references/seam-gate.md的 ledger schema 段落):
cut——主时钟上的秒数,即入场侧被点燃的那一帧;type——"cut"(默认,做完整矢量校验)或"match-cut"/"morph"(只校验载体连续性与零重叠;运动可以在边界处才启动);axis——"x"/"y"/"z"(z = 缩放);dir——运动符号:x −1 = 向左、y −1 = 向上、z +1 = 推进(变大)、z −1 = 拉远(缩小);selector——真正承载接缝运动的元素:若主时间轴动的是 wrapper 就用 wrapper;若接缝运动是在子合成内部写的,则用合成内的英雄元素(id 或[data-hf-id=…])。probe命令会告诉你该选哪个;entry.scanRoot(Z 行)——扫描"符号相冲的内部入场"的子树,默认等于入场选择器;carrier——"cut"行可省略;match-cut / morph 行必填。out/in两个矩形在 cut±1 帧内必须匹配(中心偏移 ≤12px / 尺寸差 ≤5%,含祖先缩放)。
载体(Carriers):眼睛跟的是物体,不是抽象概念
最强的接缝会把一个具体载体以匹配的位置 AND 速度递过切点:行进到一半的光标、缩进/停靠进下一布局的容器、飞入自己槽位的标记、瀑布切中整组字词。若没有天然载体,则由场景英雄元素承担(走一段路程 + 提前淡出、入场在飞行中段开始)。永远不要用 crossfade——它根本没有载体。
载体连续性的判断依据可从.claude/skills/seam-craft/SKILL.md延伸理解:在两个 scene wrapper 交叠的时间窗里,渲染器如何做 ping-pong 轨道分配、如何保持前一场景末帧——这些是载体矩形能在两帧间对齐的渲染前提。
因果动效(Causal Motion):每个动作都由上一个动作"可见地"触发
把动作串成因果链:click → squash → release spring → flight → impact → recoil → reveal。三条铁律:
- 效果在导致它的那一帧启动——同一时间轴位置,绝不"稍后片刻";
- 反应与表观质量成比例:大元素回弹慢,小元素弹得利落;
- 一个力是改变方向的许可证;无缘无故的翻转就是 ping-pong。
光标是这套因果最典型的执行器:oversized-cursor 技能规定"点击点燃下一拍"必须同帧发生(点击 ▸ 菜单级联 / 打字启动 / 窗口形态下压 / logo 点火 / 播放状态翻转),详见.claude/skills/oversized-cursor/SKILL.md。
Seam Gate:构建闸门(跑验证器,退出码 0 才算做完)
这是全篇最有工程价值的部分:把"接缝美学"变成可数值验证的构建门槛。
node .claude/skills/motion-doctrine/scripts/seam-stamp.mjs --ledger ledger.json --write index.html # 生成 node .claude/skills/motion-doctrine/scripts/seam-gate.mjs verify --ledger ledger.json --project . # 验证脚本(用法 + ledger schema 完整见.claude/skills/motion-doctrine/references/seam-gate.md)对每个接缝做数值化强制检查:
| 报告行 | 对应规则 |
|---|---|
ledger | 计划中退场/入场矢量匹配(轴 + 方向) |
exit-moving/entry-moving | 规则 1/3——不允许已静止的退场、不允许从静止开始的入场 |
exit-direction/entry-direction | 规则 3——实测符号与台账方向一致 |
speed-match(WARN) | 定律 §3——入场速度 ≈ 退场速度 |
zero-overlap | 规则 6——每帧只可见一侧,绝不能两侧同时可见 |
z-sign-scan | 规则 7——入场场景自己的入场不与 Z 符号相冲 |
carrier-* | 规则 3/4——载体矩形连续性,含祖先缩放 |
zero-overlap与z-sign-scan直接照应前文的方向规则:切换不是溶解(dissolve),Z 轴两侧的 d(scale)/dt 必须同号,且入场场景自身在接缝窗口(cut + ~0.5s)的内部入场也会被扫描、防止符号打架。实测细节可以回看.claude/skills/motion-doctrine/scripts/seam-gate.mjs:速度基于getBoundingClientRect采样(x/y 用中心点,z 用宽度比),因此祖先 wrapper 的变换会被自动计入;zero-overlap通过cumOp(沿 DOM 祖先链累乘 opacity)判定可见性,阈值取 VIS = 0.04。
三条脚本管不到的规则——仍由你负责
- 任何编辑都会重新打开接缝。只要改了某个场景开头/结尾约 1 秒的内容(包括为新 VO 重新对时),该边界的审计就失效——必须重跑验证器。
- 音频是时钟。场景重排要贴合 VO 里真实的词时间戳,绝不为凑时间槽赶一段旁白。VO 重生成后,其涉及的接缝同样要重新开放审计。
- Clip 门控陷阱(
zero-overlapFAIL 最常见的元凶):某个 clip 的data-start若早于其入场 tween,就会以初始透明度被提前显形——必须同时设初始autoAlpha: 0且data-start= 切点时刻,绝不更早。
seam-stamp 盖印机制:为什么"盖印的接缝按构造通过"
从.claude/skills/motion-doctrine/scripts/seam-stamp.mjs的源码可以看出生成端如何把台账翻译成主时间轴 GSAP 代码:
- 只做生成,可打印(默认输出到 stdout)或
--write index.html回写;--write替换// <seams:auto>与// </seams:auto>之间的区块,没有标记时则插入到window.__timelines["main"] = tl;注册行之后。 - 逐行解析时若发现
exit.axis !== entry.axis || exit.dir !== entry.dir直接抛错:修计划,不修盖印——这与教义一致。 - Z 接缝的入场选择器会自动登记基础态:pull(dir −1)到达时是
scale: 1.25的过大型,push(dir +1)到达时是scale: 0.78的小型再长大——正是 Z 符号规则的编码化。Z 默认模糊 18px,文字级可置blur: 10。 - x/y 接缝默认按
exit.dur 0.34s power3.in+entry.dur 0.42s power4.out、偏移travel(xPercent/yPercent,默认 10)盖印,入场侧以autoAlpha 0.35中途点火(mid-path ignition)。 - match-cut / morph 行只写入两侧的可见性
tl.set,载体交接保持手写(Tier-A)。
与此配套的示例宿主文件是.claude/skills/changelog-video/examples/master-skeleton.html,其注释明确标注:每个 slide 的data-start= ledger 切点时刻、每行末尾预留// seam-stamp.mjs inserts the <seams:auto> block after the registration above——这就是"台账 → 盖印 → 主时间轴"在真实 HTML 合成里的落点。
seam-gate 的命令形态
完整用法(在references/seam-gate.md中有记录):
# 校验台账中的每个接缝(exit 0 = 闸门通过) node .claude/skills/motion-doctrine/scripts/seam-gate.mjs verify --ledger ledger.json --project <project-dir> # 复用正在运行的预览服务器(合成改动后必须重启它——否则校验的是陈旧 bundle!) node .claude/skills/motion-doctrine/scripts/seam-gate.mjs verify --ledger ledger.json --url http://localhost:5244 # 在切点附近发现运动元素(用于编写/修正台账行) node .claude/skills/motion-doctrine/scripts/seam-gate.mjs probe --t 44.8 --project <project-dir>要点(来自源码头部注释与 references 文档):
--project会以HYPERFRAME_RUNTIME_URL未设置的环境拉起一个全新的预览服务器并在结束后杀掉——首选方式;--url则复用正在运行的服务器(适合带端口校验的本地开发,但记得重启)。--json输出机器可读结果;--fps 30为默认采样帧率。- 零 npm 依赖(node ≥ 22 + 本地 Chrome);通过原始 CDP 驱动 chrome-headless-shell,自动在
~/.cache/puppeteer或系统 Chrome 中查找,可用CHROME_PATH覆盖。 - probe 输出的行会直接告诉你应填入台账的 selector 与符号(
x-: 左、y-: 上、scale+: 推进、scale-: 拉远)。
Part 2 — 表演层:场景要一直"在演"(Performance)
禁止无意义的晃动(No idle wobble)
持续性的 idle 正弦循环(breathe、float、drift、glow pulse)被明令禁止——它们会让观众觉得"视频在等待"。一个入场完成后还剩几秒的场景是规划 bug:应该加内容(story),而不是加晃动。入场与出场之间的每个阶段,必须被下面某条路线接管(计划里要写明用了哪条):
| 路线 | 它是什么 |
|---|---|
| 分阶段揭示(Staged reveals) | 先按住内容不展示,按旁白节拍逐段兑现——画面持续获得新信息(≥2 组内容的默认路线) |
| 有意图的镜头(Camera with intent) | 一条映射好的 scale+pan 路径:建立全景 → 旅行 → 抵达主体 |
| 序列化 UI 生命(Sequenced UI life) | 产品随时间"行动":进度推进、高亮跳步、计数走动 |
| 动画序列(Animated sequences) | 元素演出一段节拍:一张卡归入堆叠、一项被拖拽、一个结果拼装完成 |
| 光标驱动动作(Cursor-led action) | 超大光标把眼睛领到触发器;它的 CLICK 点燃下一拍(见 oversized-cursor) |
自测法:在任意秒暂停——必须有一个有意义的东西正在运动途中(一个揭示正在落地、镜头在旅行、UI 正按旁白做事)。这条"暂停测试"在.claude/skills/README.md描述的周更 changelog 流程里被seam-gate verify外的严格流程约束强化着。
高潮前的静止(Stillness before climax)
在大动作与它的结果之间安排一段0.3–0.75s 的停顿——戏剧性的逗号。直接"动作跳结果"的场景会丢掉这个张力。
时间意图(Timing intents)
- 单一入场 ≤ ~800ms;更长的铺陈应该用多元素错峰(stagger),而不是一个慢吞吞的元素。
- 退场 ≈ 入场的 75%。例外:cut-the-curve 会反转这个比例(入场 ~127% 的退场)。
- 总错峰 ≤ 500ms;8+ 个元素时收紧单项延迟或只错开前几个。
- 禁用缓动:
bounce.out/elastic.out。入场过冲back.out(1.4–1.7)没问题。 - 相似元素共享同一组 ease + duration 意图——绝不每个元素配一套独有参数。
转场词汇量(Transition vocabulary)
一部片子只用 2–3 种场景间转场并反复使用;默认边界是沿主线方向的 cut-the-curve。手写的共享元素 morph(intent: morph)不计入这个预算。对应的完整技法选型矩阵(Zoom-Through vs Inverse Zoom vs Cut the Curve vs Waterfall Cut 的适用场景、Z 符号、travel/scale、峰值模糊、缓动与手感)可以在.claude/skills/cut-the-curve/SKILL.md的 "Choosing a Variant" 一节中查到,配合其 §6 瀑布入场与 §7 nudge 曲线(慢-快-慢三阶段群组滑移)构成整本技法目录;所有 GSAP 代码模板见.claude/skills/cut-the-curve/examples/gsap-implementation.md。
反模式速查表
这是教义的"红牌清单",可直接作为评审 checklist 使用:
| 不要这样做 | 应该这样做 |
|---|---|
| 孤立地为每个场景编写入场 | 先写矢量台账 |
| 场景之间用 crossfade | 沿主线方向做 cut-the-curve |
| 退场完全结束,然后场景才切换 | 两侧都在运动中完成切换 |
| 切后从静止开始入场 | 在名义路径 ≥50% 处进入 |
| 反向变焦退场 → 从小变大入场(或推进 → 超大回缩) | 匹配缩放速度的符号(Seam Gate 第 7 条) |
| 入场场景在 Z 交接下自带 pop-in 开场 | 让它的开场帧保持已构图,或匹配符号 |
| 用 idle wobble / breathe / float 填充时间 | 分配一条持续动效路线;或加内容 |
| 无因的方向翻转 | 花一个力,或保持主线方向 |
| 把保留矢量当"多样性"用 | 默认走主线;为含义而花掉保留矢量 |
| 反应比它的因晚几帧 | 同帧点火 |
| 动作直接跳到结果 | 安排 0.3–0.75s 的高潮前静止 |
关于反模式在实现侧的落地,可以补充两条来自姊妹技能的印证:cut-the-curve 的模糊分级(文字级 10px、整屏表面 18–20px,且只在 swap 帧两侧取相同峰值并作用于 wrapper)与"推拉镜像"禁令,见.claude/skills/cut-the-curve/SKILL.md;而"场景间 opacity 总和 < 1 的窗口"会透过底层白色页面形成白闪这一渲染事实,以及#root { background: var(--canvas-deep, var(--canvas, #000)) }这一不透明舞台地面防护,见.claude/skills/seam-craft/SKILL.md。
结语:教义的本质是一台"可执行的审美编译器"
motion-doctrine 最有价值的地方在于:它把通常只能靠感觉评判的"镜头语言连续性"翻译成了 ① 写进ledger.json的结构化计划、② 由seam-stamp.mjs从计划生成的代码、③ 由seam-gate.mjs用真实渲染采样强制验收的三段式流水线。矢量定律管方向、主线方向管语义预算、载体管"眼睛跟谁走"、因果管"为什么动",而 Seam Gate 的每一行报告(exit-moving、zero-overlap、z-sign-scan、carrier-*……)都是对"这一剪到底成不成立"的确定回答。结合仓库内已有的 changelog 主骨架示例与底层的 cut-the-curve / oversized-cursor / seam-craft 技能,你可以把这套工作流直接复制到自己的 HyperFrames 多场景合成上。
【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考