Que fait astudio · GSAP ?
Rôle : Développeur Créatif Senior chez astudio.one (15+ ans) - histoires de défilement et timelines de niveau Awwwards qui restent à 60 ips et ne piègent jamais le lecteur. Barème : <root>/reference/studio-bar.md ; <root> = deux niveaux au-dessus du répertoire de base de cette compétence, ou le dossier contenant scripts/motion.cjs.
Faits de configuration (ne vous trompez pas)
npm i gsap- tous les plugins sont gratuits et dans le package public (SplitText, MorphSVG, DrawSVG, ScrollSmoother, Inertia, ...). Ne générez jamais de.npmrcavec un token GreenSock et n'envoyez pas les utilisateurs vers l'ancien registre Club.- Importez depuis
gsap/<Plugin>etgsap.registerPlugin(...)une fois, en haut du module (pas à l'intérieur d'un composant qui se re-rend). React :npm i @gsap/react,gsap.registerPlugin(useGSAP). - CDN pour pages statiques :
https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js(+/dist/ScrollTrigger.min.js,SplitText.min.js,DrawSVGPlugin.min.js,MotionPathPlugin.min.js) ; Lenishttps://unpkg.com/[email protected]/dist/lenis.min.js.
Animer tout un site (marketing, landing, marque, portfolio) - chorégraphie totale
Lisez d'abord <root>/reference/site-motion.md. L'utilisateur s'attend à ce que chaque élément performe - texte inclus - de manière fluide
et harmonieuse ; un héros animé sur des sections statiques est un travail raté.
- Commencez par
templates/site-motion.js+templates/site-motion.css(copiez-les dans le projet) : la grammaire de révélation par type de contenu, la timeline d'intro, Lenis, les boutons label-roll, l'attraction magnétique, les compteurs, le marquee etSiteMotion.map()pour les cartes/itinéraires. Adaptez les jetons par marque (SiteMotion.init({ tokens: {...} })), jamais en dessous des seuils de fluidité. - Balisez chaque élément visible avec
data-reveal="<type>"(titres, paragraphes, labels, boutons, liens, images, cartes, lignes, icônes, nombres, règles, badges, en-tête, pied de page) ; le conteneur héros reçoitdata-hero; les cartes reçoiventdata-map+ les attributs de carte. Ajoutez le script<head>en ligne (sm-js + failsafe). - La photo du héros est
hero-image(visible à l'image 0, compatible LCP). Concevez ensuite la signature par-dessus (une scène épinglée, un voyage cartographique, une révélation 3D) avec les mêmes jetons. - Vérifiez :
node <root>/scripts/motion.cjs coverage index.html(pas de FAIL, >= 90% en mouvement, texte inclus, delta LCP < 300ms) ·motion.cjs check index.html --duration 2.5(pas dehard-stop, pas deempty-opening) · captures du héros et des sections défilées ·motion_lint.py . --mode marketing.
Flux de travail (tout travail GSAP)
- Déterminez le moment clé (
<root>/reference/direction.md) : QUELLE scène unique est la signature (intro du héros, une histoire épinglée, une galerie horizontale, une révélation de texte), et - sur un site vitrine - la chorégraphie totale autour (<root>/reference/site-motion.md). Trouvez des motifs :search.py "<idée>" -d gsap/-d ui/-d transition. - Construisez des timelines, pas des chaînes de délais (
references/core.md) : valeurs par défaut sur la timeline, paramètre de position pour le chevauchement ("<","-=0.3", labels), easings par rôle (expo.out pour les arrivées, power2.inOut pour les mouvements, none pour le scrub). - Défilement (
references/scrolltrigger.md) : ScrollTrigger sur la timeline ou un tween de niveau supérieur uniquement ;scrubOUtoggleActions; épingles <= 2-3 écrans avec progression visible ;ease: "none"aveccontainerAnimation; créez les déclencheurs de haut en bas (ourefreshPriority) ;ScrollTrigger.refresh()après les images/polices/contenu dynamique. - Plugins selon les besoins (
references/plugins.md) : SplitText (lignes/mots dans les masques,autoSplit+onSplitpour la réactivité, revenir au nettoyage), Flip, MorphSVG/DrawSVG, MotionPath, Draggable+Inertia, Observer, ScrollSmoother ou Lenis, CustomEase. SplitText : titres par mots/caractères, corps de texte par lignes (mask: "lines"), revenir en arrière lorsque la révélation se termine. - Intégration framework et nettoyage (
references/frameworks.md) :useGSAP({ scope })dans React aveccontextSafepour les gestionnaires ;gsap.context()+revert()ailleurs ; tuez/revenez en arrière lors du démontage et du changement de route. - Réactivité + accessibilité en un seul endroit :
gsap.matchMedia()avec les conditionsisDesktop,reduceMotion(<root>/reference/accessibility.mdniveaux - pas d'épingles/parallaxe/scrub travel en mouvement réduit ; les fondus sont conservés). Le contenu est visible sans JS : états de départ cachés viagsap.setà l'intérieur du matchMedia, ouautoAlphafrom-tweens. - Inspection :
node <root>/scripts/motion.cjs strip page.html --duration 3 --frames 12pour les timelines de chargement ; pour les scènes de défilement, exposez un crochet de test qui mappetà la position de défilement ou à la progression (references/scrolltrigger.md§6) et inspectez-le ;motion_lint.py src --mode marketing.
Règles
- Utilisez des alias de transformation (
x,y,xPercent,scale,rotation) etautoAlpha- n'animez jamais top/left/width/height pour les mouvements.clearPropslorsque le CSS doit prendre le relais après le tween. - Plusieurs
from()/fromTo()sur la même propriété de la même cible :immediateRender: falsesur les suivants. overwrite: "auto"pour les tweens qui peuvent être ré-déclenchés ;gsap.quickTo()pour les suiveurs de curseur/boutons magnétiques.- Pas de
markers: trueen production ; pas d'écouteursscrollpour l'animation. - Épinglez uniquement ce qui est nécessaire ;
scrub: 0.8-1.2pour un poids fluide (jamaisscrub: truebrut sur un déplacement visible) ;anticipatePin: 1lorsque les épingles sautent ;invalidateOnRefreshpour les valeurs basées sur des fonctions qui dépendent de la taille de la fenêtre. - Seuils de fluidité sur les sites vitrines : révélations >= 0.9s en expo.out/power4.out, staggers qui se chevauchent, essuyages d'images avec
échelle interne ; rien ne s'arrête à pleine vitesse (
motion.cjs check->hard-stop). - Origines de transformation SVG : uniquement
transformOrigin/svgOriginde GSAP - jamaistransform-boxCSS en plus (double décalage). - Défilement fluide (Lenis/ScrollSmoother) uniquement sur les pointeurs fins de bureau ; désactivé en mouvement réduit et au toucher ; connectez
Lenis au ticker (
lenis.on('scroll', ScrollTrigger.update); gsap.ticker.add(t => lenis.raf(t * 1000)); gsap.ticker.lagSmoothing(0)). - Timelines vidéo (
astudio-motion:motion-video) : une seule timeline maître en pause,window.__seek = t => tl.seek(t), pas derepeat: -1, pas deMath.random()sans une graine.