Web Hero Sequence Animation

Pattern für eine Hero-Section die per Scroll durch eine Bildsequenz steuert (z.B. ein Brain das aufbaut/explodiert). Lebendig wirkt das Ganze durch drei nicht-synchrone Bewegungs-Layer plus eine Soft-Edge-Maske die rechteckige Bildkanten kaschiert. Implementiert auf agenticventures.de — Code im separaten Repo ~/source/agentic-ventures-website.

Architektur — vier Bausteine

┌─ section bg #000 ──────────────────────────────┐
│  ┌─ StarField (canvas, RAF-twinkle) ─────────┐ │
│  ├─ Brain-Canvas (WebP-Sequence + soft-mask) │ │
│  └─ Text-Overlay (headline, scroll-indicator) │ │
└────────────────────────────────────────────────┘
  1. WebP-Sequence-Renderer — Canvas das per ScrollTrigger (gsap) durch nummerierte Frames steuert. drawImage zeichnet je nach Scroll-Progress den passenden Frame. Frames müssen vorgeladen sein damit der Scrub flüssig läuft.

  2. StarField (separater Canvas-Layer) — eigener Canvas mit ~80–220 Sternen (Density skaliert mit Viewport-Fläche). Jeder Stern hat zufällige Position, Radius, Twinkle-Speed und Phase. Eigene RAF-Loop, unabhängig vom Brain. Liegt als HINTERSTER Layer im DOM (zuerst gerendert) — Sterne werden durch transparente Bereiche der Brain-Canvas-Maske sichtbar.

  3. Soft-Edge-Maske auf Brain-Canvas — nach drawImage wird ein radialer Gradient per globalCompositeOperation = 'destination-in' auf den Canvas gemalt. Mitte = solid, Edges = transparent. Strahlen späterer Frames laufen weich aus statt hart abzubrechen. Plus: Brain wird absichtlich 1.35× größer skaliert als reines “contain”, damit die Strahlen über die Maske hinausragen und im Übergangs-Bereich (= wo Sterne sichtbar werden) ausfaden.

  4. Idle-Mode (vor erstem Scroll):

    • CSS-Float (translateY ±8 px über 7 s, ease-in-out) — sehr ruhiges Schweben, kein “Pumpen”
    • Frame-Cycle via separatem RAF — cycelt frames 0..27 hin und zurück über 4 s mit smoothstep-Easing
    • Beide unabhängig voneinander = organischer Look (würde sonst choreografiert wirken)
    • Stoppt automatisch beim ersten Scroll-Tick (if (self.progress > 0.001) stopIdle())

Stolperer / Lessons

  • WebP-Hintergrund matchen mit Section-BG. WebPs hatten pures #000, Section war auf bg-ink (#0A0A0A) gesetzt → sichtbarer Farb-Seam zwischen Header-Strip und Canvas-Bereich. Lösung: Section auf #000 setzen (auch wenn DESIGN.md “kein reines Schwarz” sagt — bei Hero mit dunkler Imagery ist das eine bewusste Ausnahme).

  • Headless-Preview pausiert Animationen. Im headless Browser (mcp__Claude_Preview__*) ist document.visibilityState = "hidden" → CSS-Animationen UND requestAnimationFrame sind pausiert. Visuelle Verifikation per Screenshot zeigt nichts. Workarounds: a) anim.currentTime = X manuell setzen um Keyframe-Werte zu prüfen, b) Pixel-Sampling per getImageData zur Strukturprüfung, c) Real-Browser-Reload für die echte Verifikation.

  • Scale-Pulse wirkt mechanisch. Skalierung als Idle-Animation fühlt sich an wie “ich pumpe jetzt sichtbar”. translateY-Float (±8 px, 7 s) wirkt deutlich organischer. Faustregel: bei Hero-Idle-Bewegung lieber Translation als Scale, lieber lange Periode als kurze.

  • Frame-Cycle-Range klein halten. Wenn Idle frames 0..50 cyclet und Scroll-Start dann auf frame 1 springt (= scroll 0.01), gibt’s einen sichtbaren Sprung. Range maximal so wählen dass die letzten Idle-Frames optisch noch nah am Scroll-Start sind. Auf agenticventures.de: 28 Frames als guter Kompromiss zwischen “viel Bewegung sichtbar” und “kein Sprung beim Scroll”.

  • Mix-Blend-Mode war NICHT nötig — durch Soft-Edge-Maske wird der Brain-Canvas an den Edges transparent. Sterne darunter werden direkt sichtbar. Ursprünglich überlegt: mix-blend-mode: screen auf StarField über Brain — das wäre rechentechnisch teurer und hätte das Brain aufgehellt. Stattdessen DOM-Order-Layering (Stars zuerst, Brain mit Soft-Mask drüber) ist die saubere Lösung.

Code-Pfade (im Website-Repo)

  • brain-scroll.tsx — Sequence-Renderer + Idle-Logik + Soft-Edge-Maske
  • star-field.tsx — Sternen-Canvas
  • globals.css@keyframes brain-idle (translateY-float), scroll-hint-bar, scroll-hint-chevron
  • brain-sequence — Frame-Sequenz desktop/ (121 frames) + mobile/ (121 frames)

Wann nutzen

  • Hero-Section soll narrativ durch Scroll erzählen (vor → mit → nach)
  • Bildmaterial liegt als Sequence vor (z.B. Render aus Blender, AI-Sequence, Video-Frames als WebP)
  • Performance-Budget: 121 Frames × ~30 KB WebP = ~3.5 MB Preload — auf Mobile vorsichtig sein, separate mobile/ Variante mit kleineren Frames

Wann NICHT nutzen

  • Statisches Hero-Image reicht — keine Sequence-Komplexität nötig
  • Animation soll auf jeder Seite-Größe gleich aussehen — Sequence ist Aspekt-Ratio-empfindlich (siehe Soft-Edge-Maske ist nötig)
  • Kunden-Site mit knappem Performance-Budget — 3.5 MB Preload ist nicht trivial