# Animierte Scroll-Websites mit Video: Der vollständige Leitfaden zur Erstellung

> So erstellen Sie eine Premium-Website mit Scroll-Video-Effekt (Apple-Stil): Frame-Zuschnitt in WebP, LERP-Glättung auf Canvas, Dwell-Remap und das redaktionelle System Precision Editorial.

Animated Video Scroll ist eine Technik zur Erstellung kinematografischer One-Page-Websites, bei der das Scrollen der Seite die Wiedergabe von Videomaterial direkt steuert. Wenn der Nutzer mit dem Mausrad oder per Wischgeste auf dem Smartphone scrollt, wechselt das Video flüssig Bild für Bild und synchronisiert sich dabei mit dem Lesetempo sowie dem Erscheinen der Informationsblöcke.

Dieser Effekt hat sich zum Aushängeschild für Präsentationen von Premium-Produkten wie Apple, Tesla und Porsche sowie von führenden Design-Studios weltweit entwickelt.

> [!IMPORTANT]
> Diese Technik **ist kein Einbetten eines herkömmlichen Video-Players** und verwendet keine animierten GIFs. Im Kern basiert sie auf einer Einzelbild-Sequenz aus leichten WebP-Bildern, die hardwarebeschleunigt auf einem `<canvas>`-Element via WebGL oder 2D Context gerendert werden. Dies garantiert eine sofortige Reaktion auf jedes Pixel des Scrolls.

---

## 1. Was ist eine Scroll-Site mit Video und ihre Vorteile

Traditionelles Hintergrundvideo auf einer Seite weist zwei wesentliche Nachteile auf: Es läuft in seinem eigenen Tempo ab, ignoriert die Aufmerksamkeit des Lesers und erzeugt eine hohe Belastung für Netzwerk und Akku mobiler Geräte.

Eine scroll-gesteuerte Website löst dieses Problem:

- **Volle Kontrolle über die Aufmerksamkeit:** Der Nutzer bestimmt selbst das Betrachtungstempo. Bleibt er an einem wichtigen Absatz stehen, friert das Objekt im Bildausschnitt in der gewünschten Perspektive ein.
- **Keine Verzögerungen und Pufferung:** Die Videodatei wird vorab in optimierte statische WebP-Frames zerlegt, sodass der Browser während schnellen Scrollens keine schwere Dekodierung von MP4-Containern durchführen muss.
- **Narrative Synchronisation:** Textthesen, grafische Markierungen, numerische Metriken und technische Spezifikationen erscheinen genau dann, wenn die Kamera das entsprechende Detail des Objekts zeigt.

### Eignung nach Projekttyp

| Produkttyp | Warum Scroll-Video geeignet ist | Fokus im Bildausschnitt |
| :--- | :--- | :--- |
| **Automobile & Technik** | Betont Aerodynamik, Chassis-Details, Innenraum-Materialien | Sanfte Kamerabewegung entlang der Karosserie, Wechsel der Perspektiven |
| **Premium-Elektronik** | Demonstriert präzise Montage, Gehäuse-Dicke, Optik | Explosionsansicht (exploded view), Makroaufnahmen |
| **Architektur & Immobilien** | Erzeugt räumliches Volumen- und Lichtgefühl | Flug durch die Fassade in den Innenbereich |
| **Fashion & Schmuck** | Zeigt Stofftextur, Lichtspiel auf Metall | Delikate Lichtbewegung um das Produkt herum |

---

## 2. Architektur und Dateistruktur des Skills

Der Skill ist als modularer Engineering-Pipeline aufgebaut. Jede Komponente ist für einen isolierten Arbeitsschritt verantwortlich:

```text
animated-sites-engine/
├── SKILL.md            # Сценарна інструкція: від аналізу ролика до верстки
├── visual-system.md    # Дизайн-система Precision Editorial та правила сітки
├── extract_frames.py   # Python-утиліта нарізки та оптимізації WebP
└── evals.json          # Бенчмарк та критерії перевірки якості сайту
```

### 1. SKILL.md — Hauptanweisung und Skriptalgorithmus
Beschreibt den Lebenszyklus der Seitenerstellung: von der technischen Analyse des Quellmaterials mittels `ffprobe` bis hin zur Strukturierung in sinnvolle Kapitel, Berechnung der Scroll-Länge und Zusammenbau der fertigen HTML/JS-Anwendung.

