iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
JavaScript · Intermédiaire

GSAP

Maîtriser GSAP de zéro : tweens, timelines, ScrollTrigger, plugins et intégration React/Next.js pour créer des animations web professionnelles.

GSAPJavaScriptReactNext.jsScrollTrigger
01Introduction à GSAP02Tweens : to, from, fromTo03Timelines04ScrollTrigger05Stagger, utils et matchMedia06GSAP dans React et Next.js07Plugins et techniques avancées
Chapitre 5·20 min

Stagger, utils et matchMedia

Trois fonctionnalités souvent sous-utilisées mais qui font la différence entre des animations basiques et des animations soignées.

Stagger

Stagger anime plusieurs éléments en décalant chacun dans le temps. C'est la façon correcte d'animer des listes, des grilles, des menus.

Forme simple

gsap.from('.card', {
  y: 40,
  opacity: 0,
  duration: 0.6,
  stagger: 0.1,  // 0.1s de décalage entre chaque élément
})

Chaque .card démarre 0.1s après la précédente. 10 cartes = la dernière démarre à 0.9s.

Forme objet — contrôle avancé

gsap.from('.card', {
  y: 40,
  opacity: 0,
  duration: 0.6,
  stagger: {
    amount: 0.8,       // durée totale répartie sur tous les éléments
    from: 'start',     // ordre : 'start' | 'end' | 'center' | 'random' | index
    ease: 'power1.in', // ease sur le stagger lui-même
    grid: 'auto',      // pour les grilles — calcule les distances 2D
  },
})

