Skip to main content
Guide contents

Guide contents

Time to study: 14 min
#automation#animated#video#scroll#creative-coding#frontend
Intermediate14 min

Animated Video Scroll Websites: A Complete Production Guide

How to build Apple-style scroll-driven video websites: WebP frame extraction, Canvas LERP smoothing, dwell-remap math, and the Precision Editorial design system.

Published:

Animated Video Scroll is a technique for creating cinematic, single-page web experiences where user scrolling directly controls the frame-by-frame playback of high-definition video. As a visitor scrolls with their mouse wheel or swipes on mobile, the footage advances or reverses in sync with their reading pace and the appearance of contextual text blocks.

This interactive technique is the signature pattern behind flagship product launches by Apple, Tesla, Porsche, and leading creative digital studios worldwide.

Important

This technique does not embed standard video players or rely on animated GIFs. Instead, it plays a sequence of lightweight WebP image frames hardware-accelerated on an HTML5 <canvas> element via a 2D or WebGL context, providing immediate, zero-lag feedback for every scrolled pixel.


1. What is a Video Scroll Site and Why It Matters

Background autoplay videos have two severe shortcomings: they run on their own timeline regardless of user attention, and they trigger heavy battery drain and cellular data consumption on mobile devices.

A scroll-driven canvas approach solves these issues:

  • Complete Attention Control: The user dictates the pace of discovery. Pausing on an important specification freezes the camera angle at that exact moment.
  • Instant Response with Zero Buffering: Video files are pre-extracted into optimized WebP frames, eliminating expensive in-browser MP4 container decoding during rapid scrub gestures.
  • Storyline Synchronization: Headlines, technical diagrams, telemetry metrics, and callouts appear precisely when the video frame reveals the corresponding component.

Project Fit Matrix

Industry / ProductWhy Video Scroll FitsKey Visual Subject
Automotive & HardwareEmphasizes aerodynamics, chassis engineering, cockpit detailsSweeping camera orbits, exterior fly-bys
Consumer ElectronicsShowcases precision assembly, tolerances, glass/metal finishesExploded component views, macro details
Architecture & Real EstateConveys spatial volume, lighting shifts, material texturesDrone fly-throughs from exterior facade to interior
Fashion & JewelryCaptures fabric flow, drape, reflection of light on metalControlled light movements across textures

2. Skill Architecture and File Structure

The production workflow is organized as a modular engineering pipeline. Each file in the skill directory serves an isolated, specific responsibility:

text
animated-sites-engine/ ├── SKILL.md # Master workflow script: from video analysis to frontend layout ├── visual-system.md # Precision Editorial design guidelines and grid rules ├── extract_frames.py # Python utility for frame extraction and WebP compression └── evals.json # Benchmark criteria for automated quality checks

1. SKILL.md — Workflow Core and Chapter Algorithm

Governs the end-to-end development cycle: extracting video metadata with ffprobe, segmenting footage into narrative chapters, calculating scroll height multipliers, and generating the final HTML/JS boilerplate.

2. visual-system.md — Precision Editorial Design System

Enforces strict visual standards: rejecting cheap clichés (unjustified neon glows, frosted glass cards, and Playfair serif pairings), providing the engineering-focused "Trackline" palette, and defining 5 core content composition layouts.

3. extract_frames.py — Frame Extraction and Compression Script

A CLI utility written in Python. It parses video metadata using ffprobe, calculates optimal frame counts for video duration, outputs separate desktop and mobile WebP image streams, and generates manifest.json.

4. evals.json — Quality Verification Benchmarks

Contains a benchmark test scenario (based on a Porsche GT3 track video) verifying LERP smoothness, canvas resize behavior, keyboard accessibility, and asset payload budgets.


3. Playback Mechanics: Canvas, LERP, and Dwell-Remap

At the core of the engine sits a fixed, full-viewport <canvas> element (position: fixed). Scroll position is normalized into a relative progress value between 0.0 and 1.0, which maps directly to an active frame index.

