← Zurück zu Mediendesign & Digitale Medien
Framer Motion ist eine deklarative Animations-Bibliothek für React, die physikbasierte Spring-Animationen, einfache Gesten-Unterstützung und komponentenübergreifende Übergänge in das React-Ökosystem integriert.

Was ist Framer Motion?

Framer Motion wurde von Framer – dem Prototyping-Tool-Unternehmen – als eigenständige Open-Source-Bibliothek veröffentlicht. Es ist heute die meistgenutzte Animations-Bibliothek im React-Ökosystem.

Das Besondere: Framer Motion folgt dem deklarativen Paradigma von React. Statt gsap.to(element, {x: 100}) schreibt man <motion.div animate={{ x: 100 }}>. Die Bibliothek übernimmt intern die Optimierung via WAAPI und CSS Custom Properties.

Version 12 (2024) führte neue Features wie animate() als eigenständige Funktion, verbesserte Layout-Animationen und bessere TypeScript-Typen ein.

Erklärung

Installation und Grundkonzept

``bash npm install framer-motion ``

```jsx import { motion } from 'framer-motion';

// Jedes HTML-Element hat ein motion-Äquivalent <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} transition={{ duration: 0.4, ease: 'easeOut' }} > Animierter Inhalt </motion.div> ```

motion.div, motion.span, motion.button usw. sind direkte Drop-in-Ersetzungen für normale HTML-Elemente.

Variants: Zustände zentralisieren

Variants erlauben die Zentralisierung von Animationszuständen und Weitergabe an Kinder:

```jsx const containerVariants = { versteckt: { opacity: 0 }, sichtbar: { opacity: 1, transition: { staggerChildren: 0.08, // Kinder gestaffelt delayChildren: 0.2 } } };

const elementVariants = { versteckt: { opacity: 0, y: 30 }, sichtbar: { opacity: 1, y: 0 } };

function AnimierteList({ items }) { return ( <motion.ul variants={containerVariants} initial="versteckt" animate="sichtbar" > {items.map(item => ( <motion.li key={item.id} variants={elementVariants}> {item.text} </motion.li> ))} </motion.ul> ); } ```

Kinder-Elemente erben die initial und animate-Prop vom Parent – man muss sie nicht wiederholen.

Spring-Animationen

Framer Motion's größte Stärke sind physikbasierte Spring-Animationen:

```jsx // Type "spring" für federnde Bewegungen <motion.div animate={{ x: 200 }} transition={{ type: 'spring', stiffness: 300, // Federsteifigkeit (höher = schneller) damping: 25, // Dämpfung (niedriger = mehr Federn) mass: 1 // Masse des Objekts }} />

// Vordefinierte Spring-Presets transition={{ type: 'spring', bounce: 0.4 }} // 0 = kein Bounce, 1 = viel

// Snap: Abrupt, kein Federschwingen transition={{ type: 'spring', damping: 100 }} ```

AnimatePresence: Exit-Animationen

Das Herausragende an Framer Motion ist AnimatePresence – es ermöglicht Exit-Animationen, bevor ein Komponente aus dem DOM entfernt wird:

```jsx import { AnimatePresence, motion } from 'framer-motion';

function Modal({ istOffen, zuSchliessen }) { return ( <AnimatePresence> {istOffen && ( <motion.div key="modal" className="modal-overlay" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} onClick={zuSchliessen} > <motion.div className="modal-inhalt" initial={{ scale: 0.9, y: 40 }} animate={{ scale: 1, y: 0 }} exit={{ scale: 0.9, y: -20, opacity: 0 }} transition={{ type: 'spring', damping: 25 }} onClick={e => e.stopPropagation()} > {/ Modal-Inhalt /} </motion.div> </motion.div> )} </AnimatePresence> ); } ```

useAnimation Hook

```jsx import { useAnimation } from 'framer-motion';

function AnimiertesElement() { const controls = useAnimation();

async function starteSequenz() { await controls.start({ x: 100, opacity: 0.5 }); await controls.start({ x: 200, opacity: 1 }); controls.start({ x: 0 }); }

return ( <motion.div animate={controls} onClick={starteSequenz}> Klick mich </motion.div> ); } ```

Scroll-Animationen (useInView, useScroll)

```jsx import { motion, useInView, useScroll, useTransform } from 'framer-motion'; import { useRef } from 'react';

// Element bei Scroll einblenden function ScrollElement() { const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: '-100px' });

return ( <motion.div ref={ref} initial={{ opacity: 0, y: 60 }} animate={isInView ? { opacity: 1, y: 0 } : {}} transition={{ duration: 0.6, ease: 'easeOut' }} > Erscheint beim Scrollen </motion.div> ); }

// Parallax mit useScroll/useTransform function ParallaxHero() { const { scrollY } = useScroll(); const y = useTransform(scrollY, [0, 500], [0, -150]);

return ( <div className="hero"> <motion.img src="/hintergrund.jpg" style={{ y }} /> </div> ); } ```

