Animation web
Un bon mouvement web est d'abord une décision de conception, puis un appel de bibliothèque. Suivez le flux de travail ci-dessous dans l'ordre ; ne chargez les fichiers de règles que lorsqu'une étape en a besoin.
Flux de travail
1. Lire le projet avant de choisir quoi que ce soit
- Vérifiez
package.json. Si une bibliothèque d'animation est déjà installée, utilisez-la. N'en ajoutez pas une seconde pour un seul effet. - Notez le framework (React / Next.js App Router / Vue / Svelte / HTML simple) et vérifiez si les composants sont rendus sur le serveur (
"use client"nécessaire pour les animations côté client dans Next.js). - Recherchez des jetons de mouvement existants (durées, easing) dans les variables CSS ou un fichier de thème, et réutilisez-les.
2. Déterminez le rôle du mouvement
Chaque animation a besoin d'une mission. Choisissez-en une par élément :
| Mission | Exemple | Budget typique |
|---|---|---|
| Feedback — confirmer une action | pression de bouton, bascule, copier-dans-le-presse-papier | 100–200ms |
| Orientation — montrer d'où vient ou où va quelque chose | une modale s'ouvre depuis son déclencheur, réorganisation d'un élément de liste, changement de route | 200–400ms |
| Attention — pointer vers une seule chose | une unique séquence hero, une nouvelle notification | 400–1200ms, une fois |
| Narratif — raconter une histoire liée au défilement | démonstration épinglée d'un produit, chronologie défilée | lié à la distance de défilement |
Si un élément n'a pas de mission, ne l'animez pas. Un moment orchestré bat un fade-up sur chaque section. Lisez règles/conception-mouvement.md pour les durées, l'easing, la chorégraphie et la checklist "sensation premium".
3. Choisissez l'outil le plus léger qui fait le travail
Plateforme d'abord, puis bibliothèques :
| Besoin | Utilisez | Fichier de règle |
|---|---|---|
| Survol, focus, pression, boucles simples | Transitions CSS / @keyframes | css-keyframes.md |
| Entrée et sortie de dialogue, popover, menu déroulant | CSS @starting-style + transition-behavior: allow-discrete | css-keyframes.md |
| Transitions de page / route, morphing d'élément partagé entre états | API View Transitions | view-transitions.md |
| Révélation simple liée au défilement, barre de progression, parallaxe | CSS animation-timeline: view() / scroll() | animations-defilement.md |
| Sections épinglées, chronologies multi-étapes défilées, défilement horizontal | GSAP + ScrollTrigger | gsap.md |
| Révélations de titres avec texte fractionné / masque de ligne | GSAP SplitText | gsap.md |
| Animation d'entrée/sortie React, animation de mise en page et partagée, gestes | Motion pour React (motion/react) | framer-motion.md |
| Animation impérative sans framework, ressorts | Motion (motion) | motion-one.md |
| Dessin et morphing de lignes SVG sans GSAP | Anime.js v4 (svg.createDrawable, svg.morphTo) | animejs.md |
| Morphing de chemins complexes entre formes non apparentées | Flubber (ou GSAP MorphSVG) | flubber.md |
| Lecture d'animation After Effects | Lottie (dotLottie) | lottie.md |
| Animation illustrée interactive pilotée par état | Rive | rive.md |
| Graphiques animés | Transitions D3 | d3.md |
| Formes 2D interactives multiples (éditeurs, diagrammes) | Konva | konva.md |
| 3D, particules, shaders | Three.js / React Three Fiber | three-js.md |
Lorsque le choix n'est pas évident, lisez règles/choisir-bibliotheque.md.
4. Construisez avec les non-négociables
Ceci s'applique à chaque animation, dans chaque bibliothèque :
- Animez
transformetopacity. Évitez d'animerwidth,height,top,left,margin; utilisezscale/translate, FLIP (GSAP Flip, Motionlayout) ou les View Transitions pour les changements de mise en page. Voir règles/performance.md. - Respectez
prefers-reduced-motion. Remplacez le mouvement par un fondu d'opacité ou un changement instantané ; ne supprimez jamais l'entrée du contenu pour qu'il reste invisible. Les effets liés au défilement doivent devenir statiques. - Ne cachez jamais le contenu avant l'exécution de JS. Définissez l'état initial caché dans JS (ou derrière une classe
.js), afin que le contenu soit visible si le script échoue. Avec SSR, évitez un flash de contenu visible puis caché en appliquant les styles initiaux avant le premier affichage. - Nettoyez. Revenez en arrière ou tuez les animations lors du démontage (
useGSAP,createScope().revert(),gsap.context), et tuez les ScrollTriggers lors d'un changement de route. - Gardez l'interaction réactive. Animations interruptibles pour tout ce qui est déclenché par l'utilisateur : un deuxième clic ne doit pas s'empiler derrière le premier. Ne bloquez jamais l'entrée en attendant la fin d'une animation.
- N'animez pas le focus loin. Les éléments qui se déplacent doivent conserver un état
:focus-visiblevisible, et les dialogues animés doivent toujours déplacer le focus correctement.
5. Vérifiez dans un vrai navigateur
Ne signalez pas une animation comme terminée en lisant le code. Exécutez-la et vérifiez :
- Elle se joue, et l'état final correspond à la conception (capture d'écran au milieu et au repos).
- Aucune erreur dans la console, aucun décalage de mise en page lors du démarrage.
- Émulez
prefers-reduced-motion: reduceet confirmez que la version réduite fonctionne et que le contenu est visible. - Redimensionnez à une largeur mobile : les sections épinglées et le texte fractionné fonctionnent toujours (re-fractionnement lors du redimensionnement).
- Les effets liés au défilement fonctionnent aussi bien en défilant vers le haut que vers le bas, et après un rechargement en milieu de page.
- Panneau des performances : aucune trame longue pendant l'animation, aucun pic de mise en page/peinture dû aux propriétés animées.
Points de départ minimaux
// GSAP + ScrollTrigger (npm i gsap)
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
gsap.from(".card", {
y: 40, opacity: 0, duration: 0.8, ease: "expo.out", stagger: 0.08,
scrollTrigger: { trigger: ".cards", start: "top 80%" },
});
// Motion pour React (npm i motion)
import { motion, AnimatePresence } from "motion/react";
<AnimatePresence>
{open && (
<motion.div
key="panel"
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 8 }}
transition={{ type: "spring", duration: 0.35, bounce: 0 }}
/>
)}
</AnimatePresence>
/* Révélation au défilement uniquement via la plateforme : Chrome 115+, Safari 26+, Firefox 159+ */
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: view()) {
.reveal {
animation: reveal linear both;
animation-timeline: view();
animation-range: entry 10% cover 30%;
}
}
}
@keyframes reveal { from { opacity: 0; translate: 0 2rem; } }
Fichiers de règles
- règles/conception-mouvement.md — durées, easing, chorégraphie, ce qui rend le mouvement premium
- règles/choisir-bibliotheque.md — flux de décision, matrice de capacités, tailles de bundle mesurées
- règles/performance.md — propriétés uniquement pour le compositeur, profilage,
will-change, mouvement réduit - règles/animations-defilement.md — timelines de défilement CSS, motifs ScrollTrigger, défilement fluide
- règles/view-transitions.md — transitions de page dans le même document et entre documents
- règles/css-keyframes.md — transitions,
@keyframes,@starting-style, easinglinear() - règles/gsap.md — timelines, ScrollTrigger, SplitText, Flip,
useGSAP - règles/framer-motion.md — Motion pour React : variantes,
AnimatePresence, mise en page, gestes - règles/motion-one.md — Motion vanilla JS :
animate, séquences,scroll,inView - règles/animejs.md — Anime.js v4 : timelines, stagger, dessin et morphing SVG
- règles/lottie.md — lecteur dotLottie, contrôles, événements
- règles/rive.md — machines d'état et entrées
- règles/d3.md — transitions de jointure de données
- règles/flubber.md — morphing de chemins
- règles/konva.md — formes 2D canvas et tweens
- règles/three-js.md — scènes, R3F, performance
Des exemples fonctionnels de ces techniques se trouvent dans demos/.