### 2. visual-system.md — Referenzhandbuch des Precision Editorial Systems
Legt strenge ästhetische Regeln fest: Verzicht auf billige Klischees (grundlose Neon-Glows, Glass-Panels und Playfair-Schriftarten), vorgefertigte „Trackline“-Palette für technische Storylines, 5 grundlegende Layout-Schemata für Textplatzierung und typografische Paare.

### 3. extract_frames.py — Extraktions- und Komprimierungsskript für Frames
Konsolen-Utility in Python. Liest automatisch Video-Metadaten via `ffprobe`, berechnet die proportionale Anzahl der Frames, schneidet separate Streams für Desktop und Mobile im WebP-Format zu und generiert die `manifest.json`.

### 4. evals.json — Szenarien zur Qualitätssicherung
Enthält einen Test-Referenzfall (am Beispiel eines Porsche-Videos), der die Flüssigkeit der LERP-Interpolation, das Verhalten des Canvas bei Fenstergrößenänderungen, Tastaturzugänglichkeit und Asset-Gewicht überprüft.

---

## 3. Wiedergabemechanik: Canvas, LERP und Dwell-Remap

Im Zentrum steht ein `<canvas>`-Element, das den gesamten Bildschirm abdeckt (`position: fixed`). Das Scrollen der Seite wird in einen relativen Fortschritt von 0.0 bis 1.0 umgerechnet, der bestimmt, welche Frame-Nummer angezeigt werden soll.

```text
Позиція скролу (0.0 — 1.0)
          │
          ▼
┌───────────────────────┐
│     Dwell-Remap       │ ──► Штучне сповільнення біля центрів глав
└──────────┬────────────┘
           │
           ▼
┌───────────────────────┐
│     LERP-фільтр       │ ──► targetFrame плавним кроком наздоганяє скрол
└──────────┬────────────┘
           │
           ▼
┌───────────────────────┐
│   HTML5 2D Canvas     │ ──► ctx.drawImage(loadedImages[frameIndex], ...)
└───────────────────────┘
```

### 1. Glättung durch LERP (Linear Interpolation)

Würde man Frames strikt bei jedem Scroll-Event wechseln, würde die Animation ruckartig wirken, besonders bei Mäusen mit diskretem Scrollrad.

Für kinematografische Flüssigkeit wird lineare Interpolation angewendet: Der aktuell gerenderte Frame (`currentFrame`) „holt“ sanft den Ziel-Frame (`targetFrame`) ein.