Layout-Animationen

```jsx // Automatische Animation bei Layout-Änderungen import { motion, LayoutGroup } from 'framer-motion';

function DynamischeList({ items, sortierung }) { return ( <LayoutGroup> {items.map(item => ( <motion.div key={item.id} layout // Animiert automatisch bei Position-Änderung transition={{ type: 'spring', damping: 20 }} > {item.text} </motion.div> ))} </LayoutGroup> ); } ```

Beispiele

Tab-Navigation mit shared layout

```jsx function Tabs({ tabs }) { const [aktiv, setAktiv] = useState(tabs[0].id);

return ( <div className="tabs"> {tabs.map(tab => ( <button key={tab.id} onClick={() => setAktiv(tab.id)} style={{ position: 'relative' }} > {tab.label} {aktiv === tab.id && ( <motion.div className="tab-indikator" layoutId="tab-indikator" // Gleiches layoutId = shared layout style={{ position: 'absolute', bottom: 0, left: 0, right: 0 }} /> )} </button> ))} </div> ); } ```

Gestensteuerung: Drag und Swipe

``jsx <motion.div drag="x" dragConstraints={{ left: -100, right: 100 }} dragElastic={0.1} whileDrag={{ scale: 1.05 }} onDragEnd={(event, { velocity, offset }) => { if (Math.abs(offset.x) > 100) { // Swipe-Aktion ausführen naechsteKarte(); } }} > Wischbare Karte </motion.div> ``

In der Praxis

prefers-reduced-motion in Framer Motion:

```jsx import { useReducedMotion } from 'framer-motion';

function AnimiertesElement() { const reduzierteBewegung = useReducedMotion();

return ( <motion.div initial={{ opacity: 0, y: reduzierteBewegung ? 0 : 40 }} animate={{ opacity: 1, y: 0 }} > Inhalt </motion.div> ); } ```

Vergleich & Abgrenzung

Framer MotionGSAP (GreenSock) – GrundlagenWeb Animations API (WAAPI)
React-IntegrationNativeExternExtern
Exit-AnimationenAnimatePresenceManuellManuell
Spring-PhysikExzellentMit Elastic-EaseNein
Layout-AnimationenAutomatischManuellManuell
Nicht-ReactNeinJaNativ

Häufige Fragen (FAQ)

Kann ich Framer Motion ohne React nutzen? Die Library ist ausschließlich für React. Für andere Frameworks: Vue mit vue3-motion oder Motion One (JS-Library von Framer Motion Autor Matt Perry).

Wie groß ist Framer Motion? ~50 KB gzip. Die Tree-shaking-Unterstützung ist gut – nur genutzte Features werden eingebunden.

Was ist Motion One? Motion One (von Matt Perry) ist eine ~3 KB kleine Alternative für Vanilla-JS-Projekte, die die WAAPI mit einer Framer-Motion-ähnlichen API abstrahiert.

Verwandte Einträge

Weiterführend

  • Framer Motion: Dokumentation (2024) – framer.com/motion
  • Matt Perry: Framer Motion 5 Release (2021) – framer.com/blog
  • Josh W. Comeau: A Friendly Introduction to Spring Physics (2021) – joshwcomeau.com
  • Motion One: motion.dev (Matt Perry, 2021) – kleineres WAAPI-Wrapper
  • Framer Motion Animations Course: ui.dev/framer-motion
← Zurück zu Mediendesign & Digitale Medien
Infotag · 13. Mai · 15:00 Uhr · Vor Ort

Sei am Mittwoch dabei.
Bring Eltern oder Freunde mit.

Ein halber Nachmittag, der dir drei Jahre Klarheit bringen kann. Kostenlos, unverbindlich, ehrlich.

  • Rundgang durch Studios, Schnitträume und Tonstudio
  • Echte Absolventenfilme sehen
  • 1:1-Beratung zu Bewerbung & BAföG
  • Studierende direkt fragen
  • Kaffee, kein Sales-Pitch
  • Auch online möglich

Platz beim Infotag reservieren

Dauert 30 Sekunden. Bestätigung per E-Mail.
100 % kostenlos · keine Verpflichtung · jederzeit absagbar
Framer Motion für React — Wiki | Lazi Akademie | Lazi Akademie Esslingen