seam-craft

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Seam Craft — render prerequisites for scene-to-scene transitions

接缝处理——场景间过渡的渲染前提

This is the render-correctness doctrine for PLV scene-to-scene seams: the prerequisites and master-timeline mechanics that make any transition composite correctly, independent of which specific transition is chosen. The per-transition catalog (crossfade, push-slide, zoom-through, cut-the-curve, …) lives in the transition registry — this page is the doctrine that sits underneath all of them.
The transitions this doctrine governs are Tier-B-ready: pure transform / opacity / filter on the two scene clip wrappers (
#el-<sid>
), no injected overlay DOM, no per-scene cooperation. Overlay families (staggered blocks, blinds, light leak, grid dissolve, page burn) and shader transitions are deferred to later phases.
本文档是PLV场景间接缝的渲染正确性原则:无论选择哪种特定过渡,确保所有过渡能正确合成的前提条件和主时间轴机制。单个过渡的目录(交叉淡入淡出、推滑、缩放穿越、曲线切割……)存放在过渡注册表中——本文档是所有过渡的底层原则。
本原则管控的过渡为Tier-B就绪:仅对两个场景的剪辑包装器
#el-<sid>
)进行纯变换/透明度/滤镜操作,无注入的覆盖层DOM,无需每个场景配合。覆盖层系列(交错块、百叶窗、漏光、网格溶解、页面灼烧)和着色器过渡将推迟到后续阶段处理。

Stage ground prerequisite (white-flash guard)

舞台背景前提(白闪防护)

Several templates open a window where the two wrappers' summed opacity < 1 (the cut-the-curve mid-window cut, zoom-through's 0.15 floor, plain crossfade's power-curve dip). Whatever is BEHIND the wrappers shows through during that window. If the assembled
index.html
#root
has no opaque background, the renderer composites the dip over its default white page → a white flash at every seam, glaring on dark films (observed on two Spotify runs before the fix). The assembler must paint the stage:
#root { background: var(--canvas-deep, var(--canvas, #000)) }
assemble-index.mjs
now emits this; any other consumer of these templates owns the same guarantee.
部分模板会出现两个包装器的总透明度小于1的时段(曲线切割的中间窗口、缩放穿越的0.15下限、普通交叉淡入淡出的幂曲线下降)。此时包装器后方的内容会透显出来。如果组装后的
index.html
#root
没有不透明背景,渲染器会将透明度下降的部分与默认的白色页面合成→每个接缝处都会出现白闪,在深色影片中尤为刺眼(修复前在两次Spotify运行中观察到此问题)。组装器必须为舞台上色
#root { background: var(--canvas-deep, var(--canvas, #000)) }
——
assemble-index.mjs
现在会生成这段代码;使用这些模板的其他任何使用者都需保证这一点。

How the injector applies a transition

注入器如何应用过渡

At a
break
boundary between scene i (
from
) and scene i+1 (
to
), the injector:
  1. Extends
    #el-<from>
    wrapper
    data-duration
    by
    duration_s
    (holds its final frame — verified:
    core/src/runtime/init.ts:1393-1410
    external-slot branch).
  2. Pulls
    #el-<to>
    wrapper
    data-start
    earlier by
    duration_s
    (creates the overlap window).
  3. Reassigns all clip
    data-track-index
    as a 0/1 ping-pong so the two overlapping wrappers never share a track (same-track overlap is illegal —
    core/src/lint/rules/composition.ts
    ). Higher track composites on top.
  4. Stamps the
    gsap_template
    into
    window.__timelines["main"]
    at
    T = overlap-start
    .
Verified by prototype render (2026-05-31): the master-timeline wrapper tween is seeked and rendered (no double-seek with the sub-comp's own paused timeline — the runtime drives them independently), the extended wrapper holds scene i's final frame, and the higher-track incoming wrapper composites over + blends with the outgoing one.
在场景_i_(来源场景)和场景_i+1_(目标场景)的
break
边界处,注入器会执行以下操作:
  1. #el-<from>
    包装器的
    data-duration
    延长
    duration_s
    (保留其最终帧——已验证:
    core/src/runtime/init.ts:1393-1410
    外部插槽分支)。
  2. #el-<to>
    包装器的
    data-start
    提前
    duration_s
    (创建重叠时段)。
  3. 将所有剪辑的
    data-track-index
    重新分配为0/1乒乓切换,确保两个重叠的包装器永远不会共享同一轨道(同轨道重叠是违规的——
    core/src/lint/rules/composition.ts
    )。轨道层级越高,合成时越靠上。
  4. 在主时间轴的
    T = overlap-start
    位置,将
    gsap_template
    标记到
    window.__timelines["main"]
    中。
2026-05-31的原型渲染已验证:主时间轴包装器补间可被查找并渲染(不会与子合成的暂停时间轴双重查找——运行时独立驱动它们),延长后的包装器保留场景_i_的最终帧,层级更高的 incoming包装器会在 outgoing包装器上方合成并混合。

Template placeholders

模板占位符

The injector substitutes these tokens in each
gsap_template
line:
TokenMeaning
__OLD__
"#el-<from>"
— outgoing clip wrapper selector (quoted)
__NEW__
"#el-<to>"
— incoming clip wrapper selector (quoted)
__T__
overlap-start time in seconds (master clock)
__DUR__
duration_s
for this boundary
__DX__
horizontal travel for directional types:
-1920
(LEFT) /
1920
(RIGHT)
__DY__
vertical travel:
-1080
(UP) /
1080
(DOWN)
__ORIGIN_OUT__
/
__ORIGIN_IN__
transformOrigin pair for
squeeze
filter
/
scaleX
/
transformOrigin
are lint-clean on the master timeline (verified:
core/src/lint/rules/gsap.ts
has no per-property whitelist and scopes its checks to
data-composition-id
ranges; the x/y/scale/rotation/opacity whitelist is a scene-worker prompt rule only — it does not bind index.html).
注入器会在每个
gsap_template
行中替换以下标记:
标记含义
__OLD__
"#el-<from>"
— outgoing剪辑包装器选择器(带引号)
__NEW__
"#el-<to>"
— incoming剪辑包装器选择器(带引号)
__T__
重叠开始时间(秒,主时钟)
__DUR__
此边界的
duration_s
__DX__
方向型过渡的水平位移:
-1920
(左)/
1920
(右)
__DY__
垂直位移:
-1080
(上)/
1080
(下)
__ORIGIN_OUT__
/
__ORIGIN_IN__
squeeze
过渡的transformOrigin配对值
主时间轴上的
filter
/
scaleX
/
transformOrigin
均无Lint错误(已验证:
core/src/lint/rules/gsap.ts
没有按属性的白名单,其检查范围限定在
data-composition-id
区间;x/y/缩放/旋转/透明度白名单仅为_scene-worker_提示规则——不约束index.html)。