MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / bindRootTimelineIfAvailable

Function bindRootTimelineIfAvailable

packages/core/src/runtime/init.ts:1138–1297  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

1136 let childrenBound = false;
1137 // fallow-ignore-next-line complexity
1138 const bindRootTimelineIfAvailable = (): boolean => {
1139 if (!externalCompositionsReady) return false;
1140 const currentTimeline = state.capturedTimeline;
1141 const currentDuration = getTimelineDurationSeconds(currentTimeline);
1142 const currentTimelineUsable = isUsableTimelineDuration(currentDuration);
1143 // Skip rebind ONLY if we already have a usable timeline AND children have been bound.
1144 // Without childrenBound check, the TARGET_DURATION spacer makes the timeline "usable"
1145 // before child composition timelines are added, causing them to never be discovered.
1146 if (currentTimeline && currentTimelineUsable && childrenBound) return false;
1147 const resolution = resolveRootTimelineFromDocument();
1148 if (!resolution.timeline) return false;
1149 if (currentTimeline && currentTimeline === resolution.timeline) {
1150 if (typeof currentTimeline.timeScale === "function") {
1151 currentTimeline.timeScale(state.playbackRate);
1152 }
1153 return false;
1154 }
1155 state.capturedTimeline = resolution.timeline;
1156 if (typeof state.capturedTimeline.timeScale === "function") {
1157 state.capturedTimeline.timeScale(state.playbackRate);
1158 }
1159 const boundDuration = getSafeTimelineDurationSeconds(state.capturedTimeline, 0);
1160 if (boundDuration <= 0) {
1161 // No resolvable duration (e.g. a set()-only timeline, or one whose
1162 // duration isn't known yet). Kick GSAP off the creation position so the
1163 // set() renders. For a finite-but-zero timeline progress(1) === progress(0);
1164 // for an infinite-repeat timeline this lands on the first iteration's end
1165 // frame, which is the best we can do without a known cycle length.
1166 if (typeof state.capturedTimeline.progress === "function") {
1167 state.capturedTimeline.progress(1, true);
1168 state.capturedTimeline.progress(0, false);
1169 state.capturedTimeline.pause();
1170 }
1171 }
1172 if (boundDuration > 0) {
1173 try {
1174 clock.setDuration(boundDuration);
1175 } catch {
1176 // clock not yet initialized — duration will be set during TransportClock setup
1177 }
1178
1179 if (typeof state.capturedTimeline.totalTime === "function") {
1180 // GSAP won't render tl.set() at position 0 when the paused timeline
1181 // starts there — play/pause/seek/totalTime are all no-ops at the
1182 // creation position. Force the set to render by cycling progress past
1183 // 0 (when the timeline implements it), then seek to the prior playhead
1184 // (state.currentTime) so a rebind after a user scrub or soft-reload
1185 // restore doesn't snap back to 0.
1186 if (typeof state.capturedTimeline.progress === "function") {
1187 state.capturedTimeline.progress(0.0001, true);
1188 }
1189 const seekTime = Math.max(0, state.currentTime || 0);
1190 state.capturedTimeline.totalTime(seekTime, false);
1191 state.capturedTimeline.pause();
1192 }
1193
1194 // GSAP bakes the CSS `translate` into style.transform on seek.
1195 // The Studio seek wrapper (installStudioManualEditSeekReapply) calls

Callers 5

postTimelineFunction · 0.85
transportTickFunction · 0.85

Calls 15

postRuntimeMessageFunction · 0.90
isUsableTimelineDurationFunction · 0.85
hasAuthoredTimedAncestorFunction · 0.85
timeScaleMethod · 0.80
setDurationMethod · 0.80
totalTimeMethod · 0.80
getChildrenMethod · 0.80

Tested by

no test coverage detected