mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-04 04:46:59 +00:00
* perf(studio): long clips mount only the picture tiles in view A clip's picture strip mounted one tile per frame width, so a 10-minute clip at full zoom mounted 18,000 tiles. The strip-size hook now also reports the strip's on-screen span (refreshed on scroll, resize and clip moves), and the video, image and composition strips mount only the tiles inside it. * refactor(studio): read the strip span outside the state updater * fix(studio): a dragged long clip keeps its picture across the screen The strip refreshed its span only on scroll, resize or a style change on its own clip, but a drag moves the ghost through a wrapper, so a long clip's ghost went blank past about 600 px of drag. Each strip now marks its unmounted ends and re-measures when either nears the screen, whatever moved it, and commits before paint. The tile row is one shared ThumbnailTiles for the video, image and composition strips. * fix(studio): warn of a tile gap inside the timeline scroller too * fix(studio): clip strips re-measure together, one layout per frame With row virtualization off the timeline mounts every clip, and each strip had its own scroll listener and frame that read layout and then committed. A scroll jump changed every strip's span, so a 1,000-clip timeline laid out about once per clip per frame (the viewport gate's 1,000-row arm went to ~3 s frames). All strips now share one scroll listener, observers and frame: every position is read first, then every update commits in one batch. * perf(studio): a scroll re-renders only the clip strips crossing the screen edge A strip's span is clamped to its own measured width, and each strip keeps its current size outside React so an unchanged size never calls setState. A clip wholly on or wholly off screen then does no work on a scroll; only strips straddling the edge re-render. * perf(studio): a scroll re-measures only clip strips near the screen The shared frame read every mounted strip's position, so a timeline of 1,000 unvirtualized clips forced about 1,000 style-and-layout passes per scroll frame. An IntersectionObserver now tracks which strips are within 256 px of the screen; a scroll re-measures only those, and a strip is measured as it comes near. A clip wholly off screen mounts no tile. * test(studio): share the strip test setup through the root harness * test(studio): a strip is measured as it comes near the screen * fix(studio): a scroll jump measures the clips it brings on screen in the same frame Each frame moves every strip's last measured box by its scroller's offset change and reads only the boxes that land within 256 px of the screen. A jump therefore measures exactly the strips it brings into view, with no blank frame, at the cost of a short scroll; strips far away get their span from the moved box without a layout read. * perf(studio): a strip off either side of the screen keeps one empty span * perf(studio): a clip strip far above or below the screen mounts no tiles * perf(studio): a scroll frame leaves off-screen clip strips untouched * perf(studio): short clips keep every tile and do no work on a scroll A strip up to 4,096 px wide keeps all its tiles, as before this change, and a scroll frame skips it; only long clips mount the tiles in view. Short clips gain nothing from virtualizing and paid a re-render each time they crossed the screen's edge. * fix(studio): a scroll is never applied twice to a clip strip's position Each strip remembers the scroll offset its box was read at, so a strip read between a scroll and that scroll's frame is not shifted again. The empty-span guards are removed: a near strip always starts inside itself and a far one already gets nothing. * fix(studio): a clip on screen keeps its pictures after a move and a scroll A strip showing tiles is re-read on every scroll frame instead of trusting its last box shifted by the scroll, which a move without a scroll (rows removed above it, a dock resize) leaves stale. Tests now pin the vertical shift, the 256 px band, the 4,096 px short-clip limit and the tile padding.