Animer du texte avec GSAP
GSAP (GreenSock Animation Platform) est une bibliothèque JavaScript puissante pour créer des animations fluides et performantes. Cette solution permet d'animer du texte lettre par lettre avec un effet de rotation 3D au scroll.
Installation
Dans le <head></head>
Ajoutez les scripts GSAP dans le <head> de votre fichier theme.liquid :
<!-- Gsap -->
<script src="https://unpkg.com/gsap@3/dist/gsap.min.js"></script>
<!-- Gsap : scroll detect -->
<script src="https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js"></script>CSS
Dans moon-moon.css
Ajoutez ces styles dans votre fichier CSS global :
/* Anims --------------------------- */
.mm-anim-gsap {
position: relative;
white-space: nowrap;
}
.mm-anim-gsap .letter {
display: inline-block;
transform-origin: bottom;
transform: rotateX(-90deg);
opacity: 0;
}JavaScript
Dans mm-global.js
Ajoutez ce code dans votre fichier JavaScript global :
gsap.registerPlugin(ScrollTrigger); // ScrollTrigger nous permet de detecter la position du scroll et déclancher les anims au bon moment
// On découpe les textes en lettres pour animer chaque lettre indépendamment
document.querySelectorAll('.mm-anim-gsap').forEach(element => {
element.innerHTML = element.textContent.replace(/\S/g, "<span class='letter'>$&</span>");
})
// Setup de l'anim sur tous les éléments ayant la classe '.mm-anim-gsap'
document.querySelectorAll('.mm-anim-gsap').forEach(element => {
gsap.to(element.querySelectorAll(".letter"), {
scrollTrigger: {
trigger: element,
start: 'top bottom', // Déclenche l'animation lorsque le haut de l'élément atteint le bas du viewport
once: true // Assure que l'animation n'est exécutée qu'une seule fois
},
duration: 1.3, // Durée de l'anim
rotateX: [0, 0], // Comportement de l'anim (ici, les lettres pivotent vers le haut)
opacity: 1, // Comportement de l'anim (ici, les lettres passent de l'opacité 0 à 1)
delay: (i) => i * 0.045,
ease: "power2.out"
});
});Utilisation
Il ne reste plus qu'à mettre la classe mm-anim-gsap sur les textes que vous souhaitez animer !
Exemple HTML
<h1 class="mm-anim-gsap">Mon titre animé</h1>
<p class="mm-anim-gsap">Ce paragraphe sera également animé lettre par lettre.</p>Explication du code
Découpage en lettres
element.innerHTML = element.textContent.replace(/\S/g, "<span class='letter'>$&</span>");Cette ligne :
- Récupère le texte de l'élément (
textContent) - Remplace chaque caractère non-blanc (
/\S/g) par un<span class='letter'>contenant ce caractère - Permet d'animer chaque lettre indépendamment
ScrollTrigger
scrollTrigger: {
trigger: element,
start: 'top bottom',
once: true
}trigger: L'élément qui déclenche l'animationstart: 'top bottom': L'animation se déclenche quand le haut de l'élément atteint le bas du viewportonce: true: L'animation ne se joue qu'une seule fois
Animation des lettres
rotateX: [0, 0], // De rotateX(-90deg) à rotateX(0deg)
opacity: 1, // De opacity: 0 à opacity: 1
delay: (i) => i * 0.045, // Délai progressif pour chaque lettre
ease: "power2.out" // Courbe d'animationVariantes d'animation
Animation de bas en haut (fade + translateY)
gsap.to(element.querySelectorAll(".letter"), {
scrollTrigger: {
trigger: element,
start: 'top bottom',
once: true
},
duration: 1,
y: 0, // De y: 50 à y: 0
opacity: 1,
delay: (i) => i * 0.03,
ease: "power2.out"
});CSS correspondant :
.mm-anim-gsap .letter {
display: inline-block;
transform: translateY(50px);
opacity: 0;
}Animation de gauche à droite
gsap.to(element.querySelectorAll(".letter"), {
scrollTrigger: {
trigger: element,
start: 'top bottom',
once: true
},
duration: 0.8,
x: 0, // De x: -20 à x: 0
opacity: 1,
delay: (i) => i * 0.02,
ease: "back.out(1.7)"
});CSS correspondant :
.mm-anim-gsap .letter {
display: inline-block;
transform: translateX(-20px);
opacity: 0;
}Animation avec scale
gsap.to(element.querySelectorAll(".letter"), {
scrollTrigger: {
trigger: element,
start: 'top bottom',
once: true
},
duration: 1.2,
scale: 1, // De scale: 0 à scale: 1
opacity: 1,
delay: (i) => i * 0.04,
ease: "elastic.out(1, 0.3)"
});CSS correspondant :
.mm-anim-gsap .letter {
display: inline-block;
transform: scale(0);
opacity: 0;
}Options de ScrollTrigger
Différents points de déclenchement
start: 'top bottom', // Déclenche quand le haut de l'élément atteint le bas du viewport
start: 'top center', // Déclenche quand le haut de l'élément atteint le centre du viewport
start: 'top top', // Déclenche quand le haut de l'élément atteint le haut du viewport
start: 'center center', // Déclenche quand le centre de l'élément atteint le centre du viewportAnimation répétée
Pour que l'animation se répète à chaque fois que l'élément entre dans le viewport :
scrollTrigger: {
trigger: element,
start: 'top bottom',
once: false, // Changez à false pour répéter l'animation
toggleActions: 'play none none reverse' // play au scroll down, reverse au scroll up
}Personnalisation
Ajuster la vitesse
Modifiez le delay pour changer la vitesse d'apparition des lettres :
delay: (i) => i * 0.045, // Plus petit = plus rapide
delay: (i) => i * 0.1, // Plus lentChanger la durée
duration: 1.3, // Durée de l'animation en secondes
duration: 0.8, // Plus rapide
duration: 2, // Plus lentDifférentes courbes d'animation (ease)
ease: "power2.out", // Accélération douce
ease: "power3.inOut", // Accélération puis décélération
ease: "back.out(1.7)", // Effet de rebond
ease: "elastic.out(1, 0.3)", // Effet élastique
ease: "bounce.out", // Effet de rebond
ease: "sine.inOut" // Courbe sinusoïdaleExemple complet
HTML
<section class="mm-section">
<h1 class="mm-anim-gsap">Bienvenue sur notre site</h1>
<p class="mm-anim-gsap">Découvrez nos produits exceptionnels</p>
</section>Résultat
Les titres et paragraphes avec la classe mm-anim-gsap s'animeront automatiquement lettre par lettre lorsqu'ils entrent dans le viewport lors du scroll.
Bonnes pratiques
- Performance : Utilisez
once: truepour éviter de rejouer l'animation inutilement - Accessibilité : Assurez-vous que le texte reste lisible même si JavaScript est désactivé
- Mobile : Testez les animations sur mobile, elles peuvent être plus lentes
- Contraste : Vérifiez que le texte reste lisible pendant l'animation (opacity: 0 → 1)
Dépannage
L'animation ne se déclenche pas
- Vérifiez que GSAP et ScrollTrigger sont bien chargés
- Vérifiez que
gsap.registerPlugin(ScrollTrigger)est appelé - Vérifiez que la classe
mm-anim-gsapest bien présente sur l'élément
Les lettres ne s'affichent pas correctement
- Vérifiez que le CSS est bien chargé
- Vérifiez que
white-space: nowrapn'interfère pas avec votre layout - Testez avec
display: inline-blocksur les lettres
Ressources
- Documentation GSAP : https://greensock.com/docs/ (opens in a new tab)
- Documentation ScrollTrigger : https://greensock.com/docs/v3/Plugins/ScrollTrigger/ (opens in a new tab)
- Ease Visualizer : https://greensock.com/ease-visualizer/ (opens in a new tab)