Scroll-driven · 1.7
Scroll-scrubbed frame sequence
A flipbook you thumb at your own speed.
Scroll position scrubs a pre-rendered image sequence frame by frame on a canvas, so a scene plays exactly as fast as you pull it.
4 knobs
How it actually works
This is the heaviest technique in the index, and the code is the easy half. The real problem is the asset pipeline: how many frames, at what quality, preloaded how, inside what memory ceiling. So this page puts a live counter on exactly that. Turn frame count and frame quality and watch the megabytes. Turn preload strategy and watch the per-frame cost in milliseconds. That trade is the feature.
Not by scrubbing a video element. That stutters, and iOS Safari has documented bugs. You extract the frames to a numbered set, decode them into ImageBitmaps held in memory, and drawImage the right one per scroll update inside rAF. Keeping the bitmaps pre-decoded is the whole trick: it makes the browser do less work per frame. scrollFraction = scrollTop / maxScrollTop, then frameIndex = floor(scrollFraction * frameCount). The canvas is fixed and the body carries several hundred vh of scroll distance.
The knobs, named
Frame count, scroll distance, preload strategy, frame quality. The HUD is the point: every knob here reports what it costs you in memory or in milliseconds, because that is the only honest way to teach this one.
| Knob | Source | What it teaches |
|---|---|---|
| Frame count | sourced | How many frames the sequence holds. Smoothness against weight, and the megabyte readout moves with it. |
| Scroll distance | sourced | Track height. Long distance over few frames is a slideshow; short distance over many frames skips most of them. |
| Preload strategy | sourced | Pre-decoded is the sourced trick: pay once at init, drawImage per frame. On demand pays per frame instead, and the HUD shows what that costs. |
| Frame quality | sourced | Bitmap resolution as a fraction of the canvas. This is the other half of the memory bill, and it is the one nobody budgets for. |
sourced means the source names this parameter. ours means the source names none and the knob is our design against the mechanism. No knob here is invented and passed off as sourced.
Evidence
VERIFIED (author)
Mechanism from a CSS-Tricks reconstruction, cited independently by awwwards.md and craft-web.md. Apple's own source is INFERRED: apple.com was never rendered, and the index states that gap rather than papering over it.
- Seen on
- apple.com product pages (AirPods Pro is the cited example) — attribution INFERRED, not confirmed.
- Dependencies
- vanilla canvas; GSAP ScrollTrigger commonly drives the index
- Difficulty
- hard — and not the code: the asset pipeline is the real problem
- Performance
- The heaviest technique in this index. Hundreds of real frames run to tens of megabytes, hostile on mobile data and to memory ceilings. The HUD on this page reports our own memory estimate live.
- Accessibility and the floor
- Breaks entirely without JS, so it needs a static fallback image (the end frame) and aria-hidden on the canvas, with the real content as text. Under reduced motion ours renders that end frame: the last frame is the one that carries the message.
Notes
Composability. Nothing composes with it. It wants a fixed canvas and all your memory. Give it its own section or do not use it.