@@ -1724,40 +1724,39 @@ export function initSandboxRuntimeModular(): void {
17241724 }
17251725 } ;
17261726
1727- // Unpause all non-root timelines. Per GSAP semantics, paused(false) on a
1728- // child timeline that hasn't been reached by the parent's playhead is a
1729- // no-op — the child won't fire onStart/onUpdate until the parent seeks
1730- // past its insertion point. Per-frame visibility is gated by the engine.
1731- const activateNestedChildTimelines = ( masterTimeline : RuntimeTimelineLike ) => {
1727+ // Unpause all non-root timelines registered in window.__timelines (siblings
1728+ // in the registry, not GSAP child tweens). Matches the naming convention in
1729+ // player.ts:32 (forEachSiblingTimeline) and player.ts:89 (activateSiblingTimelines).
1730+ //
1731+ // Unlike the player's seek path which re-pauses siblings after seeking,
1732+ // render-seek is one-frame-at-a-time with no transport tick between frames,
1733+ // so the residual unpaused state is harmless — the next call re-activates
1734+ // idempotently.
1735+ const activateSiblingTimelines = ( masterTimeline : RuntimeTimelineLike ) => {
17321736 const timelines = ( window . __timelines ?? { } ) as Record < string , RuntimeTimelineLike | undefined > ;
17331737 for ( const tl of Object . values ( timelines ) ) {
17341738 if ( ! tl || tl === masterTimeline ) continue ;
17351739 try {
1736- const tlWithPaused = tl as RuntimeTimelineLike & {
1737- paused ?: ( value ?: boolean ) => unknown ;
1738- } ;
1739- if ( typeof tlWithPaused . paused === "function" ) {
1740- tlWithPaused . paused ( false ) ;
1741- }
1740+ tl . play ( ) ;
17421741 } catch ( err ) {
1743- swallow ( "runtime.init.activateNested " , err ) ;
1742+ swallow ( "runtime.init.activateSiblings " , err ) ;
17441743 }
17451744 }
17461745 } ;
17471746
1748- const seekTimelineAndAdapters = ( t : number , activateChildren = false ) => {
1747+ const seekTimelineAndAdapters = ( t : number , opts ?: { activateChildren ?: boolean } ) => {
17491748 const tl = state . capturedTimeline ;
17501749 if ( tl ) {
17511750 // When rendering frame-by-frame (activateChildren=true), ensure all
1752- // nested child timelines are unpaused before seeking the root. GSAP
1751+ // sibling timelines are unpaused before seeking the root. GSAP
17531752 // does not propagate totalTime() to children that are internally
17541753 // paused, which leaves sub-compositions at their initial CSS state
17551754 // (typically opacity:0). This mirrors the activateSiblingTimelines
17561755 // call in player.ts renderSeek and is critical for sub-compositions
17571756 // whose data-start is at or near 0 — they are added to the root
17581757 // while it is paused and may never receive an explicit play().
1759- if ( activateChildren ) {
1760- activateNestedChildTimelines ( tl ) ;
1758+ if ( opts ?. activateChildren ) {
1759+ activateSiblingTimelines ( tl ) ;
17611760 }
17621761 try {
17631762 if ( typeof tl . totalTime === "function" ) {
@@ -2033,7 +2032,7 @@ export function initSandboxRuntimeModular(): void {
20332032 state . currentTime = clock . now ( ) ;
20342033 state . isPlaying = false ;
20352034 state . mediaForceSyncNextTick = true ;
2036- seekTimelineAndAdapters ( state . currentTime , true ) ;
2035+ seekTimelineAndAdapters ( state . currentTime , { activateChildren : true } ) ;
20372036 syncMediaForCurrentState ( ) ;
20382037 postState ( true ) ;
20392038 } ;
0 commit comments