HyperFrames Cut the Curve 转场技巧:完整 GSAP 代码模板、Registry Token 机制与调参指南
本文基于仓库中的 GSAP 实现模板文档,系统讲解 HyperFrames 视频合成体系里 "Cut the Curve" 技巧目录的 7 种转场/进场代码模板:前向/反向 Zoom-Through、场景级 Cut the Curve、逐词 Waterfall Cut、Rack-Focus Blur-Cut,以及场景内的 Waterfall Entry 与 Nudge Curve。读完本文,你可以直接复用这些模板编写场景切换动画,理解 registry gsap_template 的 token 注入机制,并按文档给出的调参范围精确控制速度匹配(velocity matching)。
模板文档的定位:worker 版与 registry 版两套体系
GSAP 实现模板文档 是 cut-the-curve 技能目录 中"参数与规则在 SKILL.md,代码从这里复制"的配套文件。它维护着两种不同用途的 GSAP 实现:
- Worker 版:由 worker(作者 agent)手写的、对场景内元素(in-scene elements)做 tween 的完整代码,使用真实的选择器(如
.text-a-wrapper)和具体的时间点变量,适合在单个合成(comp)内手工编排。 - Registry
gsap_template版:带 token 占位符的模板代码,由注入器(injector)在装配主时间轴时替换 token 并"盖章"(stamp)到两个 clip wrapper 上。
registry 模板中的 token 含义(见 seam-craft 技能文档 的 Template placeholders 一节):
| Token | 含义 |
|---|---|
__OLD__ |
出场 clip wrapper 选择器,形如 "#el-<from>"(带引号) |
__NEW__ |
入场 clip wrapper 选择器,形如 "#el-<to>"(带引号) |
__T__ |
重叠窗口起点时间(秒,主时钟) |
__DUR__ |
该边界的 duration_s |
__DX__ |
水平行程:-1920(LEFT)/ 1920(RIGHT) |
__DY__ |
垂直行程:-1080(UP)/ 1080(DOWN) |
__ORIGIN_OUT__ / __ORIGIN_IN__ |
squeeze 类型用的 transformOrigin 对 |
从注入器机制看(seam-craft 文档描述):在场景 i 与场景 i+1 的边界处,注入器会把 #el-<from> 的 data-duration 延长 duration_s(保持其最后一帧)、把 #el-<to> 的 data-start 前移 duration_s 形成重叠窗口,并将所有 clip 的 data-track-index 重新排为 0/1 乒乓(同 track 重叠非法,高 track 的合成在上层),最后把 gsap_template 写入 window.__timelines["main"],时间点取 T = overlap-start。这解释了模板中为什么 __OLD__ 与 __NEW__ 的 tween 都从同一个 __T__ 起始——两者在主时间轴上是并行重叠的。
1. Zoom-Through(前向穿越)
前向 Zoom-Through 用于"向同一思想更深处推进"的 Z 轴转场:出场文字向镜头加速放大,在峰值模糊处硬切,入场文字从小尺寸继续生长到焦平面。总时长约 0.4s。
Worker 版(场景内 wrapper 交换)
var EXIT_START = /* when readable text starts leaving */;
var CUT = EXIT_START + 0.2;
// Phase 1: Exit — scale/blur accelerate, opacity fades linearly (separate tween)
tl.to(".text-a-wrapper", {
scale: 1.2,
filter: "blur(10px)", // text-scale: 10px
duration: 0.2,
ease: "power3.in",
overwrite: "auto"
}, EXIT_START);
tl.to(".text-a-wrapper", { opacity: 0.15, duration: 0.2, ease: "none" }, EXIT_START);
// Phase 2: Hard cut — matched properties
tl.set(".text-a-wrapper", { opacity: 0 }, CUT);
tl.set(".text-b-wrapper", { opacity: 0.15, scale: 0.75, filter: "blur(10px)" }, CUT);
// Phase 3: Entry — fast initial velocity, long settle
tl.to(".text-b-wrapper", {
scale: 1, filter: "blur(0px)", opacity: 1,
duration: 0.5, ease: "expo.out"
}, CUT);
关键细节:
- 退场的 opacity 必须是独立的线性 tween(
ease: "none")——若挂在power3.in上,opacity 会在接近 1 的区间停留过久,硬切帧上就会看到"还在"的旧文字。 - 切帧(
CUT时刻的tl.set)上,两侧属性必须严格对称匹配:出场侧opacity: 0,入场侧opacity: 0.15, scale: 0.75, filter: "blur(10px)",保证交换帧两侧的模糊/透明度一致。 overwrite: "auto"防止与其他针对同一 wrapper 的 tween 打架。
Registry gsap_template 版
tl.to(
__OLD__,
{ scale: 2.5, opacity: 0, filter: "blur(8px)", duration: __DUR__, ease: "power3.in" },
__T__,
);
tl.fromTo(
__NEW__,
{ scale: 0.5, opacity: 0, filter: "blur(8px)" },
{ scale: 1, opacity: 1, filter: "blur(0px)", duration: __DUR__, ease: "power3.out" },
__T__,
);
注意 registry 版与 worker 版的数值差异:registry 版作用于整帧 clip wrapper,行程更大(0.5 → 1 / 1 → 2.5)、模糊更轻(8px)、且是 fromTo 并行结构;worker 版作用于场景内的文字 wrapper,模糊取 10px(文字级峰值模糊)。这段模板在仓库中有真实的 registry 落地:product-launch-video 技能的 transitions.json 中 zoom-through 条目逐字一致,且标注 default_duration_s: 0.4、energy: "high",并被登记为该 workflow 的 default_high_energy 转场(skills/pr-to-video 与 skills/faceless-explainer 下各有一份同构的 vendored 副本)。
2. Inverse Zoom-Through(反向穿越)
反向版本:出场元素后退,入场元素以超大尺寸(仿佛刚从镜头后方探出)收缩回焦平面。整体"都在缩小",用于"更大的东西落地"的到达/高潮 beat(payoff line、巨型回复、收尾定格),不要用于普通边界。总时长约 0.7s,按 30% 退场 / 70% 入场切分。
Registry gsap_template 版
tl.set(__NEW__, { opacity: 0 }, __T__);
tl.to(
__OLD__,
{ scale: 0.8, filter: "blur(10px)", duration: __DUR__ * 0.3, ease: "power3.in" },
__T__,
);
tl.to(__OLD__, { opacity: 0.15, duration: __DUR__ * 0.3, ease: "none" }, __T__);
tl.set(__OLD__, { opacity: 0 }, __T__ + __DUR__ * 0.3);
tl.fromTo(
__NEW__,
{ opacity: 0.15, scale: 1.25, filter: "blur(10px)" },
{
opacity: 1,
scale: 1,
filter: "blur(0px)",
duration: __DUR__ * 0.7,
ease: "expo.out",
immediateRender: false,
},
__T__ + __DUR__ * 0.3,
);
结构要点:
- 时间预算用
__DUR__ * 0.3/__DUR__ * 0.7表达 30/70 切分,退场(scale1 → 0.8)在前 30%,入场收缩(1.25 → 1,expo.out)占后 70%。 - 入场侧的
immediateRender: false很关键:fromTo的起始值(opacity: 0.15, scale: 1.25)不会在时间轴构建时就提前渲染,而是等到__T__ + __DUR__ * 0.3才生效。 - 同样有独立
ease: "none"的 opacity 线性 tween,与硬切tl.set(__OLD__, { opacity: 0 }, __T__ + __DUR__ * 0.3)衔接。
Worker 版:与 Zoom-Through 同构的三阶段(退场 → 硬切 → 入场),只是 scale 数值翻转——退场 1 → 0.8、切帧切入在 1.25、入场 1.25 → 1。
Z 方向符号纪律(来自 SKILL.md):Z 轴上"同轴"还不够,d(scale)/dt 的符号必须在切帧两侧一致:
| Z 向量 | 退场 scale | 入场 scale | 变体 |
|---|---|---|---|
| Push(前推) | 增长 1 → 1.2 |
增长 0.75 → 1 |
zoom-through |
| Pull(后拉) | 收缩 1 → 0.8 |
收缩 1.25 → 1 |
inverse zoom-through |
被禁止的镜像组合:后退的退场配"从小长出来"的入场(最常见的错误,因为 grow-from-small 是元素入场的默认写法),以及前推退场配超大收缩入场。这条符号纪律约束的是入场场景自己的内部入场动画(切帧 + 约 0.5s 的 seam 窗口内),而不只是 wrapper tween——入场画面要么以"已构图"状态到达,要么其入场动画与 Z 符号匹配。
3. Cut the Curve(默认场景边界)
这是所有场景到场景边界的默认切法:出场 hero 朝一个方向加速,切帧落在运动中段,入场 hero 沿同一方向继续并减速。总时长约 0.6s;方向取 LEFT / RIGHT / UP / DOWN(默认 LEFT)。核心是部分行程:约 12% 画幅(1920 宽下约 230px),绝不做整屏移出。
Worker 版(场景层)
var CUT_TIME = /* scene transition point */;
// Scene A: hero accelerates leftward (partial travel ~12% of frame)
tl.to(".scene-a-layer", { opacity: 0, duration: 0.33, ease: "power2.in" }, CUT_TIME - 0.33);
tl.to(".hero-a-wrapper", {
x: -230, filter: "blur(8px)",
duration: 0.33, ease: "power4.in", // mirrored half of power4.inOut
overwrite: "auto"
}, CUT_TIME - 0.33);
// Hard cut
tl.set(".scene-b-layer", { opacity: 1 }, CUT_TIME);
tl.set(".hero-b-wrapper", { x: 230, filter: "blur(8px)" }, CUT_TIME);
// Scene B: hero decelerates leftward
tl.to(".hero-b-wrapper", {
x: 0, filter: "blur(0px)",
duration: 0.33, ease: "power4.out" // matched velocity at the cut
}, CUT_TIME);
原理是镜像缓动:退场 power4.in + 入场 power4.out,同样的距离与时长——它们正是同一个 power4.inOut 的前后半段,因此切帧处速度精确相等。四方向的行程表:
| 方向 | 退场 | 入场 起点 → 终点 |
|---|---|---|
| 向左 | x: 0 → −230 |
x: +230 → 0 |
| 向右 | x: 0 → +230 |
x: −230 → 0 |
| 向上 | y: 0 → −230 |
y: +230 → 0 |
| 向下 | y: 0 → +230 |
y: −230 → 0 |
Registry gsap_template 版
__DX__ = -1920(LEFT)/ 1920(RIGHT);__DY__ = -1080(UP)/ 1080(DOWN)。* 0.12 / * 0.21 系数产出约 12% 的部分行程(垂直方向 1080 × 0.21 ≈ 227px,与水平 230px 对齐)。
// horizontal
tl.set(__NEW__, { opacity: 0 }, __T__);
tl.to(__OLD__, { x: __DX__ * 0.12, duration: __DUR__ * 0.5, ease: "power4.in" }, __T__);
tl.to(__OLD__, { opacity: 0, duration: __DUR__ * 0.47, ease: "power2.in" }, __T__ + __DUR__ * 0.03);
tl.fromTo(
__NEW__,
{ x: __DXIN__ * 0.12, opacity: 0.35 },
{ x: 0, opacity: 1, duration: __DUR__ * 0.5, ease: "power4.out", immediateRender: false },
__T__ + __DUR__ * 0.5,
);
// vertical
tl.set(__NEW__, { opacity: 0 }, __T__);
tl.to(__OLD__, { y: __DY__ * 0.21, duration: __DUR__ * 0.5, ease: "power4.in" }, __T__);
tl.to(__OLD__, { opacity: 0, duration: __DUR__ * 0.47, ease: "power2.in" }, __T__ + __DUR__ * 0.03);
tl.fromTo(
__NEW__,
{ y: __DYIN__ * 0.21, opacity: 0.35 },
{ y: 0, opacity: 1, duration: __DUR__ * 0.5, ease: "power4.out", immediateRender: false },
__T__ + __DUR__ * 0.5,
);
registry 版与 worker 版的结构差异在于"淡出技巧"的时间化:退场透明度从 __T__ + __DUR__ * 0.03 开始、历时 __DUR__ * 0.47,即约在行程的 25–30% 处完成(对应 SKILL.md 规则"fade ≈ 0.18–0.3s vs motion 0.3–0.34s");入场侧从 opacity: 0.35 在中途"点燃"(mid-path ignition),而不是二进制的 0→1 跳变——二进制的 0→1 会闪。
两个工程性细节(均出自 SKILL.md 与 seam-craft):
- 舞台地必须不透明:
#root需要background: var(--canvas-deep, var(--canvas, #000))。cut-the-curve 的"中段窗口"会打开一个两侧透明度之和 < 1 的窗口,若#root无底色,渲染器会把透明凹陷合成到默认白色页面之上——深色影片上每个切点都会白闪。 - 同 track 的 wrapper 重叠是非法的(
core/src/lint/rules/composition.ts校验),所以注入器要做 0/1 track 乒乓重排;filter属性在主时间轴上是 lint-clean 的(core/src/lint/rules/gsap.ts的属性白名单只约束场景 worker,不约束 index.html)。
组合版:cut-the-curve + zoom
横向切割上叠加一个温和的 Z 分量。scale 分量同样服从 Z 符号规则:两侧都收缩(退场 1 → 0.92,入场 1.08 → 1)——一致的温和"拉"叠在横向切割上;不要在这里把收缩退场配从小生长入场。
// Scene A: hero slides left + mild pull + blur
tl.to(
".hero-a-wrapper",
{
x: -230,
scale: 0.92,
filter: "blur(8px)",
duration: 0.33,
ease: "power4.in",
},
CUT_TIME - 0.33,
);
// Cut + Scene B: continues leftward, arrives slightly oversized and retracts
tl.set(".hero-b-wrapper", { x: 230, scale: 1.08, filter: "blur(8px)" }, CUT_TIME);
tl.to(
".hero-b-wrapper",
{
x: 0,
scale: 1,
filter: "blur(0px)",
duration: 0.42,
ease: "power4.out",
},
CUT_TIME,
);
4. Waterfall Cut(逐词瀑布切割)
Cut the Curve 的词级(word-level)版本,是文本到文本 seam 最强的左向切法:出场词在各自的曲线上逐词退出,入场词在飞行中途级联点燃——一道眼睛可以沿 seam 骑过去的波。
作用域:worker 在单个多 beat 合成内手写(叠放的全帧 .beat 层),不是 registry/injector 类型——它 tween 的是词 span 而非 clip wrapper。进出文本 beat 块的边界仍然使用普通 registry 转场,且不计入 2–3 个转场的预算。
DOM + CSS
<div class="beat" id="b1"><div class="line">And until now</div></div>
<div class="beat" id="b2">
<div class="line">
<span class="w">that</span> <span class="w">changes</span> <span class="w">today.</span>
</div>
</div>
.beat {
position: absolute;
inset: 0;
display: grid;
place-items: center;
will-change: transform, opacity;
}
.w {
display: inline-block;
will-change: transform, opacity;
}
时间轴
// Pre-set at build time — immediateRender:false alone leaves un-started words visible.
gsap.set([...w1, ...w2], { x: 230, opacity: 0 });
function wordExit(words, C) {
// C = cut time on the comp timeline
let s = C - 0.32; // exits START before the cut
words.forEach((el) => {
tl.to(el, { x: -230, duration: 0.34, ease: "power4.in" }, s);
tl.to(el, { opacity: 0, duration: 0.18, ease: "power1.in" }, s); // fade ends ~25-30% into travel
s += 0.022; // reading-order stagger
});
}
function wordEnter(words, C) {
let off = 0,
gap = 0.05;
words.forEach((el) => {
tl.fromTo(
el,
{ x: 230, opacity: 0.35 }, // ignites MID-PATH, already moving
{ x: 0, opacity: 1, duration: 0.3, ease: "power4.out", immediateRender: false },
C + off,
);
off += gap;
gap *= 0.84; // shrinking gaps — the cascade accelerates
});
}
const C = 2.3;
wordExit(w1, C);
tl.set(b1, { opacity: 0 }, C); // hard layer swap AT the cut
tl.set(b2, { opacity: 1 }, C);
wordEnter(w2, C);
关键机制:
- 构建期预置:所有词在构建时
gsap.set到x: 230, opacity: 0。只靠immediateRender: false会让未启动的词静止可见。 - 退场先于切帧开始(
C - 0.32),逐词 stagger+0.022s按阅读顺序——行是"剥落"而不是整块滑动;每个词的 fade 在行程 25–30% 处结束,词在到达切帧前已消失,不留拖影。 - 入场中途点燃:从
opacity: 0.35起、x: 230处已经在运动中;间隔以×0.84逐词衰减,级联自我加速,最终收敛到构图态。 - 切帧处硬层交换:
tl.set(b1, {opacity:0}, C)与tl.set(b2, {opacity:1}, C)精确落在切帧。 - 短的首 beat 可以整行退出:作为单一元素
x: -230, 0.34s, power4.in,opacity fade 几乎贯穿整个行程(在切帧前约 0.02s 结束)——下一波词点燃时它还在飞,没有死档。 - 只动 transform/opacity(seek-safe),不透明舞台地规则同样适用。
参数速查(SKILL.md 表格):行程 ±230px(约 12% 画幅);退场 0.34s power4.in;退场 fade 0.18s 与 x 同时开始;退场 stagger 按阅读顺序 +0.022s;入场 0.3s power4.out;入场起始 opacity 0.35(中途点燃,二进 0→1 会闪);入场间隔 0.05s × 0.84 衰减(加速级联)。
5. Rack-Focus Blur-Cut(可见的切)
唯一"让切被看见"的变体:失焦模糊尖峰隐藏单帧硬交换,模拟手持 DSLR 跟焦。用于同一视觉主题内同一表面(same surface)的状态切换,作为偶发的花招(每约 8s 至多一次);永远不是默认边界。与其他变体的区别:出场侧保持完全不透明直到切帧(靠模糊隐藏交换,不做提前 fade),缓动用 power2.in / power2.out(柔和光学感,而非动量感)。
var T = /* transition start */;
// Phase 1: outgoing pans + blurs, held fully opaque
tl.to("#scene-out", { x: -80, scale: 1.06, filter: "blur(12px)", duration: 0.3, ease: "power2.in" }, T);
// Phase 2: hard cut at peak blur
tl.set("#scene-out", { opacity: 0 }, T + 0.3);
tl.fromTo("#scene-in",
{ opacity: 1, x: 80, scale: 1.06, filter: "blur(12px)" },
{ x: 0, scale: 1, filter: "blur(0px)", duration: 0.35, ease: "power2.out" },
T + 0.3);
规则要点:
- 切帧必须落在峰值模糊(≥6px;峰值 8–12px,最大 ≤16–18px)——在模糊上升途中交换会露出切。
- 约 1.06 的微妙 scale("镜头呼吸感")让它读作光学现象。
- 两侧同方向——矢量定律仍然成立;入场时长 ≥ 退场时长。
- 模糊打在 wrapper 上;同一元素不要在一个 tween 里同时 blur + opacity(headless 合成 bug);不要直接 blur
<video>(要包一层)。 - 若做 Z dolly 变体,去掉 x 偏移,改用 scale
0.92 →/→ 1.08。
调参范围(Tuning ranges)
Zoom-Through / Inverse Zoom
| 参数 | 默认值 | 取值范围 |
|---|---|---|
| 退场 scale | 1.2(前向)/ 0.8(反向) | ±0.1 |
| 入场 scale | 0.75(前向)/ 1.25(反向) | ±0.1 |
| 切帧处模糊 | 文字 10px / 整帧 18–20px | — |
| 切帧处透明度 | 0.15 | 0.1–0.2 |
| 退场时长 | 0.2s | 0.15–0.3s |
| 入场时长 | 0.5s | 0.4–0.6s |
Cut the Curve
| 参数 | 默认值 | 取值范围 |
|---|---|---|
| 行程 | 230px(约 12% 画幅) | 150–300px |
| 切帧处模糊 | 8px | 6–10px |
| 退场时长 | 0.33s | 0.2–0.4s |
| 入场时长 | 0.33–0.42s | ≥ 退场 |
模糊量的依据(SKILL.md 的 Blur logic 表):文字级主体(标题、词组)峰值 10px——20px 会让字形糊成一片,切帧读起来像 glitch 而不是速度;整帧表面(窗口、卡片、截图)峰值 18–20px——大表面上过轻的模糊会读成渲染卡顿。交换帧上两侧取相同峰值模糊。
6. Waterfall Entry(场景内到达,非 seam)
逐元素"闪现 + 冲刺归位"的级联:每个元素先 tl.set(瞬时显现 + 偏移)再 tl.to(鞭打到静止)。排布公式:nextStart = prevStart + prevDuration − (overlapFrames × F);正 overlap 级联,负 overlap 刻意留空。CSS 上元素从 opacity: 0; display: inline-block 开始。用于标题卡、段落开场、列表/特性介绍,方向默认 Y(从下方来)。
var F = 1 / 60;
var t0 = 0.1;
// anchor (heaviest): biggest travel, longest settle
tl.set("#el-1", { opacity: 1, y: 80 }, t0);
tl.to("#el-1", { y: 0, duration: 0.18, ease: "power4.out" }, t0);
// normal word: 2 frames after the anchor finishes
var t1 = t0 + 0.18 + 2 * F;
tl.set("#el-2", { opacity: 1, y: 45 }, t1);
tl.to("#el-2", { y: 0, duration: 0.15, ease: "power4.out" }, t1);
// light word: 1 frame BEFORE the previous finishes (overlap)
var t3_placeholder = 0; // (illustrative)
var t2 = t1 + 0.15 - F;
tl.set("#el-3", { opacity: 1, y: 40 }, t2);
tl.to("#el-3", { y: 0, duration: 0.14, ease: "power4.out" }, t2);
// split final-word fragments: tightest overlap, extra travel (lighter)
var t3 = t2 + 0.14 - F;
tl.set("#frag-a", { opacity: 1, y: 70 }, t3);
tl.to("#frag-a", { y: 0, duration: 0.16, ease: "power4.out" }, t3);
var t4 = t3 + 0.14 - F;
tl.set("#frag-b", { opacity: 1, y: 70 }, t4);
tl.to("#frag-b", { y: 0, duration: 0.15, ease: "power4.out" }, t4);
// punctuation: lightest, fastest
var t5 = t4 + 0.13 - 2 * F;
tl.set("#dot", { opacity: 1, y: 48 }, t5);
tl.to("#dot", { y: 0, duration: 0.12, ease: "power4.out" }, t5);
(注:上面 var t3_placeholder 一行是排版占位,实际模板中不存在该行;原模板直接从 t2 推到 t3。)
编排规则(SKILL.md 表格):
| 参数 | 锚点/重元素 | 普通词 | 轻元素/标点 |
|---|---|---|---|
| Y 偏移 | 60–80px | 40–50px | 30–48px |
| 时长 | 0.16–0.20s | 0.13–0.16s | 0.10–0.13s |
| Overlap | 0–2 帧留空 | 1 帧重叠 | 1–2 帧重叠 |
- 重叠而非排队:下一元素在前一个落定的 ±2 帧内启动;间隔沿级联收缩;最后元素"啪"地落定。
- 速度按重量分级:重/锚点元素行程更远、时长更长;轻词与标点快速闪现。
- 缓动统一
power4.out(要更强 snap 用expo.out);入场永远不要.inOut。 - 每条级联一个方向;把最后一个词拆成碎片以延长高潮,碎片行程更远。
- 与 §4 Waterfall Cut 的边界:§6 Entry 的 opacity 是
tl.set二进 0→1(绝不 fade——seam 切才 fade,arrival 不 fade);§4 则在 0.35 处中途点燃。 - 落定后整组通常会再滑开给下一个 beat 让位——那就是 §7 Nudge Curve。
7. Nudge Curve(场景内群组滑动,非 seam)
已构图群组(词行、卡片堆、列表)的"慢-快-慢"重定位,用于揭示内容或腾出空间。没有单一内置缓动能产出它——power4.inOut 会"啪"地刹停。在同一个属性上串联三个 tween:
| 阶段 | 缓动 | 距离占比 | 时间占比 | 感受 |
|---|---|---|---|---|
| 1 ramp-in | power3.in |
~10% | ~20% | 几乎不动——运动被感知但没有冲击 |
| 2 burst | none(线性) |
~65% | ~18% | 约 2 倍平均 px/帧——目的明确 |
| 3 tail | power4.out |
~25% | ~62% | 衰减蠕变到静止——消掉"啪"的刹车感 |
参考值:270px 左向滑动(总时长 0.57s)。其他行程按比例缩放距离,保持时间比;tail 时间 ≥ 3× ramp-in。
var t = /* start after content settles */;
tl.to(".text-row", { x: -30, duration: 0.12, ease: "power3.in" }, t); // ramp-in: 11% dist / 21% time
tl.to(".text-row", { x: -210, duration: 0.10, ease: "none" }, t + 0.12); // burst: 67% dist / 18% time
tl.to(".text-row", { x: -270, duration: 0.35, ease: "power4.out" }, t + 0.22); // tail: 22% dist / 61% time
// vertical: same ratios on y. 150px variant: -15 / -115 / -150 at the same times.
规则:
- 若仍然"啪"地刹车:延长 tail 的时间(不是距离),或改用
power5.out。 - Phase 2 保持线性——给它加缓动会失去 burst 的对比。
- 在 phase 2 期间揭示新内容——burst 会掩盖其出现。
- 垂直方向同理;距离按比例缩放,时间比不变(150px 变体:同一时间点
-15 / -115 / -150)。
变体选择速查与工程验证
四/五种 seam 变体的选择矩阵(SKILL.md):
| Zoom-Through | Inverse Zoom | Cut the Curve | Waterfall Cut | |
|---|---|---|---|---|
| 作用域 | 场景内文本交换 | 到达/高潮 beat | 场景之间 | 文本到文本 seam |
| Z 符号/轴 | 增长(push) | 收缩(pull) | X / Y | X,逐词 |
| 行程/scale | 1→1.2,然后 0.75→1 | 1→0.8,然后 1.25→1 | ±230px | ±230px |
| 峰值模糊 | 文字 10px / 整帧 18–20px | 同左 | 8–10px 可选 | 无 |
| 缓动 | power3.in / expo.out | power3.in / expo.out | power4.in / power4.out | power4.in / power4.out |
| 感受 | 向前推进 | 抵达 | 被侧向带走 | 一道骑过 seam 的波 |
工程侧验证链:这些模板不是"凭感觉对",仓库配套了机器验证。motion-doctrine 技能 提供 seam-stamp.mjs + seam-gate.mjs 生成-校验对:项目根目录的 ledger.json 按行记录每个 seam 的 cut 时间、technique、exit/entry 的 axis 与 dir(z +1 = push,z −1 = pull);seam-gate.mjs verify 会用无头 Chrome 逐帧测量(基于 getBoundingClientRect,自动包含祖先 wrapper 变换),检查切帧两侧是否"一帧只见一侧"(zero-overlap)、实测速度是否匹配(speed-match)、入场场景内部入场是否对抗 Z 符号(z-sign-scan,对应 SKILL.md 的 Seam Gate rule 7)。probe 子命令可以在某切帧时刻附近发现 mover 元素,辅助填写 ledger。
此外,各生产型技能(如 product-launch-video、pr-to-video、faceless-explainer)各自 vendored 了一份 registry JSON,其中模板 token(__OLD__/__NEW__/__T__/__DUR__/__DX__/__DXIN__/__DY__/__DYIN__)与本文模板文档完全一致——registry 版的代码就是从这些模板注入的,而 worker 版的代码则由 worker 在单个 comp 内按参数表手写。更完整的转场总目录可参考 TRANSITION-REGISTRY。
适用前提与限制:本文所有模板面向 1920×1080 / 30fps 级别的 HyperFrames 合成(__DX__/__DY__ 的 1920/1080 常数、12% 行程与 230px 默认值均以此为基准);Tier-B 转场的前提是纯 transform/opacity/filter 作用于两个 clip wrapper,不注入 overlay DOM;filter 在主时间轴可用但在单元素上与 opacity 同 tween 存在 headless 合成 bug(rack-focus 规则);不同分辨率下应按比例换算行程常数而非照抄 230px。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00