Cinematic Scroll Experience
Porsche 911 Carrera S
A scroll-driven concept site for the Porsche 911 Carrera S, where scrolling plays 4K driving footage frame-by-frame over a custom canvas engine that stays smooth and memory-safe on any device.
targetProblem Statement
Automotive landing pages that scrub footage on scroll lean on the <video> element, which seeks to the nearest keyframe and stutters under scroll input. The naive fix, decoding the whole frame sequence up front, costs roughly 475 MB of memory and freezes weaker devices, forcing a choice between cinematic fidelity and basic usability.
boltReal-world Impact
Delivered a concept site held to an Awwwards bar where the entire page behaves like one continuous film: scroll plays the footage frame-by-frame, headlines resolve in sequence, and a wheel rolls in to reveal the closing call to action. Windowed decoding cut peak memory from ~475 MB to roughly 120 MB, and a full accessibility layer keeps the cinematics from costing usability. Independent concept study, not affiliated with Porsche.
account_treeSystem Architecture
Next.js 16 App Router shell driving a single scroll timeline. The 4K clip is extracted offline into a numbered frame sequence; Lenis feeds normalized scroll progress into a Zustand store, and a windowed decoder keeps only frames within ±24 of that position decoded via createImageBitmap, explicitly releasing bitmaps as the window moves. A dedicated requestAnimationFrame loop paints the active frame to canvas so drawing never blocks the scroll thread, while a directional prefetch warms the cache ahead of travel. Motion drives the typographic and CTA choreography layered above the canvas.
┌──────────────────────────────────────────────┐
│ 911 — SCROLL-DRIVEN FILM ENGINE │
└──────────────────────────────────────────────┘
[4K Clip] ──(ffmpeg extract + compress)──► [Frames]
│
[Lenis Scroll] ──► [Progress 0..1] │
│ │
▼ ▼
[Windowed Decoder] ◄── (prefetch ahead)
(keep ±24 frames via createImageBitmap)
│
(bitmap.close() outside window)
│
▼
[Canvas Painter — own rAF loop]
│
┌─────────────────┴─────────────────┐
│ │
[Magnetic Beat Snap] [prefers-reduced-motion]
(settle on story beats) (static frame path)memoryAI / System Intelligence
No runtime inference. The intelligence sits in the asset pipeline. Hero footage was generated in Higgsfield, extracted and compressed into a frame sequence with ffmpeg, and product shots isolated with rembg background removal, letting a solo build ship broadcast-grade automotive footage without a production crew.
psychologyKey Architectural Decisions
Canvas Frame Sequence over <video> Scrubbing
A <video> element seeks to the nearest keyframe, so scroll-linked playback stutters and drifts off the scroll position. Extracting the clip to a frame sequence and painting each frame to a canvas gives frame-accurate playback that tracks scroll roughly 1:1.
Windowed Decode with Explicit Bitmap Release
Holding every decoded frame costs ~475 MB and freezes weaker devices. Only frames within ±24 of the scroll position stay decoded via createImageBitmap, explicitly freed as the window moves, capping memory near 120 MB regardless of clip length.
Dedicated rAF Loop for Canvas Paint
Drawing runs on its own requestAnimationFrame loop rather than inside the scroll handler, so canvas work never blocks scrolling. A directional prefetch warms the cache ahead of travel so fast scrolls do not stall on the network.
Physically Derived Wheel Rotation
The closing wheel's rotation angle is computed from distance travelled divided by circumference rather than a hand-tuned constant. The wheel never visually slips, which is the detail that separates motion design from motion decoration.
Cinematics Never Cost Usability
Full keyboard navigation, visible focus rings, AA contrast, 44px tap targets, a persistent accessible heading, and a complete prefers-reduced-motion path that swaps the scrub for static frames. Responsive to 375px with a dedicated mobile hero that preserves the narrative.