1实现原理 · 为什么它能做到
一个原理统摄五个接缝技法:在速度峰值处切、两侧方向与速度都要匹配;再加两个场景内技法(§6 入场级联 / §7 组滑移)。
Five SEAM techniques, one principle: **cut at peak velocity, match direction and speed on both sides of the cut** — plus the two in-scene techniques (§6 arrivals, §7 slides).
速度匹配的力学是「一条 power4.inOut 掰成两半」:出场 power4.in + 入场 power4.out,距离与时长相同,因此切点处速度精确相等。
- **Mirrored eases:** exit `power4.in` + entry `power4.out`, same distance and duration — the two halves of one `power4.inOut`, so velocity matches exactly at the cut.
默认场景边界是 cut-the-curve,且用部分位移:约画面 12%(1920 下≈230px),绝不是整幅离开画面;四个方向各有出场/入场的起止值(左:出 0→−230 / 入 +230→0,其余同理)。
**Partial travel:** ~12% of frame (≈230px at 1920) — never full off-screen moves. | Direction | Exit | Entry start → end | | --------- | ------------- | ----------------- | | Leftward | `x: 0 → −230` | `x: +230 → 0` |
淡出技巧:出场不透明度在其位移的 ~25–30% 处就走完(淡出≈0.18–0.3s vs 运动 0.3–0.34s),入场在路径中途 ~0.35 不透明度点火;最后一个淡出的元素要正好死在切点上——留一个什么都不动的空档会被读成 dead air。
- **The fade trick:** exit opacity completes at ~25–30% of its travel (fade ≈ 0.18–0.3s vs motion 0.3–0.34s); entry ignites at ~0.35 opacity mid-path. Time the last fading element to die right at the cut — a gap where nothing moves reads as dead air.
Z 轴方向是符号:同轴不够,d(scale)/dt 的符号必须两侧一致(推:出场 1→1.2 / 入场 0.75→1;拉:出场 1→0.8 / 入场 1.25→1);被禁的镜像有两种——收缩出场配从小长大的入场(最常见,因为 grow-from-small 是元素默认入场),以及推出场配超大回缩。且这条约束**同时绑定入场场景自身的入场动画**(切点 + ~0.5s 窗口),要按 Seam Gate 第 7 条核对。
| Push (forward) | growing `1 → 1.2` | growing `0.75 → 1` | zoom-through | | Pull (back) | shrinking `1 → 0.8` | shrinking `1.25 → 1` | inverse zoom-through |
模糊按主体尺度分档:文字尺度(标题、词组)峰值 10px(20px 会把字形抹花,读成故障而不是速度);满幅面(窗口、卡片、截图)18–20px(大面上轻模糊读成渲染打嗝);两侧在交换帧上用相同峰值;模糊 wrapper,绝不模糊子元素。
| Text-scale (headline, word group) | **10px** | 20px smears letterforms — the cut reads as a glitch, not speed | | Full-frame surface (window, card, screenshot) | **18–20px** | lighter blur on a big surface reads as a rendering hiccup |
waterfall cut(§4)与 waterfall entry(§6)是两套规则,不可混用:接缝版在 0.35 不透明度中途点火(淡入本身即速度技巧),入场版用 tl.set 二值 0→1(淡入会削弱 snap);接缝版轴默认 X 随电流、有出场侧,入场版轴默认 Y、无出场侧。
| Opacity | BINARY 0→1 via `tl.set` at entry — never fade | ignites at 0.35 mid-path — the fade IS the velocity trick | | Axis default | Y, from below | X, riding the current | | Outgoing side | none | words ramp out on mirrored power4.in |
waterfall entry 的编排判据:接力不是排队——下一个元素在前一个稳定前(±2 帧)就起步,间隙逐级收缩,末元素啪地到位;速度按元素重量分级(锚点/重 60–80px、0.16–0.20s;普通词 40–50px、0.13–0.16s;轻词/标点 30–48px、0.10–0.13s);ease 用 power4.out,入场绝不用 .inOut;末期把最后一个词拆成碎片以延长高潮。
- **Overlap, don't queue** — next element starts within ±2 frames of the previous settling; gaps SHRINK across the cascade; the last element snaps. - **Velocity varies by weight** — heavy/anchor elements travel further and longer; light words/punctuation snap in tight:
nudge curve(§7)是三次 tween 串成的一条曲线,10% / 65% / 25% 距离对应 20% / 18% / 62% 时间:power3.in 起手、linear 爆发(~2× 平均 px/帧)、power4.out 长尾收尾;尾巴时间 ≥3× 起手时间,否则易顿死;新内容要在爆发相里揭示(爆发掩盖其出现)。
| 1 ramp-in | `power3.in` | ~10% | ~20% | barely moves — motion registers, no jolt | | 2 burst | `none` (linear) | ~65% | ~18% | ~2× average px/frame — purposeful | | 3 tail | `power4.out` | ~25% | ~62% | decaying creep to rest — kills the smack |
rack-focus blur-cut(§5)是唯一「让切被看见」的变体:散焦模糊尖峰遮住单帧硬交换(手持 DSLR 拉焦);出场保持完全不透明直到切点,ease 用 power2.in/out(光学感而非动量感),只在叙事 beat 上、≤ 每 ~8s 一次、绝不在字幕中或保持镜头里使用;模糊峰值 ≥6px、常规 8–12px、上限 16–18px;切必须在峰值模糊处。
The one variant where the cut is SEEN: a defocus blur SPIKE hides a single-frame hard swap — a handheld-DSLR focus-pull.
所有可执行代码集中在 examples/gsap-implementation.md:worker 版(改场景内元素)与 registry 版(注入器打在两个 clip wrapper 上,用 __OLD__/__NEW__/__T__/__DUR__/__DX__/__DY__ 占位)各一套,外加 waterfall 的 DOM/CSS/JS、rack-focus,并附调参区间表。
All GSAP templates — worker-authored versions, registry `gsap_template`s, the combined cut-the-curve + zoom, waterfall DOM/CSS/JS, rack-focus — live in `examples/gsap-implementation.md`.
waterfall cut 的实施细节:travel 用 ±230px、出场 0.34s power4.in、出场淡出 0.18s 且随 x 一起起步(词在位移的 ~25–30% 处就没了,不出拖影)、出场按阅读序 +0.022s 错峰(是「剥落」不是整块滑动)、入场 0.3s power4.out、入场起点 0.35 不透明度、入场间隙 0.05s × 0.84 衰减;且必须在构建期把所有词预置为 x:+230 / opacity:0(只靠 immediateRender:false 会让未启动的词停在可见的静息位)。
- Pre-set all words to `x: +230, opacity: 0` at build time — `immediateRender: false` alone leaves un-started words visible at rest.
cut-the-curve 的入场侧在 registry 模板里用 __DXIN__ / __DYIN__ × 0.12(横)/ × 0.21(竖)表达反向入场位移,而 seam-craft 的占位符表只列 __DX__ / __DY__——两侧 token 命名不闭合。
`__DX__` = `-1920` (LEFT) / `1920` (RIGHT); `__DY__` = `-1080` (UP) / `1080` (DOWN). The `* 0.12` / `* 0.21` factors yield the ~12% partial travel.
worker 版与 registry 版的合并变体(cut-the-curve + 轻微 Z 拉)也遵守 Z 符号规则:两侧都收缩(出场 1→0.92、入场 1.08→1),绝不把收缩出场配从小长大的入场。
The scale component obeys the Z sign rule: both sides SHRINK (exit `1 → 0.92`, entry `1.08 → 1`) — a consistent mild pull layered on the lateral cut. Never pair a shrinking exit with a grow-from-small entry here.
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| package | 上位 skill 依赖:motion-doctrine(接缝法、电流、账本、Seam Gate 的归属地) |
| package | 同仓组件:transition registry 的 gsap_template(注入器按 token 施加到两个 clip wrapper)、seam-craft(stage ground 前置) |
| package | GSAP(模板代码运行于宿主 composition 的 GSAP 时间线;本 skill 不自带库) |
4风险提醒 风险提醒:绿色 · 放心使用
- registry 模板的 token 与 seam-craft 的占位符契约不闭合(__DXIN__/__DYIN__ 未在契约表中) — examples 的 registry 版入场用 `__DXIN__ * 0.12` / `__DYIN__ * 0.21`,而 seam-craft 只声明 __DX__/__DY__。照抄这份模板去注入,入场侧位移 token 无法被替换(或被替换为空),表现为入场不动或注入报错。
- 参数密集且彼此耦合,脱离上位 skill 单独读易误用 — 本页只给力学;向量律/电流/ledger 在 motion-doctrine。若只加载这一页,代理可能写出「单点正确但接缝方向乱」的片子(反模式表里 consecutive boundaries in opposing directions 就是这个症状)。
- rack-focus 有配额但无机器检查 — 「≤ 每 ~8s 一次」「never mid-caption」靠人/代理守,没有 seamer 或 lint 能数次数。
- 数值面向 1920×1080,跨画幅需换算 — ±230px(~12%)、模糊 8–10px / 18–20px 都以 1920 为基准;changelog-video 用 1080×1080 方画幅,照搬像素值会偏离「12% 位移」的意图(应换算而非直接抄)。
- 跨页引用的 stage ground 表达式与仓库现状有差 — 本页与 seam-craft 都写 `var(--canvas-deep, var(--canvas, #000))`,但该变量在 pin 内零命中(实际由 assemble-index.mjs 写 frame.md 的 canvas 色)。照抄通常仍可渲染,但可能与真实配色不一致。
5第二遍独立确认
- [ok] 「五个接缝」是否每条都有可抄实现(防止目录表吹牛) — examples/gsap-implementation.md 逐条核对:§1 Zoom-Through(worker + registry 两版)、§2 Inverse(registry 版 + 说明 worker 只是翻符号)、§3 Cut the Curve(worker + registry 横/竖两版 + 合并 zoom 版)、§4 Waterfall Cut(DOM/CSS + wordExit/wordEnter 时间线函数)、§5 Rack-Focus、§6 Waterfall Entry、§7 Nudge Curve(含 150px 变体)。声明与实现相符。
- [discrepancy] registry 模板的 token 是否与 seam-craft 的占位符契约一致(跨 skill 引用是否自洽) — 存在一处不闭合:examples 的 registry 模板入场用 `__DXIN__ * 0.12` / `__DYIN__ * 0.21`(而注释只解释 `__DX__ = -1920 (LEFT) / 1920 (RIGHT)`),但 seam-craft 的占位符表只列 `__OLD__ / __NEW__ / __T__ / __DUR__ / __DX__ / __DY__ / __ORIGIN_OUT__ / __ORIGIN_IN__`——**没有 `__DXIN__` / `__DYIN__`**。即这份模板若要真被注入器施加,入场侧的水平/垂直位移 token 名对不上(需注入器额外提供或模板改为取负)。属跨文档的 token 命名漂移,照抄可能注入失败或被替换为空。
- [ok] 难度最高的那条规则(Z 符号绑定入场场景自身入场)是否在别处有一致说法 — cut-the-curve 的 Z 符号段 + 反模式表两处,以及 §2 的 Sign discipline(`the incoming scene arrives as a composed frame inside the retracting wrapper — no grow-from-small intro in the seam window`)措辞一致;motion-doctrine 的 Seam Gate 段亦列 `the Z sign rule … the incoming scene's own entrances are scanned for sign-fighting`,三处自洽。
- [ok] §3 列出的 stage ground 前置与 seam-craft 是否一致(跨页重复会不会打架) — 两页都写 `background: var(--canvas-deep, var(--canvas, #000))`,且本页显式 `(see seam-craft)` 交回详情;无参数冲突。该表达式与代码实现的形式差异(pin 内 canvas-deep 零命中、assemble-index.mjs 实际输出 frame.md canvas 色)已记在 seam-craft 的分析中。
- [ok] 数值是否被第一遍夸大(例:把 rack-focus 的配额写成建议值) — 原文硬写 `≤ once per ~8s; never mid-caption or during a hold`,并给上下限 `≥6px; peak 8–12px, ≤16–18px max`;本 JSON 照录,未软化。
- [ok] 是否存在被遗漏的外部资源(CLI/API/包) — 两文件全文 URL 零命中;无 npx/CLI 调用语句。唯一外部依赖是 GSAP 运行时(由宿主 composition 提供)与同仓的 motion-doctrine / transition registry / seam-craft(文档互指)。
6结论
f788ef0474b6f6ce…d2f0bc7f34