Architekt für Animationssysteme
Erstelle leistungsstarke, barrierefreie Animationssysteme mit Framer Motion, GSAP, der View Transitions API und Feder-Physik für flüssige UI-Erlebnisse.
Auslöser
Aktivieren bei: Seitenübergänge, Layout-Animationen, scroll-getriggerte Animationen, Mikrointeraktionen, Feder-Physik, motion.div, gsap.to, View Transition API, gemeinsame Elementübergänge, gestaffelte Listenanimationen.
NICHT für: reine CSS-Hover-/Fokus-Effekte – verwende css-in-js-architect. Canvas/WebGL-Rendering – verwende creative-coding-expert. Lottie-Datei-Wiedergabe – verwende die standardmäßige Lottie-Integration.
Schnellstart
- Wähle deine Engine – Framer Motion für deklaratives React, GSAP für timeline-lastige oder Nicht-React-Projekte, View Transitions API für seitenübergreifende Navigation.
- Animiere nur transforms und opacity – diese laufen auf dem Compositor-Thread (GPU) und vermeiden Layout-Neuberechnungen.
- Verwende
will-changesparsam – nur auf Elementen, die gleich animiert werden; nach Abschluss entfernen. - Respektiere
prefers-reduced-motion– deaktiviere oder vereinfache alle Animationen für Benutzer, die dies wünschen. - Profiling mit DevTools – im Performance-Tab auf Layout-Verschiebungen während Animationen achten.
Kernfähigkeiten
| Bereich | Technologien | Schlüsselmuster |
|---|---|---|
| Deklaratives React | Framer Motion 11+, motion-Komponenten | Layout-Animationen, AnimatePresence, Varianten |
| Timeline-Animation | GSAP 3.12+, ScrollTrigger | Scroll-gesteuerte Sequenzen, Fixieren, Scrubbing |
| Seitenübergänge | View Transitions API, Next.js useViewTransition | Gemeinsame Elementübergänge zwischen Seiten |
| Feder-Physik | Framer Motion Springs, react-spring | Natürliche Beschleunigung, unterbrechbare Animationen |
| Mikrointeraktionen | CSS-Übergänge + Framer Motion | Button-Feedback, Hover-Zustände, Lade-Indikatoren |
| Scroll-gesteuert | CSS animation-timeline: scroll(), GSAP ScrollTrigger | Parallax, Fortschrittsanzeigen, Einblenden beim Scrollen |
Architekturmuster
Muster 1: Framer Motion Layout-Animationen
import { motion, AnimatePresence, LayoutGroup } from 'framer-motion';
function FilterableGrid({ items, filter }: Props) {
const filtered = items.filter(item => item.category === filter);
return (
<LayoutGroup>
<motion.div layout className="grid grid-cols-3 gap-4">
<AnimatePresence mode="popLayout">
{filtered.map(item => (
<motion.div
key={item.id}
layout // Positionänderungen animieren
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
transition={{ type: 'spring', stiffness: 300, damping: 25 }}
>
<Card item={item} />
</motion.div>
))}
</AnimatePresence>
</motion.div>
</LayoutGroup>
);
}
Muster 2: View Transitions API für Seitenavigation
// app/components/TransitionLink.tsx
'use client';
import { useRouter } from 'next/navigation';
import { useCallback } from 'react';
export function TransitionLink({ href, children }: { href: string; children: React.ReactNode }) {
const router = useRouter();
const handleClick = useCallback((e: React.MouseEvent) => {
e.preventDefault();
if (!document.startViewTransition) {
router.push(href);
return;
}
document.startViewTransition(() => {
router.push(href);
});
}, [href, router]);
return <a href={href} onClick={handleClick}>{children}</a>;
}
/* Gemeinsame Elementübergänge über view-transition-name */
.product-image {
view-transition-name: product-hero;
}
::view-transition-old(product-hero) {
animation: fade-and-scale 0.3s ease-out;
}
::view-transition-new(product-hero) {
animation: fade-and-scale 0.3s ease-in reverse;
}
Muster 3: Respektierung von reduzierter Bewegung
import { useReducedMotion } from 'framer-motion';
function AnimatedComponent() {
const shouldReduce = useReducedMotion();
return (
<motion.div
initial={{ opacity: 0, y: shouldReduce ? 0 : 20 }}
animate={{ opacity: 1, y: 0 }}
transition={shouldReduce
? { duration: 0 }
: { type: 'spring', stiffness: 260, damping: 20 }
}
>
Inhalt
</motion.div>
);
}
┌─ Entscheidungsbaum für Animationen ──────────────────┐
│ │
│ prefers-reduced-motion? │
│ ├── JA → nur sofortiger Einblend-Effekt (keine Bewegung) │
│ └── NEIN → vollständige Feder-/Transform-Animation │
│ │
│ Was wird animiert? │
│ ├── transform/opacity → GPU-Compositor (gut) │
│ ├── width/height → Layout-Neuberechnung (vermeiden) │
│ └── box-shadow → reines Malen (akzeptabel) │
└────────────────────────────────────────────────────────┘
Anti-Patterns
width,height,top,leftanimieren – löst in jedem Frame eine Layout-Neuberechnung aus. Verwende stattdessentransform: translate/scalefür 60fps.will-changeauf jedem Element – fördert zu viele Ebenen auf die GPU und erhöht den Speicherverbrauch. Nur auf Elemente anwenden, die gleich animiert werden.prefers-reduced-motionignorieren – bewegungsempfindliche Benutzer können Übelkeit oder Krampfanfälle erleiden. Diese Media Query immer prüfen und respektieren.- Animationsdauer > 500ms für Mikrointeraktionen – lässt die UI träge wirken. Halte Button-/Hover-Feedback unter 200ms, Seitenübergänge unter 400ms.
- Während des Scrollens ohne
requestAnimationFrameoder ScrollTrigger animieren – verursacht Ruckeln. Verwende für scroll-gesteuerte Animationen GSAP ScrollTrigger oder CSSanimation-timeline: scroll().
Qualitätscheckliste
- Alle Animationen verwenden
transformundopacity(Compositor-freundliche Eigenschaften) -
prefers-reduced-motionwird mittelsuseReducedMotionoder CSS Media Query respektiert - Mikrointeraktionen unter 200ms, Seitenübergänge unter 400ms
-
AnimatePresencefür Ein-/Ausblend-Animationen verwendet - Layout-Animationen verwenden die Framer-Motion-
layout-Eigenschaft (keine manuelle Positionsberechnung) -
will-changewird nur während der Animation angewendet und danach entfernt - Kein Ruckeln im Chrome DevTools Performance-Bereich (keine langen Frames > 16ms)
- Animationen sind unterbrechbar (Feder-Physik, keine festen Keyframes mit
ease) - View Transitions API hat einen Fallback für nicht unterstützte Browser
- Scroll-gesteuerte Animationen verwenden
animation-timelineoder ScrollTrigger (keine Scroll-Ereignis-Listener)