amount vs valeur directe :

  • stagger: 0.1 = 0.1s entre chaque élément (dépend du nombre d'éléments)
  • stagger: { amount: 0.8 } = 0.8s total réparti sur tous les éléments (indépendant du nombre)

amount est préférable quand le nombre d'éléments varie — l'animation prend toujours le même temps total.

from : point de départ du stagger

// Depuis le centre — effet "explosion vers l'extérieur"
stagger: { amount: 0.6, from: 'center' }
 
// Depuis un index précis
stagger: { amount: 0.6, from: 3 }  // l'élément 3 en premier
 
// Aléatoire — bonne surprise visuelle
stagger: { amount: 0.6, from: 'random' }

Stagger sur une grille

Pour une grille, le stagger peut prendre en compte la position 2D de chaque élément :

// 6 colonnes, 4 lignes
gsap.from('.grid-item', {
  scale: 0,
  opacity: 0,
  duration: 0.5,
  stagger: {
    amount: 1,
    grid: [4, 6],      // [rows, columns]
    from: 'center',    // depuis le centre de la grille
    ease: 'power2.out',
  },
})

Avec grid: 'auto', GSAP calcule la grille lui-même à partir des positions DOM.

gsap.utils

gsap.utils est une collection d'utilitaires mathématiques souvent nécessaires dans les animations.

clamp

Contraint une valeur entre un min et un max.

const clamp = gsap.utils.clamp(0, 100)
clamp(150)  // 100
clamp(-20)  // 0
clamp(50)   // 50

Utile pour normaliser des valeurs de scroll ou de pointeur.

mapRange

Mappe une valeur d'une plage vers une autre.

const mapper = gsap.utils.mapRange(0, 1000, 0, 100)
mapper(500)   // 50
mapper(250)   // 25
mapper(1000)  // 100

Cas d'usage courant : convertir une position de scroll en pourcentage d'animation.

window.addEventListener('mousemove', (e) => {
  const normalized = gsap.utils.mapRange(0, window.innerWidth, -20, 20)
  const rotation = normalized(e.clientX)
  gsap.to('.card', { rotation, duration: 0.4, ease: 'power1.out' })
})

interpolate

Interpole entre deux valeurs selon un progrès (0 à 1).

const lerp = gsap.utils.interpolate('#ff0000', '#0000ff')
lerp(0)    // '#ff0000'
lerp(0.5)  // couleur intermédiaire
lerp(1)    // '#0000ff'

Fonctionne avec les nombres, couleurs, objets, et tableaux.

toArray

Convertit n'importe quoi en tableau — pratique pour normaliser les inputs.

gsap.utils.toArray('.card')           // NodeList → Array
gsap.utils.toArray(someElement)       // Element → [Element]
gsap.utils.toArray([el1, el2])        // Array → Array (inchangé)

Utile dans les fonctions qui acceptent un sélecteur ou un tableau d'éléments.

shuffle

Mélange un tableau en place.

const items = gsap.utils.toArray('.card')
gsap.utils.shuffle(items)
gsap.from(items, { y: 30, opacity: 0, stagger: 0.08 })

snap

Contraint une valeur au multiple le plus proche.

const snap = gsap.utils.snap(90)
snap(100)  // 90
snap(140)  // 90
snap(145)  // 180
 
// Snap à une valeur d'un tableau
const snapTo = gsap.utils.snap([0, 100, 200, 300])
snapTo(80)   // 100
snapTo(250)  // 300

Utile pour des sliders ou des carousels qui s'accrochent à des positions précises.

matchMedia — animations responsive

gsap.matchMedia() permet de définir des animations différentes selon la taille d'écran, et de les nettoyer automatiquement quand la media query ne s'applique plus.

const mm = gsap.matchMedia()
 
mm.add('(min-width: 768px)', () => {
  // Animations desktop
  gsap.from('.hero-text', {
    x: -100,
    opacity: 0,
    duration: 1,
  })
 
  gsap.from('.hero-image', {
    x: 100,
    opacity: 0,
    duration: 1,
  })
 
  // La fonction retournée est appelée au cleanup
  return () => {
    // nettoyage si nécessaire
  }
})
 
mm.add('(max-width: 767px)', () => {
  // Animations mobile — différentes ou désactivées
  gsap.from('.hero-text', {
    y: 40,
    opacity: 0,
    duration: 0.7,
  })
  // Pas d'animation sur hero-image en mobile
})

Quand la fenêtre passe d'une résolution à une autre, GSAP annule automatiquement les animations de la media query inactive et applique la nouvelle. Plus besoin de gérer ça à la main.

Conditions multiples

mm.add({
  isDesktop: '(min-width: 1024px)',
  isTablet: '(min-width: 768px) and (max-width: 1023px)',
  isMobile: '(max-width: 767px)',
  prefersReducedMotion: '(prefers-reduced-motion: reduce)',
}, (context) => {
  const { isDesktop, isMobile, prefersReducedMotion } = context.conditions
 
  if (prefersReducedMotion) {
    // Pas d'animations, ou animations très réduites
    return
  }
 
  if (isDesktop) {
    gsap.from('.hero', { x: -200, duration: 1.2 })
  } else if (isMobile) {
    gsap.from('.hero', { y: 40, duration: 0.7 })
  }
})

prefers-reduced-motion

Toujours vérifier cette préférence utilisateur. Les personnes sensibles au mouvement peuvent configurer leur OS pour réduire les animations.

mm.add('(prefers-reduced-motion: no-preference)', () => {
  // Toutes vos animations ici
  // Elles ne s'activent que si l'utilisateur n'a pas demandé la réduction de mouvement
  const tl = gsap.timeline({ ... })
  // ...
})

C'est la façon la plus propre de respecter cette préférence — une seule condition englobe toutes vos animations.

gsap.context() — ancêtre de useGSAP

gsap.context() permet de scoper des animations à un conteneur DOM et de les nettoyer facilement.

const ctx = gsap.context(() => {
  // Toutes les animations ici sont associées au contexte
  gsap.from('.box', { y: 30, opacity: 0 })
  gsap.from('.title', { x: -20, opacity: 0 })
}, containerElement)  // scoped à containerElement
 
// Nettoyer toutes les animations du contexte
ctx.revert()

revert() annule toutes les animations ET remet les éléments à leur état d'origine (avant que GSAP les modifie). C'est plus propre que kill() qui arrête sans remettre en place.

En React, useGSAP wrape gsap.context() — c'est couvert au chapitre suivant.


Stagger, utils et matchMedia permettent d'écrire des animations robustes, précises, et respectueuses des préférences utilisateur. Le chapitre suivant couvre l'intégration dans React et Next.js — avec les pièges propres aux frameworks.

Précédent
ScrollTrigger
Suivant
GSAP dans React et Next.js

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main