Scroll Cinema
Generate premium scrollytelling websites where scroll is the narrative engine. Three libraries coordinate as a unified system: Lenis provides buttery smooth locomotion, GSAP ScrollTrigger orchestrates cinematic section reveals with fluid color transitions, and Three.js renders a living painted-texture background that reacts to cursor position and scroll progress.
This is NOT a general animation skill, a 3D product viewer, or a scroll-hijacking pattern. Scroll-cinema produces pages where the reader moves through chapters — each chapter entrance is choreographed, the color palette flows between sections, and an ambient shader canvas breathes behind the content.
Quick Start
# Complete cinematic storytelling site
python3 ~/.claude/skills/scroll-cinema/scripts/scroll_cinema_generator.py \
--mode full-cinema \
--shader painted-dots \
--chapters 5 \
--pacing medium \
--output story.html
# Chapter reveals with color transitions (no Three.js)
python3 ~/.claude/skills/scroll-cinema/scripts/scroll_cinema_generator.py \
--mode chapter-reveal \
--chapters 4 \
--output chapters.html
# Standalone reactive shader background
python3 ~/.claude/skills/scroll-cinema/scripts/scroll_cinema_generator.py \
--mode painted-backdrop \
--shader watercolor \
--output backdrop.html
# All three shader presets side by side
python3 ~/.claude/skills/scroll-cinema/scripts/scroll_cinema_generator.py \
--mode catalog \
--output catalog.html
Or describe a concept and let Claude generate directly from the templates and references.
Example: /scroll-cinema a story about the Mediterranean told in five chapters — from dawn on the Aegean to dusk on the Strait of Sicily
Modes
| Mode | Output | Libraries |
|---|---|---|
chapter-reveal | Multi-section storytelling page with cinematic entrances and fluid color transitions | Lenis + GSAP ScrollTrigger + OKLCH color system |
painted-backdrop | Three.js shader canvas reactive to cursor + scroll, standalone or embeddable | Three.js + GLSL + scroll-fed uniforms |
full-cinema | Complete cinematic scrolltelling site — all systems integrated | Lenis + GSAP + Three.js + color system |
catalog | All three shader presets rendered side by side with one WebGL context | Lenis + GSAP + Three.js (scissor test) |
Core Architecture
┌──────────────┐ autoRaf: false ┌─────────────────┐
│ Lenis │ ──── lenis.raf(time) ──→ │ GSAP Ticker │
│ (smooth DOM │ ←── drives animation ─── │ (master clock) │
│ scrolling) │ └────────┬────────┘
└──────┬───────┘ │
│ ┌──────▼──────┐
│ lenis.on('scroll') │ ScrollTrigger│
│ → ScrollTrigger.update() │ (orchestrate │
│ │ sections) │
│ └──────┬───────┘
│ │
│ scroll progress │ drives
│ + cursor position │
▼ ▼
┌──────────────┐ ┌────────────────┐
│ Three.js │ │ Section Reveals │
│ Shader │ ← uniforms: uScroll, │ Color Interp. │
│ Background │ uMouse, uTime │ Typography Anim │
└──────────────┘ └────────────────┘
Non-negotiable initialization sequence — the single most important pattern in this skill:
// 1. Register GSAP plugins FIRST
gsap.registerPlugin(ScrollTrigger);
// 2. Init Lenis with autoRaf OFF — GSAP drives the loop
const lenis = new Lenis({ autoRaf: false });
// 3. Connect Lenis to GSAP ticker (single animation frame)
gsap.ticker.add((time) => {
lenis.raf(time * 1000); // GSAP=seconds, Lenis=ms
});
gsap.ticker.lagSmoothing(0);
// 4. Sync ScrollTrigger with Lenis scroll position
lenis.on('scroll', ScrollTrigger.update);
Full integration details, cleanup, and SPA lifecycle: references/lenis-gsap-integration.md
Shader Presets
| Preset | Technique | Performance | Feel |
|---|---|---|---|
painted-dots | Dot-grid with mouse-reactive ripple, scroll-driven density | Lightest | Subtle, editorial, clean |
watercolor | NPR Kuwahara-style edge-preserving filter + procedural noise | Medium | Organic, painterly, warm |
domain-warp | Progressive sinusoidal domain warping | Lightest | Flowing, abstract, psychedelic at high iterations |
All shaders receive these uniforms from the orchestration layer:
uTime— elapsed time from GSAP tickeruMouse— normalized cursor position, lerped at 0.08 for smoothnessuScroll— Lenis smoothed scroll progress (0.0–1.0), lerped at 0.05uVelocity— scroll velocity magnitude (0.0–1.0), clamped ±3 then normalized, lerped at 0.10uChapter— smooth chapter index float, lerped at 0.03uMobile— 1.0 on viewports ≤768px, 0.0 otherwise (watercolor uses this to skip edge detection)uResolution— viewport dimensions for aspect correctionuChapterHue/uChapterLightness— chapter color sync, lerped at 0.03
Full GLSL code, uniform pipeline, and lerp rates: references/painted-shader-patterns.md
Color System
Scroll-driven color transitions between chapters using OKLCH interpolation. sRGB interpolation produces muddy brown midpoints when transitioning between hues — OKLCH maintains perceptual uniformity.
Each chapter defines a palette via data attributes:
<section data-chapter="0" data-hue="250" data-chroma="0.15" data-lightness="0.25">
GSAP ScrollTrigger tweens CSS custom properties registered via @property for GPU-accelerated animation. Fallback to HSL interpolation where OKLCH is unsupported.
Full color system, @property registration, fallback strategy: references/color-interpolation.md
Cinematic Easings
Four custom easing curves for scroll-driven cinematic animation:
| Curve | Cubic-Bezier | Feel | Best For |
|---|---|---|---|
cinematicSilk | 0.45,0.05,0.55,0.95 | Luxurious slow in/out | Hero reveals, title entrances |
cinematicSmooth | 0.25,0.1,0.25,1 | Natural deceleration | Section fade-ins, content blocks |
cinematicFlow | 0.33,0,0.2,1 | Apple-like momentum | Parallax layers, camera moves |
cinematicLinear | 0.4,0,0.6,1 | Subtle ease | Color shifts, background opacity |
Timing philosophy and ScrollTrigger scrub values: references/cinematic-easings.md
Composition Parameters
| Parameter | Range | Default | Effect |
|---|---|---|---|
--mode | chapter-reveal|painted-backdrop|full-cinema|catalog | full-cinema | Output mode |
--shader | painted-dots|watercolor|domain-warp | painted-dots | Shader preset (modes with Three.js) |
--chapters | 2–8 | 5 | Number of story chapters |
--entrance | fade-up|split-text|scale-reveal|clip-path-wipe | fade-up | Section entrance animation (chapter modes) |
--pacing | slow|medium|fast | medium | Scroll height multiplier: slow=1.5×, fast=0.6× |
--color-scheme | dark|light | dark | Background/foreground polarity |
--font | font name | Geist | Primary display font (Google Fonts CDN) |
--accent | hex color | — | Override accent color |
--output | path | output.html | Output file path |
Chapter Structure
Each chapter is a <section> element with sticky content. Minimum height scales with pacing. Entrance animations complete within the first 30% of the chapter's scroll distance — the reader never waits.
Section entrance patterns: fade-up (default), split-text, scale-reveal, clip-path-wipe.
Full chapter architecture, scroll pacing table, responsive layout: references/chapter-structure.md
Design tokens (colors, typography, spacing, animation): references/design-tokens.md