text
Scroll Progress (0.0 — 1.0) │ ▼ ┌───────────────────────┐ │ Dwell-Remap │ ──► Artificial slowdown near chapter centerpoints └──────────┬────────────┘ │ ▼ ┌───────────────────────┐ │ LERP Filter │ ──► targetFrame smooths out rapid mousewheel notches └──────────┬────────────┘ │ ▼ ┌───────────────────────┐ │ HTML5 2D Canvas │ ──► ctx.drawImage(loadedImages[frameIndex], ...) └───────────────────────┘

1. Smoothing via LERP (Linear Interpolation)

Binding frame changes directly to scroll events produces jerky, notched motion on stepped mouse wheels.

To achieve cinematic smoothness, Linear Interpolation (LERP) is applied: the currently rendered frame (currentFrame) smoothly chases the target scroll frame (targetFrame).

javascript
let currentFrame = 0; let targetFrame = 0; const lerpFactor = 0.075; // Smoothing factor (typically between 0.05 and 0.1) function renderLoop() { // Smoothly increment currentFrame towards targetFrame currentFrame += (targetFrame - currentFrame) * lerpFactor; const frameToDraw = Math.round(currentFrame); drawCanvasFrame(frameToDraw); requestAnimationFrame(renderLoop); } window.addEventListener("scroll", () => { const maxScroll = document.documentElement.scrollHeight - window.innerHeight; const progress = Math.min(Math.max(window.scrollY / maxScroll, 0), 1); targetFrame = progress * (totalFrames - 1); }, { passive: true });

2. Chapter Deceleration (Dwell-Remap)

To give users ample time to read chapter headings and body copy without requiring surgical precision on their scroll wheel, Dwell-Remap artificially reduces scrub speed around chapter centers while preserving fluid motion during transitions.

