Seam Craft — prerrequisitos de renderizado para transiciones entre escenas
Esta es la doctrina de corrección de renderizado para las transiciones entre escenas de PLV: los prerrequisitos y la mecánica de la línea de tiempo maestra que hacen que cualquier transición se componga correctamente, independientemente de la transición específica elegida. El catálogo por transición (fundido cruzado, deslizamiento empujando, zoom, corte-curvo, …) se encuentra en el registro de transiciones — esta página es la doctrina que subyace a todas ellas.
Las transiciones que esta doctrina rige están listas para Tier-B: transform / opacidad /
filter puros en los dos contenedores de clip de la escena (#el-<sid>), sin DOM overlay inyectado, sin
cooperación por escena. Las familias de overlay (bloques escalonados, persianas, fuga de luz, disolución
en cuadrícula, quema de página) y las transiciones shader se posponen a fases posteriores.
Prerrequisito del fondo de escena (guardia contra destello blanco)
Varias plantillas abren una ventana donde la opacidad sumada de los dos contenedores < 1 (el
corte a mitad de ventana de corte-curvo, el piso de 0.15 de zoom-through, el
valle de la curva de potencia del fundido cruzado simple). Lo que esté DETRÁS de los contenedores se ve
a través durante esa ventana. Si el index.html ensamblado #root no tiene un fondo opaco, el
renderizador compone el valle sobre su página blanca por defecto → un destello blanco en
cada unión, que resalta en películas oscuras (observado en dos ejecuciones de Spotify antes de la corrección).
El ensamblador debe pintar el escenario: #root { background: var(--canvas-deep, var(--canvas, #000)) } — assemble-index.mjs ahora emite esto;
cualquier otro consumidor de estas plantillas asume la misma garantía.
Cómo el inyector aplica una transición
En un límite de break entre la escena i (from) y la escena i+1 (to), el
inyector:
- Extiende
#el-<from>contenedordata-durationenduration_s(mantiene su fotograma final — verificado:core/src/runtime/init.ts:1393-1410rama de slot externo). - Adelanta
#el-<to>contenedordata-startenduration_s(crea la ventana de superposición). - Reasigna todos los clips
data-track-indexcomo un ping-pong 0/1 para que los dos contenedores superpuestos nunca compartan una pista (la superposición en la misma pista no está permitida —core/src/lint/rules/composition.ts). La pista más alta se compone encima. - Coloca la
gsap_templateenwindow.__timelines["main"]enT = overlap-start.
Verificado por render de prototipo (2026-05-31): el tween del contenedor de la línea de tiempo maestra se busca y renderiza (sin doble búsqueda con la línea de tiempo pausada del sub-comp — el runtime los maneja de forma independiente), el contenedor extendido mantiene el fotograma final de la escena i, y el contenedor entrante de pista más alta se compone encima + se mezcla con el saliente.
Placeholders de plantilla
El inyector sustituye estos tokens en cada línea de gsap_template:
| Token | Significado |
|---|---|
__OLD__ | "#el-<from>" — selector del contenedor de clip saliente (entre comillas) |
__NEW__ | "#el-<to>" — selector del contenedor de clip entrante (entre comillas) |
__T__ | tiempo de inicio de superposición en segundos (reloj maestro) |
__DUR__ | duration_s para este límite |
__DX__ | desplazamiento horizontal para tipos direccionales: -1920 (IZQUIERDA) / 1920 (DERECHA) |
__DY__ | desplazamiento vertical: -1080 (ARRIBA) / 1080 (ABAJO) |
__ORIGIN_OUT__ / __ORIGIN_IN__ | par de transformOrigin para squeeze |
filter / scaleX / transformOrigin están limpios de lint en la línea de tiempo maestra
(verificado: core/src/lint/rules/gsap.ts no tiene lista blanca por propiedad y limita
sus comprobaciones a rangos de data-composition-id; la lista blanca de x/y/scale/rotation/opacity
es solo una regla de prompt del scene-worker — no vincula index.html).