Introduction
En 2026, les animations ne sont plus un luxe mais un standard pour des interfaces engageantes et performantes. Framer Motion, la bibliothèque officielle de Framer pour React, excelle par sa déclaration simple, ses APIs puissantes et son accélération GPU native, surpassant CSS transitions ou GSAP en intégration React. Contrairement aux libs génériques, elle gère nativement les gestures, le scroll et les layout shifts sans boilerplate.
Ce tutoriel intermediate vous guide pour animer une app Next.js : du basique au scroll-linked, avec 6 étapes codées. Vous apprendrez à créer des micro-interactions fluides qui boostent la rétention utilisateur de 20-30% (selon études Nielsen). À la fin, votre app rivalisera avec les benchmarks Figma/Webflow. Prêt à transformer vos composants statiques en expériences vivantes ? (128 mots)
Prérequis
- Node.js 20+ installé
- Bases solides en React 18+ et TypeScript
- Familiarité avec Next.js 14 (App Router)
- Éditeur VS Code avec extension Tailwind CSS IntelliSense
- Connaissances CSS/Flexbox pour le positionnement
Initialiser le projet Next.js
npx create-next-app@latest framer-motion-demo --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
cd framer-motion-demo
npm install framer-motion
npm run devCette commande crée un projet Next.js 14 prêt pour TypeScript et Tailwind, puis installe Framer Motion (v11+ en 2026). Elle configure l'App Router pour les pages server-side et les aliases d'imports. Lancez npm run dev pour un serveur hot-reload sur http://localhost:3000. Évitez les templates legacy pour profiter des optimisations RSC.
Premier rendu animé
Remplacez le contenu par défaut de src/app/page.tsx pour tester Framer Motion. Nous utilisons motion.div comme wrapper universel : il remplace div et ajoute des props d'animation comme initial, animate et transition. Analogy : comme un div supercharged avec physique réelle (springs, easing).
Composant animé basique
import { motion } from 'framer-motion';
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-center p-24 bg-gradient-to-br from-blue-400 to-purple-600">
<motion.div
initial={{ opacity: 0, y: 50 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, ease: 'easeOut' }}
className="text-4xl font-bold text-white mb-8"
>
Bienvenue à Framer Motion !
</motion.div>
<motion.button
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
className="px-8 py-4 bg-white text-blue-600 rounded-lg font-semibold shadow-lg"
>
Cliquez-moi
</motion.button>
</main>
);
}Ce code remplace la page d'accueil par une entrée fade-in/slide-up et un bouton avec hover/tap scale. initial définit l'état de départ, animate l'état cible ; whileHover cible les interactions. Copiez-collez directement : il est autonome et optimise les re-renders via useReducedMotion. Piège : oubliez transition pour des defaults brusques.
Maîtriser les variants
Variants centralisent les états multiples en objet : idéal pour orchestrer des groupes d'éléments (orchestration). Analogy : un chef d'orchestre pour vos animations, évitant la duplication de props. Utilisez animate={state} pour switcher dynamiquement.
Animation avec variants
import { motion, useMotionValue, useSpring } from 'framer-motion';
import { useState } from 'react';
type ItemProps = { title: string; index: number };
const Item = ({ title, index }: ItemProps) => (
<motion.li
variants={{
hidden: { opacity: 0, x: -50 },
visible: (i = 1) => ({
opacity: 1,
x: 0,
transition: { delay: i * 0.1 }
})
}}
initial="hidden"
animate="visible"
custom={index}
className="p-4 bg-white rounded shadow-md mb-2"
>
{title}
</motion.li>
);
export default function AnimatedList() {
const [items] = useState(['Élément 1', 'Élément 2', 'Élément 3']);
return (
<motion.ul
initial="hidden"
whileInView="visible"
variants={{
hidden: { opacity: 0 },
visible: { opacity: 1 }
}}
className="w-80"
>
{items.map((item, index) => (
<Item key={item} title={item} index={index} />
))}
</motion.ul>
);
}Ce composant liste animée utilise variants pour stagger (délai par index via custom). whileInView déclenche au scroll viewport. Importez-le dans page.tsx via . Avantage : enfant hérite des variants parents. Piège : sans custom, pas de stagger ; testez sur mobile pour useReducedMotion.
Personnaliser les transitions
Les transitions contrôlent le 'comment' : duration, ease, type ('spring' pour rebond naturel). En 2026, priorisez springs pour UX premium (plus organique que cubic-bezier).
Transitions avancées avec springs
import { motion } from 'framer-motion';
export default function SpringCard() {
return (
<motion.div
initial={{ scale: 0, rotate: -180 }}
animate={{ scale: 1, rotate: 0 }}
transition={{
type: 'spring',
stiffness: 300,
damping: 20,
mass: 1
}}
whileHover={{
scale: 1.1,
rotate: 5,
transition: { type: 'spring', stiffness: 400 }
}}
className="w-64 h-64 bg-gradient-to-r from-green-400 to-blue-500 rounded-xl shadow-2xl flex items-center justify-center text-white font-bold text-xl cursor-pointer"
>
Spring Magic
</motion.div>
);
}Springs simulent la physique réelle : stiffness (raideur), damping (froissement). Hover override la transition globale. Copiez dans page.tsx. Résultat : rebond fluide 60fps. Piège : valeurs extrêmes causent overshoot ; tunez via Framer Motion playground.
Ajouter des gestures interactives
whileDrag, drag activent le drag&drop natif multi-touch. Parfait pour cards, sliders. Intégrez useMotionValue pour sync valeurs custom.
Composant draggable
import { motion, useMotionValue } from 'framer-motion';
export default function DragCard() {
const x = useMotionValue(0);
const y = useMotionValue(0);
return (
<motion.div
drag
dragConstraints={{ top: -50, left: -50, right: 50, bottom: 50 }}
dragElastic={0.2}
style={{ x, y }}
whileDrag={{ scale: 1.2, rotate: 10 }}
className="w-48 h-48 bg-purple-500 rounded-lg shadow-lg flex items-center justify-center text-white font-bold cursor-grab active:cursor-grabbing"
>
Glissez-moi
</motion.div>
);
}drag active le drag ; constraints limite la zone. useMotionValue tracke position pour sync (ex: parallax). dragElastic ajoute rebond. Testez touch/mobile. Piège : sans style={{x,y}}, pas de sync ; performant même sur low-end.
Animations liées au scroll
useScroll + useTransform lie animations au viewport. Ex: parallax, progress bars. motionValue pour granularité.
Effet parallax scroll
import { motion, useScroll, useTransform } from 'framer-motion';
import { useRef } from 'react';
export default function ScrollParallax() {
const ref = useRef(null);
const { scrollYProgress } = useScroll({
target: ref,
offset: ['start end', 'end start']
});
const y = useTransform(scrollYProgress, [0, 1], ['0%', '-30%]);
return (
<section ref={ref} className="h-screen flex items-center justify-center bg-gradient-to-b from-indigo-500 to-violet-600 relative overflow-hidden">
<motion.div
style={{ y }}
className="text-6xl font-black text-white drop-shadow-2xl"
>
Parallax
</motion.div>
<motion.div
style={{ opacity: useTransform(scrollYProgress, [0, 0.5, 1], [0, 1, 0]) }}
className="absolute bottom-10 left-1/2 transform -translate-x-1/2 text-white text-lg"
>
Scroll pour magie
</motion.div>
</section>
);
}useScroll tracke progress ; useTransform mappe à props (y/opacity). offset définit triggers. Ajoutez à page avec hauteur. Résultat : fond parallax fluide. Piège : target ref requis ; throttle auto pour perf.
Bonnes pratiques
- Lazy-load : Utilisez
Suspense+whileInViewpour animations off-screen. - Perf :
transformTemplatepour GPU ; limitez à 3-5 motions par frame. - Accessibilité : Intégrez
useReducedMotionviamotionValue. - Orchestration :
layoutIdpour shared layout transitions. - Tests : Snapshot avec
@testing-library/react+ mock MotionValues.
Erreurs courantes à éviter
- Re-renders infinis : Évitez
animatedansuseEffectsans deps ; utilisezuseAnimation. - Layout thrashing : Ne mélangez pas
position: relativeavec scales ; prioriseztransform. - Mobile lag : Oubliez
dragMomentum= false pour stops nets. - SSR mismatch :
initial={false}sur client-only ; utilisezAnimatePresencepour exits.
Pour aller plus loin
- Docs officielles : Framer Motion
- Exemples avancés : CodeSandbox Framer
- Vidéo tutos : YouTube "Framer Motion 2026 updates"
- Formation pro : Formations Learni Dev sur React Animations Avancées.