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) │ │
└────────────────────────────────────────────────┘
-
WebP-Sequence-Renderer — Canvas das per
ScrollTrigger(gsap) durch nummerierte Frames steuert.drawImagezeichnet je nach Scroll-Progress den passenden Frame. Frames müssen vorgeladen sein damit der Scrub flüssig läuft. -
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.
-
Soft-Edge-Maske auf Brain-Canvas — nach
drawImagewird ein radialer Gradient perglobalCompositeOperation = '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. -
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 aufbg-ink(#0A0A0A) gesetzt → sichtbarer Farb-Seam zwischen Header-Strip und Canvas-Bereich. Lösung: Section auf#000setzen (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__*) istdocument.visibilityState = "hidden"→ CSS-Animationen UNDrequestAnimationFramesind pausiert. Visuelle Verifikation per Screenshot zeigt nichts. Workarounds: a)anim.currentTime = Xmanuell setzen um Keyframe-Werte zu prüfen, b) Pixel-Sampling pergetImageDatazur 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: screenauf 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
Related
- DESIGN.md — Brand-Tokens (Bone, Forest, Ink, Inter+Lora) — Hero deviiert bewusst (pure black bg)
- reference_av_website_repo.md — Repo-Pointer