OUJOOD.COM
Les animations CSS sont excellentes pour les transitions simples et les états visuels statiques. Mais dès qu'on veut contrôler dynamiquement une animation — la mettre en pause, la ralentir, la jouer à l'envers, ou la synchroniser avec d'autres — CSS montre ses limites. On finissait alors par ajouter une bibliothèque JavaScript dédiée.
La Web Animations API change ça. Elle expose le moteur d'animation natif du navigateur — le même qui fait tourner les animations CSS — directement en JavaScript. Résultat : des animations aussi fluides que CSS, avec toute la logique de contrôle qu'on veut, sans dépendance externe.
Créer une animation avec animate()
La méthode animate() s'appelle directement sur un élément DOM. Elle prend deux arguments : un tableau de keyframes et un objet d'options de timing :
Exemple : 📋 Copier le code
const boite = document.getElementById('maBoite');
// Animer avec des keyframes et des options de timing
const animation = boite.animate(
[
{ transform: 'translateX(0px)', opacity: 1 }, // état de départ
{ transform: 'translateX(300px)', opacity: 0.5 } // état d'arrivée
],
{
duration: 1000, // durée en millisecondes
easing: 'ease-in-out',
fill: 'forwards' // conserver l'état final après l'animation
}
);
console.log(animation); // objet Animation retourné
Contrôler la lecture
L'objet Animation retourné par animate() expose des méthodes pour piloter l'animation en temps réel :
Exemple : 📋 Copier le code
const animation = element.animate(keyframes, options); animation.pause(); // mettre en pause animation.play(); // lancer ou reprendre animation.reverse(); // jouer à l'envers animation.cancel(); // annuler et revenir à l'état initial animation.finish(); // sauter directement à la fin // Modifier la vitesse (1 = normale, 2 = double, 0.5 = ralenti) animation.playbackRate = 2; // Position actuelle dans l'animation (en millisecondes) console.log(animation.currentTime); // Sauter à une position précise animation.currentTime = 500; // aller à 500ms
Keyframes multiples
On peut définir autant d'étapes intermédiaires que nécessaire. La propriété offset positionne chaque keyframe entre 0 (début) et 1 (fin) :
Exemple : 📋 Copier le code
const element = document.getElementById('balle');
element.animate(
[
{ transform: 'translateY(0)', offset: 0 },
{ transform: 'translateY(-150px)', offset: 0.4 }, // pic du rebond
{ transform: 'translateY(0)', offset: 0.7 },
{ transform: 'translateY(-60px)', offset: 0.85 }, // second rebond
{ transform: 'translateY(0)', offset: 1 }
],
{
duration: 1200,
easing: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
iterations: Infinity // répéter indéfiniment
}
);
Options de timing détaillées
L'objet de timing accepte plusieurs propriétés pour contrôler finement le comportement de l'animation :
Exemple : 📋 Copier le code
element.animate(keyframes, {
duration: 800, // durée totale en ms
delay: 200, // délai avant de démarrer
endDelay: 100, // délai après la fin
iterations: 3, // nombre de répétitions (Infinity pour boucle)
direction: 'alternate', // 'normal' | 'reverse' | 'alternate' | 'alternate-reverse'
easing: 'ease-out', // courbe d'accélération
fill: 'both' // 'none' | 'forwards' | 'backwards' | 'both'
});
Détecter la fin d'une animation
L'objet Animation expose une Promise finished qui se résout quand l'animation se termine. C'est la façon la plus propre d'enchaîner des actions après une animation :
Exemple : 📋 Copier le code
async function animerEtSupprimer(element) {
// Animer la disparition
const animation = element.animate(
[
{ opacity: 1, transform: 'scale(1)' },
{ opacity: 0, transform: 'scale(0.8)' }
],
{ duration: 400, easing: 'ease-in', fill: 'forwards' }
);
// Attendre la fin de l'animation avant de supprimer l'élément
await animation.finished;
element.remove();
console.log('Élément supprimé après animation.');
}
document.getElementById('btnSupprimer').addEventListener('click', () => {
animerEtSupprimer(document.getElementById('carte'));
});
Exemple pratique : menu qui s'ouvre avec animation
Voici un menu latéral qui s'ouvre et se ferme avec des animations fluides contrôlées par la WAAPI :
Exemple : 📋 Copier le code
const menu = document.getElementById('menuLateral');
const bouton = document.getElementById('btnMenu');
let menuOuvert = false;
let animationMenu = null;
function ouvrirMenu() {
// Annuler une animation en cours
if (animationMenu) animationMenu.cancel();
animationMenu = menu.animate(
[
{ transform: 'translateX(-100%)', opacity: 0 },
{ transform: 'translateX(0)', opacity: 1 }
],
{ duration: 300, easing: 'ease-out', fill: 'forwards' }
);
menuOuvert = true;
}
function fermerMenu() {
if (animationMenu) animationMenu.cancel();
animationMenu = menu.animate(
[
{ transform: 'translateX(0)', opacity: 1 },
{ transform: 'translateX(-100%)', opacity: 0 }
],
{ duration: 250, easing: 'ease-in', fill: 'forwards' }
);
menuOuvert = false;
}
bouton.addEventListener('click', () => {
menuOuvert ? fermerMenu() : ouvrirMenu();
});
Synchroniser plusieurs animations
Promise.all() permet d'attendre que plusieurs animations se terminent avant d'exécuter la suite :
Exemple : 📋 Copier le code
const titre = document.getElementById('titre');
const image = document.getElementById('image');
const texte = document.getElementById('texte');
const keysFadeIn = [{ opacity: 0 }, { opacity: 1 }];
const timingEntree = { duration: 600, fill: 'forwards' };
// Lancer trois animations en parallèle
const animTitre = titre.animate(keysFadeIn, { ...timingEntree, delay: 0 });
const animImage = image.animate(keysFadeIn, { ...timingEntree, delay: 200 });
const animTexte = texte.animate(keysFadeIn, { ...timingEntree, delay: 400 });
// Attendre que toutes soient terminées
await Promise.all([
animTitre.finished,
animImage.finished,
animTexte.finished
]);
console.log('Toutes les animations sont terminées.');
Web Animations API vs CSS vs bibliothèques
Chaque approche a sa place :
- CSS animations/transitions : idéales pour les états visuels simples et les interactions hover. Déclaratives, faciles à maintenir.
- Web Animations API : quand on a besoin de contrôle dynamique (pause, reverse, synchronisation avec des événements), sans dépendance externe. Le bon choix pour la majorité des projets en 2026.
- GSAP, Anime.js : pour les animations très complexes, les timelines imbriquées, ou quand on a besoin de support pour des navigateurs très anciens. Un surcoût en octets à justifier.
Par carabde | Mis à jour le 17 avril 2026