Frontend-Animationen
Du bist verantwortlich für Design, Implementierung, Review und Optimierung von Frontend-Animationen. Standardmäßig wird ein React + TypeScript-Projekt angenommen; bei reinem JS oder anderen Frameworks richte dich nach dem Projektstand, ohne React-Lösungen in Vue- oder native Projekte zu erzwingen. Animationen sind Verbesserungen, keine Dekoration: Stelle zuerst sicher, dass die statische Version gut aussieht und funktioniert, bevor du Animationen hinzufügst. Ohne Bestätigung des Nutzers dürfen keine neuen Abhängigkeiten hinzugefügt werden.
§0 Vor der Arbeit: Abhängigkeiten & Designsystem-Erkennung
Führe vor der Arbeit die folgenden fünf Schritte in dieser Reihenfolge aus; fehlt ein Schritt, führe zuerst die Erkennung durch, bevor du Code schreibst.
- Lies
package.jsonund die tatsächlich gesperrten Versionen inpnpm-lock.yaml/package-lock.json/yarn.lock, um installierte Animationsbibliotheken und deren Hauptversionen zu identifizieren. - Lies
tailwind.config.*, globale Styles (globals.css/index.css/app.css) und Theme-Dateien, um vorhandene Tokens, Dauern, Easing-Funktionen und Namenskonventionen zu finden. - Wenn motion vorhanden ist, verwende kein GSAP; wenn GSAP vorhanden ist, füge kein motion hinzu; für denselben Anwendungsfall sind keine zwei Bibliotheken erlaubt.
- Füge keine neuen Abhängigkeiten eigenmächtig hinzu. Wenn eine neue Abhängigkeit wirklich nötig ist, erkläre zuerst den Paketnamen, die min+gzip-Größe, Alternativen und warum vorhandene Bibliotheken nicht ausreichen, und warte auf die Bestätigung des Nutzers.
- Übernimm die vorhandenen Namenskonventionen, Dateistruktur, Codestil und Token-Namen des Projekts; führe kein zweites Animationssystem ein.
| Erkanntes | Standardvorgehen |
|---|---|
| Bereits motion vorhanden | Interaktionen, Ein-/Ausblendungen und Layout-Animationen alle mit motion; GSAP nicht einführen |
| Bereits framer-motion (alte Version) | Vorhandenen Paketnamen und API verwenden, nicht eigenmächtig auf motion migrieren; Upgrade separat vorschlagen und durchführen |
| Bereits GSAP vorhanden | Timeline- und Scroll-Interaktionen mit GSAP + ScrollTrigger; einfaches Hover weiterhin mit CSS-Transition; kein motion hinzufügen |
| Nur Tailwind | transition / duration / ease Utility-Klassen mit globalen CSS-Variablen verwenden; keine Bibliothek installieren |
| Reines CSS-Projekt | Nur CSS-Transition/-Animation + WAAPI verwenden; keine JS-Animationsbibliothek installieren |
| Next.js App Router | Animationskomponenten mit "use client" markieren; View Transitions und motion als Client-Komponenten behandeln; keine Hacklösungen für routenübergreifenden Zustand |
| Vue | Native CSS oder Vue-Ökosystem-Animationslösungen verwenden; React-spezifische Bibliotheken nicht aufzwingen |
§1 Anti-Pattern-Liste (Nicht verhandelbar)
Prüfe Punkt für Punkt; wenn ein Punkt zutrifft, schreibe den Code neu – keine Kompromisse.
| Verboten | Alternative |
|---|---|
transition: all .3s | Explizit transform, opacity auflisten, bei Bedarf color hinzufügen |
Einheitliches ease-in-out für die ganze Seite | Kurven nach Ein-/Aus-/Bidirektional-Kontext wählen (siehe §3) |
Element mit opacity: 0 + scale(.8) einfliegen | opacity: .9→1 + translateY(8px)→0 |
Gedankenloses linear | Nur bei Fortschrittsbalken und unendlichen Schleifendekorationen verwenden |
| Mehr als 3 gleichzeitig bewegte Elemente auf einem Bildschirm | Nur 1 visuellen Fokus behalten; restliche Elemente still oder sehr schwach animieren |
Hover mit transform: translateY(-4px), wenn der Container keinen Platz reserviert hat | scale verwenden oder dem Elternelement padding zur Reservierung geben |
| Nur Einblendung, keine Ausblendung | Muss paarweise entworfen werden; Ausblendung schneller als Einblendung |
Großflächige filter: blur() / drop-shadow in Animationen | Vorgemerkte Unschärfeebenen verwenden oder den Animationsbereich reduzieren |
| Animationen überdecken CTA / Formulare | Animationsebene mit pointer-events: none versehen oder den interaktiven Bereich aussparen |
| Ladeanimation der ersten Seite länger als 1,5s | Wenn länger, zuerst ein Content-Skeleton anzeigen |
| Benutzerdefinierte Cursor + Schweif (außer vom Nutzer explizit gewünscht) | Nicht verwenden |
| Jedes Listenelement mit komplexer Wort-für-Wort- oder Frame-für-Frame-Animation | 30–50ms Stagger-Verschiebung der gesamten Gruppe verwenden |
setTimeout zum Verketten von Animationen | Transition/animation-Events, onAnimationComplete, Timeline verwenden |
Frame-basiertes el.style.left = x | WAAPI / rAF / Timeline der Bibliothek verwenden |
Begründung: Wenn der erste Bildschirm länger als 1,5s wartet, beginnt der Nutzer zu zweifeln, ob die Seite hängt; daher zuerst Content-Skeleton anzeigen. Wenn mehr als 3 unabhängige Bewegungen gleichzeitig stattfinden, geht der visuelle Fokus verloren und der Nutzer weiß nicht, wohin er schauen soll.
§2 Auswahlentscheidungsbaum (Kurzfassung)
Bestimme zuerst das Schema aus der Tabelle, dann die Werte aus §3, erst dann schreibe Code.
| Szenario | Erste Wahl | Nicht verwenden |
|---|---|---|
| Hover / Press / Toggle-Feedback | CSS-Transition | GSAP (zu schwer) |
| Komponentenbetreten/-verlassen, Listenhinzufügung/-entfernung, Layout-Änderungen | motion (AnimatePresence + layout) | Manuelles height-Animieren |
| Routen-/Seitenübergänge | View Transitions API oder motion layoutId | Vollbildüberlagerung + Verzögerung |
| Komplexe Timeline, Sequenz-Choreographie, Scroll-Interaktionen | GSAP + ScrollTrigger | CSS-Keyframes-Ansammlung |
| 3D / Partikel / Physik / Shader | three.js + React Three Fiber + drei | Mit CSS 3D vortäuschen |
| Vektoranimationen vom Designer | dotLottie / Lottie | In GIF umwandeln |
| Einfache Icons oder Pfadanimationen | SVG + CSS | Lottie-Runtime einführen |
| Diagrammanimationen | Bibliothekseigene Animationen (wie Recharts/visx Transition) | Pfade selbst tweenen |
| Hintergrunddekoration (Grid/Wellen/Glühen) | CSS oder Canvas + requestAnimationFrame, pausierbar | three.js (außer bei echtem 3D-Bedarf) |
| Zahlen-/Betragsänderungen | tabular-nums + einfaches Tween | Frame-basiertes Layout-Reset |
Vollständige Auswahllogik, Fragereihenfolge und die Eskalationsleiter „CSS → leichte Bibliothek → schwere Bibliothek“ findest du unter references/decision-tree.md.
§3 Wertevorgaben (Kein „nach Gefühl“)
Alle Dauern, Kurven und Amplituden aus der folgenden Tabelle; für Werte, die nicht in der Tabelle enthalten sind, muss zuerst eine Begründung erfolgen, bevor sie hinzugefügt werden.
Dauer
| Element | Wert |
|---|---|
| Hover / Press | 120–180ms |
| Toggle / Aus-/Einklappen | 200–300ms |
| Einblendung | 240–400ms |
| Ausblendung | Einblendungsdauer × 0,6–0,7 |
| Seitenübergang | 300–500ms |
| Layout-Änderung (Layout-Animation) | 300–500ms |
| Stagger-Intervall | 30–50ms, Gesamtdauer der gesamten Gruppe ≤ 500ms |
| Länger als 600ms | Muss begründet werden, sonst entfernen |
Easing
| Easing | Kurve |
|---|---|
| Einblendung | cubic-bezier(0.16, 1, 0.3, 1) |
| Ausblendung | cubic-bezier(0.4, 0, 1, 1) |
| Bidirektional / Zustandswechsel | cubic-bezier(0.4, 0, 0.2, 1) |
| Verschiebung / Drag / Gesten | Spring: stiffness 300–500, damping 30–40 |
| linear | Nur Fortschrittsbalken, unendliche Schleifendekorationen |
Amplitude
| Amplitude | Wert |
|---|---|
| Verschiebung | Gering 4–8px / Mittel 12–24px / Groß 32–64px / >80px nur bei Vollbildübergängen |
| Transparenz | Mikrointeraktion .9→1; Einblendung .6→1; 0→1 nur bei Vollbildüberlagerungen und Modals |
| Skalierung | Nur im Bereich 0.96–1.04 |
Spring
| Parameter | Wert | Begründung |
|---|---|---|
| stiffness | 300–500 | Unter 300 träge, über 500 zittert es wie ein Defekt |
| damping | 30–40 | Unter 30 zu starkes Zurückfedern, über 40 kein Federeffekt |
| mass | 0.8–1 | Minimale Änderung der Trägheit spürbar |
Begründung für Intervalle, ein Satz pro Punkt:
- Hover / Press 120–180ms: Unter 120ms ist die Statusänderung nicht lesbar; über 180ms wirkt die Rückmeldung träge, der Nutzer denkt, er habe nicht geklickt.
- Einblendung 240–400ms: Unter 240ms ist die Bewegungsrichtung nicht lesbar; über 400ms beginnt der Nutzer zu warten.
- Ausblendung × 0,65: Das Verlassen muss nicht deutlich sichtbar sein; langsamer wirkt schleppend.
- Stagger 30–50ms: Unter 30ms erscheint alles gleichzeitig; über 50ms überschreitet die gesamte Gruppe die 500ms-Geduldsgrenze.
Diese Werte sind bereits als CSS-Variablen und TS-Konstanten in references/tokens.md hinterlegt; der gesamte Code referenziert Tokens, keine hartcodierten Zahlen.
§4 Performance- und Accessibility-Richtlinien
- Animiere nur
transform/opacity; für Größenänderungen verwende FLIP oder dielayout-Fähigkeit einer Bibliothek. - Füge
will-change: transformzu kontinuierlich animierten Ebenen hinzu; entferne es nach Ende der Animation. - Virtualisiere lange Listen; pausiere Offscreen-Elemente mit IntersectionObserver.
prefers-reduced-motion: reduceist ein Pflichtzweig, keine optionale Verbesserung. Nach dem Downgrade muss der Statuswechsel immer noch klar erkennbar sein: In der Regel auf ≤120ms Opacity-Überblendung (120ms reichen aus, um den Statuswechsel zu lesen, ohne dass eine interpretierte Animation nötig ist) oder direkten Wechsel zurückgreifen.- Verwende kein Flimmern mit mehr als 3 Mal pro Sekunde (WCAG 2.3.1 Photosensitivitätsschwelle liegt bei 3 Flimmern pro Sekunde).
- Während der Animation darf kein Fokus geraubt, keine Tabulatorreihenfolge gestört werden; der Tastaturfokus-Ring nimmt nicht an der Animation teil.
- Gestalte so, dass auch die statische Version gut aussieht – Animationen sind nur eine Verbesserung.
WCAG-Kriterien, aria-live und Testmethoden findest du unter references/accessibility.md.
§5 Implementierungsregeln (Eisern)
- Ein- und Ausblendung paarweise entwerfen; Ausblendung schneller.
- Nur ein visueller Fokus pro Bildschirm.
- Stagger mit 30–50ms; gesamte Gruppe maximal 500ms.
- Dekorative Animationsebene muss
pointer-events: noneerhalten. - Verwende Transition/animation-Events,
onAnimationCompleteoder Timeline zur Verkettung;setTimeoutist verboten. - Verwende kein GSAP, wenn CSS oder Framer-Motion ausreichen.
- Verwende
transform, anstattwidth/heightzu animieren. - Animationsdauer unterliegt dem Design-Review; keine „gefühlt langsamere“ Anpassung per Wort.
- Erst reduzieren, dann hinzufügen: Lösche zunächst Animationen, die entfernt werden können; optimiere die verbleibenden.
§6 Review-Modus
Beim Review vorhandener Animationen gibst du jede Beanstandung in vier festen Abschnitten aus:
Problem / Begründung (Verweis auf §1–§4) / Codevorschlag / Auswirkung (Dauer, Performance, Accessibility)
Regeln:
- Meldepunkte auf echte Probleme beschränken – keine Änderungen an funktionierenden Implementierungen um der Menge willen.
- Maximal 8 Punkte; sortiert nach Schweregrad: Accessibility > Performance > Dauer/Easing > Stil.
- Am Ende einen Abschnitt „Diese Aspekte sind in Ordnung“ mit 1–3 Punkten, damit der Nutzer nicht versehentlich gute Implementierungen ändert.
Scan-Befehl (nur lesend, kein --fix; jede automatische Änderung würde die Designabsicht zerstören):
node ~/.claude/skills/frontend-animation/scripts/audit-animation.mjs <Projektverzeichnis> --json
Das Skript meldet nur Probleme und Positionen; die Entscheidung zur Behebung liegt beim Menschen.
§7 Referenzen nach Symptom/Bedarf
| Symptom/Bedarf | Datei |
|---|---|
| Unsicher, ob CSS oder Bibliothek; Auswahl zwischen Frameworks; Fragereihenfolge | references/decision-tree.md |
| Token anlegen, Tailwind anbinden, CSS-Variablen oder TS-Konstanten schreiben | references/tokens.md |
| Installation, API, Versionsfallen von motion / GSAP / three.js+R3F / Lottie / View Transitions | references/libraries.md |
| Fertige Vorlagen (Listen-Einblendung / Routenübergang / Drag / Mausfolge / Zahlenlauf / 3D-Flip / Schleifen-Hintergrund / Skeleton / Magnetic-Button / Lottie) | references/patterns.md |
| Easing-Kurven auswählen, lineare Näherung von Spring, Kurve begründen | references/easing.md |
| reduced-motion-Downgrade, WCAG, Flimmern und Fokus, Testmethoden | references/accessibility.md |
| Vollständige Referenzkomponente mit reduced-motion-Zweig | assets/template-component.tsx |
| Animationsprobleme im bestehenden Code scannen | scripts/audit-animation.mjs |
§8 Selbstprüfung vor dem Commit (8 Fragen, jede einzeln beantworten)
- Ist diese Animation notwendig? Sieht die statische Version auch ohne sie gut aus?
- Werden nur transform / opacity animiert?
- Liegen Dauer, Easing und Amplitude innerhalb der Vorgaben aus §3?
- Sind Ein- und Ausblendung paarweise vorhanden und die Ausblendung schneller?
- Gibt es einen reduced-motion-Zweig? Ist der Zustandswechsel im Downgrade noch erkennbar?
- Wurde eine neue Abhängigkeit hinzugefügt? Ohne Bestätigung wäre das ein Verstoß.
- Gibt es mehr als 3 Flimmer pro Sekunde? Wird während der Animation der Fokus geraubt?
- Gibt es nur einen visuellen Fokus pro Bildschirm?
Falls eine Frage nicht beantwortet werden kann, stoppe und korrigiere, bevor du committest.