Architecte de Systèmes d'Animation
Construisez des systèmes d'animation performants et accessibles en utilisant Framer Motion, GSAP, l'API View Transitions et la physique des ressorts pour des expériences UI fluides.
Déclencheurs d'Activation
Activer sur : transitions de pages, animations de mise en page, animations déclenchées par défilement, micro-interactions, physique des ressorts, motion.div, gsap.to, View Transition API, transitions d'éléments partagés, animations de listes décalées.
PAS pour : les effets de survol/focus uniquement CSS -- utilisez css-in-js-architect. Le rendu Canvas/WebGL -- utilisez creative-coding-expert. La lecture de fichiers Lottie -- utilisez l'intégration Lottie standard.
Démarrage Rapide
- Choisissez votre moteur -- Framer Motion pour React déclaratif, GSAP pour les lourdes timelines ou React, API View Transitions pour la navigation entre pages.
- Animez uniquement les transformations et l'opacité -- ces propriétés s'exécutent sur le thread du compositeur (GPU), évitant les à-coups de mise en page.
- Utilisez
will-changeavec parcimonie -- uniquement sur les éléments sur le point d'être animés, supprimez-le après la fin de l'animation. - Respectez
prefers-reduced-motion-- désactivez ou simplifiez toutes les animations pour les utilisateurs qui le demandent. - Profitez avec DevTools -- onglet Performance > vérifiez les décalages de mise en page pendant les animations.
Capacités Principales
| Domaine | Technologies | Patrons Clés |
|---|---|---|
| React Déclaratif | Framer Motion 11+, composants motion | Animations de mise en page, AnimatePresence, variantes |
| Animation par Timeline | GSAP 3.12+, ScrollTrigger | Séquences basées sur le défilement, épinglage, scrutation |
| Transitions de Pages | API View Transitions, useViewTransition de Next.js | Transitions d'éléments partagés entre pages |
| Physique des Ressorts | Ressorts Framer Motion, react-spring | Assouplissement naturel, animations interruptibles |
| Micro-interactions | Transitions CSS + Framer Motion | Retour de bouton, états de survol, indicateurs de chargement |
| Basé sur le Défilement | CSS animation-timeline: scroll(), GSAP ScrollTrigger | Parallax, indicateurs de progression, révélation au défilement |
Patrons d'Architecture
Patron 1 : Animations de Mise en Page Framer Motion
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 // anime les changements de position
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>
);
}
Patron 2 : API View Transitions pour la Navigation de Page
// 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>;
}
/* Transitions d'éléments partagés via 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;
}
Patron 3 : Respect du Mouvement Réduit
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 }
}
>
Contenu
</motion.div>
);
}
┌─ Arbre de Décision d'Animation ─────────────────┐
│ │
│ prefers-reduced-motion? │
│ ├── OUI → fondu d'opacité instantané (pas de mouvement)
│ └── NON → animation complète ressort/transformation
│ │
│ Qu'est-ce qui est animé ? │
│ ├── transform/opacity → compositeur GPU (bon) │
│ ├── width/height → à-coup de mise en page (éviter)
│ └── box-shadow → peinture uniquement (acceptable) │
└───────────────────────────────────────────────────┘
Anti-patrons
- Animer
width,height,top,left-- déclenche un recalcul de mise en page à chaque image. Utilisez plutôttransform: translate/scalepour 60 ips. will-changesur chaque élément -- promeut trop de couches vers le GPU, augmentant l'utilisation de la mémoire. Appliquez uniquement aux éléments sur le point d'être animés.- Ignorer
prefers-reduced-motion-- les utilisateurs sensibles au mouvement peuvent ressentir des nausées ou des crises d'épilepsie. Vérifiez et respectez toujours cette requête média. - Durée d'animation > 500 ms pour les micro-interactions -- rend l'UI lente. Gardez les retours de bouton/survol sous 200 ms, les transitions de page sous 400 ms.
- Animer pendant le défilement sans
requestAnimationFrameou ScrollTrigger -- provoque des à-coups. Utilisez GSAP ScrollTrigger ou CSSanimation-timeline: scroll()pour les animations basées sur le défilement.
Checklist Qualité
- Toutes les animations utilisent
transformetopacity(propriétés compatibles compositeur) -
prefers-reduced-motionrespecté avecuseReducedMotionou requête média CSS - Micro-interactions sous 200 ms, transitions de page sous 400 ms
-
AnimatePresenceutilisé pour les animations de montage/démontage - Les animations de mise en page utilisent la propriété
layoutde Framer Motion (pas de calcul de position manuel) -
will-changeappliqué uniquement pendant l'animation, supprimé après - Pas d'à-coups dans le panneau Performance des DevTools Chrome (pas d'images longues > 16 ms)
- Les animations sont interruptibles (physique des ressorts, pas d'images clés fixes avec
ease) - L'API View Transitions a un repli pour les navigateurs non supportés
- Les animations basées sur le défilement utilisent
animation-timelineou ScrollTrigger (pas d'écouteurs d'événement de défilement)