Framer Motion
Framer Motion
Framer Motion is the most complete animation solution for React. It uses a declarative API where you describe the initial, animate, and exit states and the library handles interpolation, spring physics, and orchestration.
terminal
INSTALL
npm install framer-motion
6.1 Basic motion Component
FadeIn.jsx
JSX
import { motion } from 'framer-motion'; export function FadeIn({ children }) { return ( <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} transition={{ duration: 0.4, ease: 'easeOut' }} > {children} </motion.div> ); }
6.2 AnimatePresence: Exit Animations
AnimatePresence is Framer Motion’s answer to the unmount problem. Wrap conditional or list components with it to enable exit animations.
Notification.jsx
JSX
import { AnimatePresence, motion } from 'framer-motion'; export function NotificationStack({ notifications }) { return ( <div className="stack"> <AnimatePresence> {notifications.map(n => ( <motion.div key={n.id} layout {/* auto-animates layout shifts */} initial={{ opacity: 0, x: 60, scale: 0.9 }} animate={{ opacity: 1, x: 0, scale: 1 }} exit={{ opacity: 0, x: 60, scale: 0.85 }} transition={{ type: 'spring', stiffness: 500, damping: 40 }} className="notification" > {n.message} </motion.div> ))} </AnimatePresence> </div> ); }
6.3 Variants: Orchestrated Animations
Variants let you define named states and propagate them down the component tree — enabling staggered child animations with a single parent state change.
StaggerList.jsx
JSX
import { motion } from 'framer-motion'; const container = { hidden: {}, show: { transition: { staggerChildren: 0.1, // 100ms between each child delayChildren: 0.2, }, }, }; const item = { hidden: { opacity: 0, y: 24 }, show: { opacity: 1, y: 0, transition: { type: 'spring', bounce: 0.35 }, }, }; export function StaggerList({ items }) { return ( <motion.ul variants={container} initial="hidden" animate="show" > {items.map(item => ( <motion.li key={item.id} variants={item}> {item.text} </motion.li> ))} </motion.ul> ); }
6.4 Layout Animations
Add layout prop to a motion component and Framer Motion automatically animates any change in its size or position, including reflows caused by sibling DOM changes.
ExpandableCard.jsx
JSX
import { motion } from 'framer-motion'; import { useState } from 'react'; export function ExpandableCard({ title, body }) { const [expanded, setExpanded] = useState(false); return ( <motion.div layout {/* animates height changes */} onClick={() => setExpanded(e => !e)} style={{ cursor: 'pointer', overflow: 'hidden' }} > <motion.h3 layout="position">{title}</motion.h3> {expanded && ( <motion.p initial={{ opacity: 0 }} animate={{ opacity: 1 }} > {body} </motion.p> )} </motion.div> ); }
6.5 Page Transitions with React Router
PageWrapper.jsx
JSX
import { motion, AnimatePresence } from 'framer-motion'; import { useLocation, Routes, Route } from 'react-router-dom'; const pageVariants = { initial: { opacity: 0, x: -20 }, animate: { opacity: 1, x: 0 }, exit: { opacity: 0, x: 20 }, }; const pageTransition = { duration: 0.25, ease: 'easeInOut' }; export function AnimatedRoutes() { const location = useLocation(); return ( <AnimatePresence mode="wait"> <Routes location={location} key={location.pathname}> <Route path="/" element={ <motion.div variants={pageVariants} initial="initial" animate="animate" exit="exit" transition={pageTransition} > <HomePage /> </motion.div> } /> </Routes> </AnimatePresence> ); }