javascript
function applyDwellRemap(rawProgress, chapterPoints = [0.2, 0.5, 0.8], dwellWidth = 0.08, strength = 0.45) { let remapped = rawProgress; for (const center of chapterPoints) { const distance = Math.abs(rawProgress - center); if (distance < dwellWidth) { // Smooth cosine deceleration curve const factor = Math.cos((distance / dwellWidth) * (Math.PI / 2)); const delta = (rawProgress - center) * (1 - factor * strength); remapped = center + delta; break; } } return Math.min(Math.max(remapped, 0), 1); }

3. Progressive Frame Loading

To avoid white canvas flashes and eliminate long loading screens, frames are loaded in two passes:

  1. Critical Priority: The initial 5 frames and the keyframe of each chapter are loaded immediately before unhiding the UI.
  2. Background Queue: Remaining frames are fetched in batches via requestIdleCallback. If a requested frame has not arrived, the canvas displays the nearest available neighbor.

4. Step-by-Step Production Process: Video to Code

The complete creation pipeline consists of seven sequential stages:

Step 1. Technical Analysis via ffprobe

Before writing code, extract technical specs from the raw footage:

bash
ffprobe -v error -select_streams v:0 \ -show_entries stream=width,height,duration,r_frame_rate,codec_name \ -of default=noprint_wrappers=1 input.mp4

Generate a contact sheet of 6 keyframes to evaluate camera motion, object positions, and available negative space for typographic overlays.

Step 2. Establishing the Design Concept

Formulate a strict creative thesis:

  • Core Subject: The primary focus of the footage.
  • Target Mood: Technical precision, quiet luxury, athletic performance, or calm minimalism.
  • Type Pairing: High-contrast editorial headline with a technical monospace sub-accent.
  • Signature Accent: Telemetry HUD dock, variable-width headline easing, or frame index stamps.

Step 3. Frame Extraction and Optimization

Select your target frame count and scroll height based on video duration:

Video DurationFrame CountRecommended Scroll HeightTarget Payload Budget (WebP)
0–5 seconds60–80 frames450–550vh4–7 MB
5–15 seconds90–130 frames600–750vh8–12 MB
15–30 seconds130–180 frames750–900vh10–15 MB
30+ seconds180–200 frames900–1000vh12–16 MB

Run the extraction script:

bash
python3 extract_frames.py \ --input ./raw/porsche-gt3.mp4 \ --output ./public/frames \ --desktop-frames 120 \ --mobile-frames 80 \ --quality 62

Step 4. Chapter Structuring

Divide the narrative into 4–6 thematic chapters. For example:

  1. Chapter 1: Intro (0–15%) — Model name and subtle silhouette reveal.
  2. Chapter 2: Aerodynamics (20–40%) — Detail on rear wing geometry and intake channels.
  3. Chapter 3: Powertrain (45–65%) — Engine bay or chassis with telemetry stats.
  4. Chapter 4: Final Call to Action (75–100%) — Complete vehicle reveal and test-drive link.

Step 5. Layer Composition and Negative Space

Never place typography directly over the primary visual subject. Depending on camera movement, dynamically position text from the left column to the right column, or dock it in the lower third.

Step 6. Assembly with the Starter Template

Populate the battle-tested HTML5 starter boilerplate with custom CSS design tokens, extracted WebP image assets, and chapter scroll ranges.

Step 7. Verification and Critique

Tip

Always run your build through a local HTTP server (python3 -m http.server) rather than opening file:/// URLs directly. Browser CORS policies block async WebP image fetch() requests when opened from the filesystem.


5. Visual System: Typography and Trackline Palette

The Precision Editorial approach rejects visual clutter in favor of Swiss typographic rigor, structured grids, and instrument-panel aesthetics.

Curated Type Pairings

  • Headlines: Archivo (Black, Tight tracking -0.03em)
  • Body Text: Archivo (Regular, 15px)
  • Telemetry & Badges: IBM Plex Mono (Medium, 11px, Uppercase)
  • Best For: Automotive, aerospace, heavy engineering, horology.

The "Trackline" Color Palette

Inspired by racetrack tarmac, lightweight composite materials, and cockpit warning signals:

css
:root { /* Surface Tokens */ --color-carbon: #080a09; /* Deep matte carbon black (base background) */ --color-paper: #f1f0e9; /* Warm off-white (primary body text) */ --color-alloy: #a8aca8; /* Anodized aluminum gray (secondary text) */ --color-track: #414541; /* Tarmac graphite (grid lines, dividers) */ /* Signal Accents */ --color-petrol: #12372d; /* Deep racing petroleum green (card backgrounds) */ --color-signal: #d9381e; /* FIA red (active states, alerts) */ --color-heritage: #c5a059; /* Muted gold (progress bar and telemetry accents) */ }
Note

Vibrant signal colors (--color-signal and --color-heritage) are used sparingly — highlighting active chapter indices or progress indicators without occupying more than 3% of the viewport.


6. Layer Composition, Motion, and Signature Techniques

Pages are constructed from three visually distinct, stacked layers:

text
┌─────────────────────────────────────────────────────────────┐ │ 3. Interface Layer: progress bar, chapter pill, actions │ ├─────────────────────────────────────────────────────────────┤ │ 2. Information Layer: headlines, body copy, telemetry dock │ ├─────────────────────────────────────────────────────────────┤ │ 1. Canvas Layer: full-bleed video rendered with LERP │ └─────────────────────────────────────────────────────────────┘

5 Core Typographic Layout Patterns

Layout PatternPlacementBest Use Case
Masthead StatementFull-width centered title across the viewportOpening hero screen introducing the subject
Side Margin AnnotationNarrow column (3–4 cols) pinned left or rightSubject moves through the opposite side of the frame
Split StatementHeadline pinned left, technical specs pinned rightSubject remains firmly centered in the footage
Telemetry DockLow-profile horizontal HUD at the bottomDemonstrating metrics, speed, horsepower, dimensions
Final CalloutCentered card with a single primary actionClosing frame directing the user to a purchase or test-drive

DOM Motion Principles

Because the canvas already provides intense visual motion, text overlays must animate with discipline:

  • Masked Transitions: Text translates upward through an overflow: hidden container.
  • Subtle Displacement: Y-axis translation limited to 16–24px.
  • Timings: 600–800ms duration using a cubic-bezier(0.16, 1, 0.3, 1) easing curve.
  • No Backdrop Blurs: filter: blur() is prohibited on scrubbed layers to protect 60 FPS performance.

7. Anti-Patterns: Rejecting Cheap Luxury Clichés

Many video landing pages fail because they lean on generic visual tropes. Avoid these patterns:

Outdated ClichéWhy It FailsProfessional Alternative
Playfair Display + thin sansGeneric luxury-template aestheticPurpose-built grotesque typefaces: Archivo, Roboto Flex
Heavy GlassmorphismObscures the video and bottlenecks GPU layersHigh-contrast clean typography positioned in negative space
Floating dust particlesDistracts from the actual engineered productClean canvas presentation without decorative artificial noise
Purple/Cyan neon gradientsCheap crypto-landing page vibeNatural palette colors pulled directly from video frames
Laggy custom cursorIntroduces perceived latency and degrades UXNative system cursor with distinct interactive hover states

8. Performance, Accessibility (A11y), and Mobile Optimization

High-frame-rate canvas experiences require strict engineering discipline:

1. Limiting Device Pixel Ratio (DPR)

Modern phones feature DPRs of 3.0 or 3.5. Rendering a full-screen canvas at that resolution causes memory strain and battery overheating.

javascript
// Cap maximum canvas DPR at 2.0 const dpr = Math.min(window.devicePixelRatio || 1, 2); canvas.width = window.innerWidth * dpr; canvas.height = window.innerHeight * dpr; ctx.scale(dpr, dpr);

2. Pausing Inactive Tabs

Pause render loops whenever the user changes browser tabs:

javascript
document.addEventListener("visibilitychange", () => { if (document.hidden) { cancelAnimationFrame(animationFrameId); } else { requestAnimationFrame(renderLoop); } });

3. Supporting Reduced Motion (prefers-reduced-motion)

For users with vestibular conditions, continuous frame-by-frame scrub animation can cause motion sickness.

Important

When prefers-reduced-motion: reduce is enabled in the operating system, the canvas animation must be replaced with a high-resolution static poster image or a standard multi-panel layout.

css
@media (prefers-reduced-motion: reduce) { .scroll-container { height: auto !important; } canvas { display: none !important; } .static-hero-fallback { display: block !important; } }

9. Hands-on Workshop: Project Setup and Launch

Here is how to structure and launch a minimal production-ready scroll site.

Step 1. Frame Extraction

Place your source video in your workspace and run extraction:

bash
mkdir my-scroll-site && cd my-scroll-site python3 extract_frames.py --input sample.mp4 --output ./frames --desktop-frames 120

This generates frames/manifest.json:

json
{ "totalFrames": 120, "desktop": { "pathPattern": "frames/desktop/frame-%04d.webp", "width": 1920, "height": 1080, "totalWeightMb": 9.4 }, "recommendedScrollVh": 700 }

Step 2. Project Directory Tree

text
my-scroll-site/ ├── index.html # Markup and canvas container ├── styles.css # Precision Editorial design tokens and breakpoints ├── app.js # LERP render loop, dwell-remap, and scroll listeners └── frames/ ├── desktop/ # frame-0001.webp ... frame-0120.webp ├── mobile/ # frame-0001.webp ... frame-0080.webp └── manifest.json # Dimensions and frame count

Step 3. Launching the Local Server

Start a lightweight HTTP server:

bash
python3 -m http.server 3000

Open http://localhost:3000 in your browser to verify smooth playback, chapter synchronization, and responsive layout behavior.


10. Production Readiness Checklist

Verify your site against this checklist before going live:

Engineering & Performance

  • Desktop frame payload is under 12 MB (Mobile under 5 MB).
  • Initial 5 frames are preloaded via <link rel="preload">.
  • Canvas DPR is clamped at 2.0 to protect mobile GPUs.
  • Render loop halts when the browser tab is hidden (visibilitychange).

User Experience & Accessibility

  • LERP interpolation delivers fluid transitions across stepped mouse wheels.
  • Dwell-Remap provides readable pauses at chapter centerpoints.
  • Static poster fallback is active for prefers-reduced-motion: reduce.
  • Interactive touch targets meet the minimum 44×44px size threshold.

Visual Polish & Art Direction

  • Typography uses a purposeful, engineering-led typeface pair.
  • Negative space placement ensures text never obscures the primary subject.
  • Palette tokens reflect authentic colors sampled from the source footage.
  • Site concludes with a clear, singular Call to Action (CTA).
This guide is completely free. If it saved you an evening, you can support the project's growth.
Support the author