```javascript
let currentFrame = 0;
let targetFrame = 0;
const lerpFactor = 0.075; // Коефіцієнт згладжування (0.05 — 0.1)

function renderLoop() {
  // Наближаємо поточний кадр до цільового
  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. Verlangsamung nahe jedem Kapitel (Dwell-Remap)

Damit der Nutzer Zeit hat, Überschriften und Texte zu lesen, ohne das Mausrad filigran stoppen zu müssen, wird die **Dwell-Remap**-Technik eingesetzt. Nahe der Mitte jedes Kapitels wird die Geschwindigkeit des Frame-Wechsels künstlich verlangsamt, während zwischen den Kapiteln eine flüssige Bewegung erhalten bleibt.

```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) {
      // Плавне згасання коефіцієнта швидкості по косинусоїді
      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. Progressives Laden der Frames

Um weiße Flashes zu vermeiden und nicht auf das Laden des gesamten Pakets (100–150 Frames) warten zu müssen, wird eine zweistufige Strategie angewendet:

1. **Kritische Priorität:** Sofort werden die ersten 5 Frames sowie die Schlüssel-Frames der wichtigsten Kapitel geladen.
2. **Hintergrund-Warteschlange:** Die übrigen Frames werden in kleinen Batches via `requestIdleCallback` oder Promise-Queue nachgeladen. Falls der benötigte Frame noch unterwegs ist, rendert das Canvas den nächstgelegenen bereits geladenen Frame.

---

## 4. Schritt-für-Schritt-Entwicklungsprozess: Vom Video zum Code

Der gesamte Produktionsprozess ist in sieben sequenzielle Schritte unterteilt:

### Schritt 1. Analyse des Videos mittels ffprobe

Vor der Codegenerierung werden die technischen Parameter der Quelldatei analysiert:

```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
```

Es wird ein Kontaktbogen mit 6 Referenz-Frames erstellt, um Kamerabewegung, Objektposition und verfügbaren negativen Raum (negative space) für Text einzuschätzen.

### Schritt 2. Formulierung des Design-Konzepts

Eine klare These wird definiert:
- **Hauptdarsteller:** Wer oder was steht im Mittelpunkt?
- **Ziel-Emotion:** Technische Präzision, ruhiger Luxus, Drive, Meditativität.
- **Schrift-Paar:** Kontrastreiche Headline und ingenieurtechnische Monospace-Akzentuierung.
- **Markantes Stilmittel:** Telemetrie, variabler Tracking-Wert, Mikroframe-Zähler.

### Schritt 3. Zuschnitt und Optimierung der Frames

Anzahl der Frames und Scroll-Höhe werden entsprechend der Video-Lauflänge gewählt:

| Video-Länge | Anzahl Frames | Empfohlene Scroll-Höhe | Gesamtzielgewicht (WebP) |
| :--- | :--- | :--- | :--- |
| **0–5 Sekunden** | 60–80 Frames | 450–550vh | 4–7 MB |
| **5–15 Sekunden** | 90–130 Frames | 600–750vh | 8–12 MB |
| **15–30 Sekunden** | 130–180 Frames | 750–900vh | 10–15 MB |
| **30+ Sekunden** | 180–200 Frames | 900–1000vh | 12–16 MB |

Start der Extraktion via Python-Skript:

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

### Schritt 4. Skript pro Kapitel

Die Seite wird in 4–6 inhaltliche Abschnitte unterteilt. Zum Beispiel:
1. **Kapitel 1: Intro (0–15%)** — Modellname, minimalistische Silhouette.
2. **Kapitel 2: Aerodynamik (20–40%)** — Fokus auf Geometrie des Spoilers und Luftkanäle.
3. **Kapitel 3: Antriebsstrang (45–65%)** — Darstellung des Motors oder Chassis mit Telemetriedaten.
4. **Kapitel 4: Finale & Action (75–100%)** — Vollständige Entfaltung des Fahrzeugs und Testfahrt-Button.

### Schritt 5. Layer-Komposition und Layout rund um das Video

Text darf niemals Schlüsseldetails im Bild überdecken. Je nach Bewegungsrichtung des Objekts verschieben sich Textblöcke sanft vom linken zum rechten Rand oder fixieren sich im unteren Bilddrittel.

### Schritt 6. Assembly basierend auf Start-Template

Ein robustes HTML5-Framework mit vorbereiteter Lazy-Loading-Logik und Responsive-Support wird genutzt, an das individuelle Farb-Tokens und das Frame-Manifest angebunden werden.

### Schritt 7. Überprüfung und Kritik

> [!TIP]
> Testen Sie Scroll-Sites immer über einen lokalen HTTP-Server (`python3 -m http.server`), statt die Datei direkt via `file:///` zu öffnen. Browser-CORS-Richtlinien blockieren das Laden von WebP-Frames via `fetch()` beim lokalen Öffnen von Dateien.

---

## 5. Visuelles System: Typografie und Trackline-Palette

Das **Precision Editorial**-System verlangt den Verzicht auf dekorative Überladenheit zugunsten einer ausgefeilten Schweizer Typografie und der Ästhetik von Kontrollinstrumenten.

### Typografische Kombinationen

:::tabs
=== Archivo + IBM Plex Mono (Sportlich-Technisch)
- **Headlines:** Archivo (Black, Tight tracking `-0.03em`)
- **Body Text:** Archivo (Regular, 15px)
- **Technische Captions & Telemetrie:** IBM Plex Mono (Medium, 11px, Uppercase)
- **Ideal für:** Automobile, Luftfahrt, Heavy Engineering, Uhrwerke.
=== Roboto Flex + Roboto Mono (Modern Engineering)
- **Headlines:** Roboto Flex (Variable width, Bold)
- **Body Text:** Roboto (Regular, 16px)
- **Technische Captions:** Roboto Mono (12px, tabular-nums)
- **Ideal für:** Enterprise Software, Robotik, Laborgeräte.
=== Barlow Condensed + Manrope (Kinematografischer Drive)
- **Headlines:** Barlow Condensed (Extra Bold, Uppercase)
- **Body Text:** Manrope (Medium, 15px)
- **Technische Captions:** Space Mono (11px)
- **Ideal für:** Extremsport, E-Sports, Mode, Collection Drops.
=== Anybody + Source Code Pro (Industrieller Akzent)
- **Headlines:** Anybody (Bold, Ultra-expanded)
- **Body Text:** Inter (Regular, 15px)
- **Technische Captions:** Source Code Pro (11px)
- **Ideal für:** Architekturbüros, konzeptuelle Elektrofahrzeuge.
:::

### Farbpalette „Trackline“

Die Palette basiert auf Farben echter Rennstrecken: mattes Carbon, kühles Aluminium und dezente Racing-Akzente.

```css
:root {
  /* Базові відтінки */
  --color-carbon: #080a09;    /* Глибокий чорний вуглепластик (основний фон) */
  --color-paper: #f1f0e9;     /* Теплий матовий білий (основний текст) */
  --color-alloy: #a8aca8;     /* Металевий алюміній (другорядні підписи) */
  --color-track: #414541;     /* Графітовий асфальт (межі сітки, розділювачі) */
  
  /* Акцентні інженерні маркери */
  --color-petrol: #12372d;    /* Глибокий петролеум для підкладок карток */
  --color-signal: #d9381e;    /* Гоночний червоний (активні стани, алерти) */
  --color-heritage: #c5a059;  /* Золотистий колір для прогрес-бару та таймінгу */
}
```

> [!NOTE]
> Signal-Farben (`--color-signal` und `--color-heritage`) werden punktuell eingesetzt — zur Markierung des aktiven Kapitels oder Positionsindikators, wobei sie maximal 3% der Bildschirmfläche beanspruchen.

---

## 6. Layer-Komposition, Bewegung und markante Stilmittel

Die Seite besteht aus drei visuell unabhängigen Ebenen unterschiedlicher Tiefe:

```text
┌─────────────────────────────────────────────────────────────┐
│ 3. Шар інтерфейсу: прогрес-бар, індикатор глави, кнопки дій │
├─────────────────────────────────────────────────────────────┤
│ 2. Інформаційний шар: заголовок, опис, блок телеметрії      │
├─────────────────────────────────────────────────────────────┤
│ 1. Canvas-шар: повноекранне відео з LERP-рендерингом       │
└─────────────────────────────────────────────────────────────┘
```

### 5 Varianten der Textkomposition

| Layout-Schema | Content-Position | Optimales Nutzungsszenario |
| :--- | :--- | :--- |
| **Masthead Statement** | Riesige Headline zentriert über den ganzen Screen | Erster Viewport (Intro des Videos) |
| **Side Margin Annotation** | Schmale Spalte (3–4 cols) rechts oder links | Objekt bewegt sich im gegenüberliegenden Bildteil |
| **Split Statement** | Headline links, techn. Beschreibung rechts | Objekt stabil streng zentriert fixiert |
| **Telemetry Dock** | Horizontales Panel unten mit Instrumentendaten | Demonstration von Dynamik, Speed, Power |
| **Final Callout** | Fokussierter Block mit einer einzigen Hauptaktion (CTA) | Abschluss-Screen nach Ende der Videosequenz |

### Animationsprinzipien für DOM-Elemente

Da das Video auf dem Canvas bereits intensive Bewegung erzeugt, muss die Animation der Textblöcke zurückhaltend sein:
- **Erscheinen via Maske:** Text steigt von unten aus einem Container mit `overflow: hidden` auf.
- **Verschiebung:** Maximal 16–24px auf der Y-Achse.
- **Timings:** 600–800ms beim Eintritt des Kapitels mit der Kurve `cubic-bezier(0.16, 1, 0.3, 1)`.
- **Kein Blur:** Der Filter `filter: blur()` ist streng verboten — er erzwingt Neurechnungen der Browser-Layer und zerstört stabile 60 FPS.

---

## 7. Anti-Patterns: Verzicht auf veraltete „Luxus“-Klischees

Die meisten Template-Video-Landingpages wirken billig aufgrund typischer Designer-Klischees. Hier ist, was vollständig vermieden werden sollte:

| Veraltetes Klischee | Warum es schlecht ist | Professionelle Alternative |
| :--- | :--- | :--- |
| **Playfair Display + dünner Grotesk** | Standard-Template für „Pseudo-Luxus“ | Präzise Grotesks: Archivo, Roboto Flex, Manrope |
| **Glassmorphism (Mattglas)** | Verschwimmt das Hintergrundvideo, belastet GPU stark | Kontrastreiner klarer Text im freien Raum des Bildes |
| **Schwebende Partikel & Staub** | Lenken vom realen Objekt ab | Sauberes Canvas ohne künstlichen dekorativen Ballast |
| **Violett-blaue Neon-Gradienten** | Assoziiert mit Krypto-Landingpage-Templates | Natürliche Farben, direkt aus den Video-Frames entnommen |
| **Custom Cursor mit Lag** | Erzeugt Trägheitsgefühl und ist unkomfortabel | Nativer System-Cursor mit klaren Hover-States |

---

## 8. Performance, Accessibility (A11y) und Mobile-Optimierung

Scroll-Sites mit viel Grafik erfordern strenge technische Disziplin:

### 1. Begrenzung des Device Pixel Ratio (DPR)
Moderne Smartphones haben Screens mit DPR 3.0 oder 3.5. Rendert man das Canvas in dieser Auflösung, steigt die Rechenfläche fast um den Faktor 10, was den Prozessor sofort überhitzt.

```javascript
// Обмежуємо максимальний DPR значенням 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. Rendering-Pause für versteckte Tabs
Wenn der Nutzer zu einem anderen Tab wechselt, muss das Rendering sofort pausieren:

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

### 3. Reduzierter Animationsmodus (prefers-reduced-motion)
Für Menschen mit empfindlichem Vestibularapparat kann kontinuierliches Frame-Scrolling Schwindel auslösen.

> [!IMPORTANT]
> Ist in der OS-Einstellung `prefers-reduced-motion: reduce` aktiviert, muss die Site statt endloser Frame-Scrolling einen hochwertigen statischen Poster oder eine vereinfachte Slide-Galerie anzeigen.

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

---

## 9. Praktischer Workshop: Erstellung und Start des Projekts

Erstellen wir eine minimale funktionierende Struktur einer Scroll-Site.

### Schritt 1. Generierung der Frames aus dem Video

Legen Sie das Video im Arbeitsverzeichnis ab und starten Sie den Zuschnitt:

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

Das Skript erstellt die Manifestdatei `frames/manifest.json`:

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

### Schritt 2. Dateistruktur des fertigen Projekts

```text
my-scroll-site/
├── index.html              # Розмітка та логіка canvas-плеєра
├── styles.css              # Токени Precision Editorial та медіазапити
├── app.js                  # LERP-цикл, dwell-remap та обробка скролу
└── frames/
    ├── desktop/            # frame-0001.webp ... frame-0120.webp
    ├── mobile/             # frame-0001.webp ... frame-0080.webp
    └── manifest.json       # Метадані та розміри
```

### Schritt 3. Start der lokalen Umgebung

Für korrektes Nachladen der Ressourcen starten Sie einen lokalen HTTP-Server:

```bash
python3 -m http.server 3000
```

Öffnen Sie die Adresse `http://localhost:3000` im Browser und prüfen Sie die Flüssigkeit des Frame-Laufs sowie die korrekte Umschaltung der Kapitel.

---

## 10. Abschließender Checkliste für die Fertigstellung der Scroll-Site

Vor dem Release prüfen Sie die Einhaltung aller ingenieurtechnischen und visuellen Kriterien:

### Technische Metriken
- [x] Gesamtgewicht der Desktop-Frames überschreitet nicht 12 MB (Mobile max. 5 MB).
- [x] Die ersten 5 Frames haben Preload-Priorität (`preload`).
- [x] DPR-Faktor ist auf den Wert `2` begrenzt, um Überhitzung mobiler Geräte zu verhindern.
- [x] Der `requestAnimationFrame`-Loop stoppt beim Wechsel zu einem anderen Browser-Tab.

### User Experience & Accessibility
- [x] Sanfter LERP-Übergang zwischen Frames ohne harte Ruckler implementiert.
- [x] Dwell-Remap für komfortables Lesen des Textes nahe jedem Kapitel eingestellt.
- [x] Modus `prefers-reduced-motion` mit statischem Poster unterstützt.
- [x] Mindestgröße aller klickbaren Elemente beträgt mindestens 44×44px.

### Design & Ästhetik
- [x] Klares ingenieurtechnisches Schrift-Paar ohne Pseudo-Luxus-Klischees verwendet.
- [x] Text überdeckt nicht das bewegte Hauptobjekt im Bild.
- [x] UI-Farben direkt aus dem Videomaterial übernommen.
- [x] Seite endet mit einer klaren, eindeutigen Handlungsaufforderung (CTA).