Sauter au contenu

Cours 05 - Animations par défilement

À l’image de useGSAP, ScrollTrigger est un plugin de GSAP devant passer par l’étape de l’inscription avant d’être utilisé.

import gsap from 'gsap';
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { useGSAP } from "@gsap/react";
gsap.registerPlugin(ScrollTrigger, useGSAP);

Ce module permet de déclencher ou contrôler des animations en fonction de défilement de la page.

On peut ainsi:

Lancer une animation à l’arrivée d’un l’élément à l’écran

Section intitulée « Lancer une animation à l’arrivée d’un l’élément à l’écran »

La propriété scrollTrigger peut autant être déclarée sur l’objet gsap ou sur un timeline ou être créée directement avec ScrollTrigger.create. On la crée ainsi lorsque l’animation sera effectuée à partir du onUpdate.

On désigne l’élément ciblé pour démarrer l’animation avec sa proriété trigger. L’animation sera démarrée dès que ce dernier sera dans le viewport.

gsap.to(elementRef.current, {
scrollTrigger: {
trigger: 'selecteurCSS ou ref',
},
x: 100,
duration: .3,
// ...
});

Il est également possible d’être plus précis en désignant à partir de quel endroit la cible doit être positionnée dans le viewport pour démarrer l’animation (ou la timeline) avec la propriété start:

gsap.to(elementRef.current, {
scrollTrigger: {
trigger: 'selecteurCSS ou ref',
// le haut de l'élément trigger
// doit être au 2/3 du viewport pour démarrer l'animation
// (l'origine étant en haut à gauche)
start: "top 66%",
},
x: 100,
duration: .3,
// ...
});

Décrit un point du trigger et un point du viewport (par défaut) qui doivent se rencontrer:

  • "top center": quand le haut du trigger touche le centre du viewport
  • "bottom 80%" : quand le bas du trigger atteint 80% de la hauteur du viewport
  • Pourcentages : "80%"
  • Pixels : "100px"

"top bottom-=100px": quand le haut du trigger arrive 100px au-dessus du bas du viewport

Valeur exacte de scroll en pixels.

Exemple : 200 → déclenche à 200px de défilement

Une fonction qui retourne une chaîne de caractères ou un nombre (pour un calcul dynamique).

  • Appelée lors de la création ou au redimensionnement du scroller
  • Reçoit l’instance self en paramètre Exemple :
start: self => self.previous().end

Animation par le défilement (plutôt que par le temps)

Section intitulée « Animation par le défilement (plutôt que par le temps) »

Plutôt que de faire jouer l’animation à l’arrivée de l’élément trigger au bon endroit dans le viewport, on peut aussi évoluer l’animation par le défilement.

  • L’animation démarrera au point de départ défini par start et sera échelonnée jusqu’au point de défilement d’arrivé défini par la propriété end (obligatoire ici).
  • Plus l’espace entre start et end est grand, plus “lente” sera l’animation.
  • Un endTrigger peut également être fourni s’il est désiré que la présence d’un autre élément dans le viewport interrompe l’animation.
  • On utilise enfin scrub:true afin d’activer le comportement désiré
gsap.to(elementRef.current, {
scrollTrigger: {
trigger: 'selecteurCSS ou ref',
start: "top 66%",
// l'animation se termine quand le bas du trigger se trouve à la moitié du viewport + 100px
end: "bottom 50%+=100px",
scrub: true,
},
x: 100,
// ...
});

Afin de rendre le défilement plus doux et moins saccadé, il peut être utile d’utiliser une librairie comme lenis ou Locomotive Scroll (basé sur Lenis) qui génèrent de l’interpolation entre les étapes du scroll.

Enfin, pour permettre à l’élément trigger de rester “collé” au viewport, on utilise la propriété pin:true.

  • L’élément y adhérera jusqu’à ce que la position de la propriété end soit atteinte.
  • Il faut éviter d’animer le même élément que celui qui est collé au viewport pour éviter de nuire aux différents calculs.
  • En réalité, l’élément est positionné en fixed et un spacer est ajouté pour éviter que le reste du html remonte sous l’élément.
gsap.to(elementRef.current, {
scrollTrigger: {
trigger: 'selecteurCSS ou ref',
start: "top 66%",
// l'animation se termine quand le bas du trigger se trouve à la moitié du viewport + 100px
end: "bottom 50%+=100px",
pin: true,
pingSpacing: true // true par défaut, permet d'éviter le spacing généré par gsap
},
x: 100,
// ...
});

Il existe également certains outils disponibles avec GSAP afin de faciliter le développement:

  • gsap.utils.toArray: L’équivalent de document.querySelectorAll, mais qui retourne un tableau plutôt qu’un NodeList. Peut donc être utilisé avec les méthodes de tableau courrantes et être aussi utilisé directement dans une fonction d’animation gsap. Utilse pour donner des valeurs spécifiques d’animation à chaque élément du tableau.
  • gsap.utils.clamp: Permet de limiter une valeur à une limite minimale/maximale:
  • gsap.utils.mapRange: Permet de transposer une valeur d’une range vers un autre.
  • gsap.utils.random: Permet d’obtenir des valeurs aléatoires numériques ou depuis un tableau de valeurs.
  • gsap.utils.interpolate: Équivalent du lerp dans Unity, permet de récupérer une valeur interpolée entre un min et un max (fonctionne avec des nombres et des couleurs).
// strings
gsap.utils.interpolate("20px", "40px", 0.5); // "30px"
//colors
gsap.utils.interpolate("red", "blue", 0.5); // "rgba(128,0,128,1)"
  • gsap.parseEase: Permet de récupérer la valeur correspondant à une courbe d’accélération à un point précis (entre 0 et 1).

    À utiliser en combinaison avec gsap.utils.interpolate et gsap.set pour animer un élément manuellement dans un onUpdate.

const value = gsap.parseEase("power2.out")(.5);
gsap.to(".class", {
//nombre aléatoire entre -100 et 100 pour chaque élément .class
//par sauts de 5
x:"random(-100, 100, 5)"
});
// nombre aléatoirement choisi parmi 0, 100, 200 ou 500
gsap.to(".class", {
x:"random([0, 100, 200, 500])"
});
  • gsap.shuffle: Permet de brasser des valeurs dans un tableau.
  • gsap.matchMedia(): Permet de déclarer des animations pour des media queries précises.

Autre fonction utile (n’appartenant pas à gsap):

const isMobile = window.matchMedia('(max-width: 1000px)').matches; // retourne un booléen