fix(sim): double-buffer video so morph->loop handoff doesn't stall
Operator eyeball: a jolt/pause when the morph ends and the next altitude's loop loads. Root cause: swapping vid.src to the base + seeking to the tail reloaded the ON-SCREEN element (decode + seek stall). Now a dedicated #vid-loop element carries the steady-state base loop; during a scrub it is PRELOADED to the clip we're heading toward, seeked to the tail and paused on that exact frame. The paint shader reads the active source (busy ? morph : loop), so landing is an instant source swap — no reload, no seek. E2E asserts the loop element is armed + playing from ~3s after landing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -93,19 +93,20 @@ test("a landed clip loops from the morph-tail offset (no jump-back to frame 0)",
|
||||
const start = (await page.locator("#scale-name").textContent())!;
|
||||
await wheelOnStage(page, 60);
|
||||
await page.waitForFunction((s) => document.querySelector("#scale-name")?.textContent !== s, start, { timeout: 20000 });
|
||||
// After landing, the base loop is armed (loopTail="1") and seeked to the tail
|
||||
// (~3s) so it continues the morph's last frame instead of restarting at 0.
|
||||
// After landing, the dedicated loop element (#vid-loop) is armed (loopTail="1") and
|
||||
// playing from the tail (~3s) — preloaded during the scrub, so the landing was a
|
||||
// source swap, not a reload that restarts at 0.
|
||||
await page.waitForFunction(
|
||||
() => { const v = document.querySelector("video") as HTMLVideoElement; return v.dataset.loopTail === "1" && v.currentTime >= 2.5; },
|
||||
() => { const v = document.querySelector("#vid-loop") as HTMLVideoElement; return v.dataset.loopTail === "1" && v.currentTime >= 2.5; },
|
||||
null,
|
||||
{ timeout: 10000 },
|
||||
);
|
||||
const v = await page.evaluate(() => {
|
||||
const el = document.querySelector("video") as HTMLVideoElement;
|
||||
return { t: el.currentTime, loopTail: el.dataset.loopTail, morph: el.dataset.morph || "" };
|
||||
const el = document.querySelector("#vid-loop") as HTMLVideoElement;
|
||||
return { t: el.currentTime, loopTail: el.dataset.loopTail, paused: el.paused };
|
||||
});
|
||||
expect(v.morph).toBe(""); // on the base loop, not a morph
|
||||
expect(v.loopTail).toBe("1"); // tail-loop armed
|
||||
expect(v.paused).toBe(false); // the loop is actually playing
|
||||
expect(v.t).toBeGreaterThanOrEqual(2.5); // looping from ~3s, not 0
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user