--- name: motion-spring-physics description: >- Implement physical, tactile micro-interactions and layout transitions using Spring Physics (Motion / Framer Motion, FLIP technique via layoutId, CSS @starting-style, View Transitions API) with strict compliance with prefers-reduced-motion. --- # Motion & Spring Physics Architecture Ce skill régit l'animation interactive haute fidélité. Il remplace les animations rigides basées sur des durées fixes (`transition: all 0.3s ease`) par des **ressorts physiques réels** (*Spring Physics*), conférant aux interfaces un toucher organique, réactif et interruptible caractéristique des applications comme Linear, Raycast ou macOS. --- ## 🎯 Déclencheurs d'Activation Activez ce skill dès que : 1. Vous animez des éléments interactifs (boutons, modales, tiroirs, onglets, menus accordéons). 2. Vous concevez des transitions d'état de liste ou de réorganisation (glisser-déposer, suppression, filtrage). 3. Vous implémentez un indicateur de sélection flottant ou un curseur d'onglets partagé (`layoutId`). 4. Vous créez des micro-interactions au survol ou à la pression tactile (`whileHover`, `whileTap`). 5. Vous devez garantir l'accessibilité des animations face au critère WCAG 2.3.3 (`prefers-reduced-motion`). --- ## 🏎️ 1. Les Principes de la Physique de Ressort (*Springs*) Contrairement aux courbes de Bézier cubiques (`ease-in-out`) qui forcent un temps fixe indépendamment de la distance parcourue, un ressort physique calcule la trajectoire en temps réel : - **Stiffness (Raideur)** : Vitesse de rappel du ressort. Une raideur élevée (300–500) rend le contrôle vif et immédiat. - **Damping (Amortissement)** : Friction qui freine le mouvement. Un amortissement bien réglé (20–30) évite les oscillations oscillatoires excessives (« effet cartoon »). - **Mass (Masse)** : Inertie de l'élément (0.5 à 1.0 par défaut). ### Les 3 Profils de Ressort Standards | Profil | Cas d'Usage | Paramètres Recommandés | | :--- | :--- | :--- | | **Snappy / Micro-tactile** | Boutons, toggles, badges, chips, icones | `{ type: 'spring', stiffness: 500, damping: 30, mass: 0.5 }` | | **Smooth / Layout** | Modales, volets latéraux, accordéons, cartes | `{ type: 'spring', stiffness: 350, damping: 28, mass: 0.8 }` | | **Gentle / Page Transition** | Entrées de page, vues séquentielles | `{ type: 'spring', stiffness: 200, damping: 24, mass: 1.0 }` | --- ## 💫 2. Transitions Partagées avec `layoutId` (Technique FLIP) Pour un indicateur d'onglet ou un sous-lignage qui glisse d'un bouton à l'autre sans saut visuel : ```tsx import { motion } from 'framer-motion'; import { useState } from 'react'; const tabs = ['Vue d\'ensemble', 'Analytique', 'Paramètres']; export const TabNavigation = () => { const [activeTab, setActiveTab] = useState(tabs[0]); return ( ); }; ``` --- ## ♿ 3. Respect Impératif de `prefers-reduced-motion` Chaque animation doit se désactiver instantanément pour les utilisateurs sensibles au mal des transports ou ayant activé la réduction de mouvement dans leur OS : ```tsx import { motion, useReducedMotion } from 'framer-motion'; export const AccessibleCard = ({ children }: { children: React.ReactNode }) => { const shouldReduceMotion = useReducedMotion(); return ( {children} ); }; ``` --- ## 🎨 4. Alternatives CSS Modernes (Sans Dépendance JS) Pour les transitions simples au chargement d'éléments, privilégiez `@starting-style` et la View Transitions API : ```css /* Entrée fluide pure CSS d'un dialog ou popover */ dialog[open] { opacity: 1; transform: scale(1); transition: opacity 0.2s ease-out, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), display 0.2s allow-discrete; } @starting-style { dialog[open] { opacity: 0; transform: scale(0.96); } } ``` --- ## 📋 Checklist de Conformité Motion - [ ] Aucun mouvement décoratif continu en boucle (pas de floating infini qui distrait). - [ ] Les micro-interactions au clic utilisent `active:scale-[0.98]` ou un ressort réactif. - [ ] `useReducedMotion()` (ou la media query `@media (prefers-reduced-motion: reduce)`) ramène la durée à 0. - [ ] Les animations de changement de layout (`layoutId`) ne causent aucun reflow de texte brutal. - [ ] La performance d'animation cible 60fps/120fps en animant exclusivement `transform` et `opacity`.