mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-03 12:17:03 +00:00
* fix(core): motion blur preview no longer slows down later in the timeline With data-motion-blur-events="on", which Studio's Subtle and Strong write, both blur tiers ran timeline callbacks at every per-frame pose read. Each frame's reads step back from half a shutter ahead to the frame, so a callback that keeps state and replays from zero on a backward seek (a ripple simulation, for example) redid its whole history most frames, and the cost grew with the playhead. The mover scan still runs callbacks, so motion set from a render(t) callback is still found. With events on, it also scans once without them, and the per-frame reads run callbacks only when the two scans disagree. The eventful scan runs first, so tweens take their start values after the callbacks before them and a one-off call fires as often as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(core): keep the motion blur comments to the invariant Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(core): motion blur reads run callbacks when a callback moves any box Comparing which elements each scan finds missed a callback that pans a mover's ancestor while a tween also changes that ancestor: both scans found the same movers and the same changing elements, so the reads left the pan out. The scans now compare every changing element's box at each step, and the reads run callbacks when any step differs. Raises @hyperframes/core's unpacked size budget to the measured size plus the usual 5%: main already sat 0.98% over the old budget, and this change adds 1,232 bytes, which tipped it past the 1% tolerance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(core): silent motion blur reads land back on the frame as its own seek left it After silent pose reads, the restore seek back to the frame left GSAP in a different state than the frame's own eventful seek did: - A step exactly on the frame (a .call() or set) was re-armed, so the next frame fired it again. Calls fired 2-5 times per crossing, and a toggle could end inverted. - In renders, which keep no GSAP structure, landing back on the frame from later skipped same-time steps' authored order, so the frame showed the first of two sets instead of the last. Events-off blur always read silently and had both. This PR moves events-on roots without callback-driven motion (the Studio default) onto that path, so both are fixed here. The host's new holdFrame snapshots every landing mark on the root and scene timelines before the reads, and its restore seeks back silently, redraws in authored order where there is no structure, and puts the marks back. Each call now fires once per frame crossing, as without blur, and same-time sets land as authored. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(core): a held render frame draws its scenes first, so the root lands last holdFrame redrew the root and then the scenes, the reverse of the frame's own seek. When a scene and the root tween one property, the frame landed on the scene's value instead of the root's. The hold and landing move into the GSAP adapter as holdFrameMarks, which takes the scenes and the root separately, so the order lives in one place a real-GSAP test can pin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>