mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-01 03:06:54 +00:00
fix(core): exported scenes keep their frames when later scenes are added (#6035)
* fix(core): exported scenes keep their frames when later scenes are added * style(core): format the root length test and shorten its fix comment
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import gsap from "gsap";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { initSandboxRuntimeModular } from "./init";
|
||||
import type { RuntimeTimelineLike } from "./types";
|
||||
import { resetRuntimeFixtureDom } from "./runtimeSeekFixture.test-helpers";
|
||||
|
||||
// A render seek must draw each scene once, at its own time, however many scenes follow the playhead.
|
||||
describe("runtime root length across render seeks", () => {
|
||||
beforeEach(() => {
|
||||
resetRuntimeFixtureDom();
|
||||
window.gsap = gsap as unknown as typeof window.gsap;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
window.__hfRuntimeTeardown?.();
|
||||
delete window.__player;
|
||||
delete window.__playerReady;
|
||||
delete window.__hf;
|
||||
});
|
||||
|
||||
/** `sceneCount` five-second scenes back to back; returns the local times scene 1 is drawn at. */
|
||||
function load(sceneCount: number) {
|
||||
const hosts = Array.from(
|
||||
{ length: sceneCount },
|
||||
(_, i) => `<div data-composition-id="s${i}" data-start="${i * 5}" data-duration="5"></div>`,
|
||||
).join("");
|
||||
document.body.innerHTML = `<div data-composition-id="main" data-start="0" data-duration="${sceneCount * 5}">${hosts}</div>`;
|
||||
const timelines: Record<string, RuntimeTimelineLike> = {
|
||||
main: gsap.timeline({ paused: true }) as unknown as RuntimeTimelineLike,
|
||||
};
|
||||
const drawnAt: number[] = [];
|
||||
for (let i = 0; i < sceneCount; i++) {
|
||||
const target = { v: 0, w: 0 };
|
||||
const scene = gsap
|
||||
.timeline({ paused: true })
|
||||
.to(target, { v: 1, duration: 5, ease: "none" }, 0)
|
||||
.to(target, { w: 1, duration: 1 }, 0)
|
||||
// Overwrites the tween above on its first render, which marks the root's length stale.
|
||||
.to(target, { w: 2, duration: 1, overwrite: "auto" }, 0);
|
||||
if (i === 1)
|
||||
scene.eventCallback("onUpdate", () => drawnAt.push(Number(scene.time().toFixed(4))));
|
||||
timelines[`s${i}`] = scene as unknown as RuntimeTimelineLike;
|
||||
}
|
||||
window.__timelines = timelines;
|
||||
initSandboxRuntimeModular();
|
||||
return drawnAt;
|
||||
}
|
||||
|
||||
function renderFrames(from: number, to: number) {
|
||||
for (let frame = from; frame <= to; frame++) window.__player?.renderSeek(frame / 30);
|
||||
}
|
||||
|
||||
it("draws a scene at its own time when no scene follows it", () => {
|
||||
const drawnAt = load(2);
|
||||
renderFrames(210, 214);
|
||||
expect(drawnAt).toEqual([2, 2.0333, 2.0667, 2.1, 2.1333]);
|
||||
});
|
||||
|
||||
it("draws a scene at its own time when a later scene first renders during the seek", () => {
|
||||
const drawnAt = load(3);
|
||||
renderFrames(210, 214);
|
||||
expect(drawnAt).toEqual([2, 2.0333, 2.0667, 2.1, 2.1333]);
|
||||
});
|
||||
});
|
||||
@@ -4638,6 +4638,14 @@ export function initSandboxRuntimeModular(): void {
|
||||
swallow("runtime.init.activateSiblings", err);
|
||||
}
|
||||
}
|
||||
if (rearmed.length === 0) return rearmed;
|
||||
// GSAP leaves paused scenes out of the root's length and play() keeps that stale length.
|
||||
try {
|
||||
masterTimeline.shiftChildren?.(0);
|
||||
masterTimeline.totalDuration?.();
|
||||
} catch (err) {
|
||||
swallow("runtime.init.remeasureRoot", err);
|
||||
}
|
||||
return rearmed;
|
||||
};
|
||||
|
||||
|
||||
@@ -317,6 +317,7 @@ export type RuntimeTimelineLike = {
|
||||
seek: (timeSeconds?: number, suppressEvents?: boolean) => unknown;
|
||||
totalTime?: (timeSeconds?: number, suppressEvents?: boolean) => unknown;
|
||||
totalDuration?: () => number;
|
||||
shiftChildren?: (amount: number) => unknown;
|
||||
progress?: (value?: number, suppressEvents?: boolean) => unknown;
|
||||
time: () => number;
|
||||
duration: () => number;
|
||||
|
||||
Reference in New Issue
Block a user