• 20 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Animez vos pages

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Ce chapitre va vous permettre de vous initier aux techniques d'animations de pages avec JavaScript.

Répéter une action à intervalles réguliers

Un premier niveau d'animation consiste à modifier le contenu d'un élément de manière répétée. Illustrons cela en créant un compte à rebours sur une page web.

Voici le fichiercours.html à créer dans le répertoirechapitre_7/html.

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <title>Animer une page</title>
</head>

<body>
    <h1 id="titre">Cette page web s'autodétruira dans <span id="compteur">10</span> seconde(s)...</h1>

    <script src="../js/cours.js"></script>
</body>

</html>

Tapez maintenant le code ci-dessous dans le fichiercours.js à créer dans le répertoirechapitre_7/js.

var compteurElt = document.getElementById("compteur");

// Diminue le compteur jusqu'à 0
function diminuerCompteur() {
    // Conversion en nombre du texte du compteur
    var compteur = Number(compteurElt.textContent);        
    compteurElt.textContent = compteur - 1;
}

// Appelle la fonction diminuerCompteur toutes les secondes (1000 millisecondes)
setInterval(diminuerCompteur, 1000);

Ouvrez la page web dans votre navigateur : le compte à rebours fonctionne...

... Ou plutôt semble fonctionner : il ne s'arrête jamais. o_O Nous règlerons ce petit souci un peu plus loin.

Démarrer une action répétée

Comment fonctionne  cet exemple ? Le programme JavaScript définit une fonctiondiminuerCompteurqui récupère puis décrémente (diminue de 1) la valeur de l'élément HTML qui affiche la valeur du compteur. L'appel àNumberpermet de convertir le texte du compteur (chaîne de caractères) en valeur numérique. Cette conversion est indispensable pour pouvoir ensuite effectuer l'opération mathématique de soustraction.

C'est l'appel à setIntervalqui déclenche le compte à rebours. Cette fonction permet d'appeler une fonction à intervalles réguliers. Les paramètres desetIntervalsont la fonction à appeler et le délai entre deux appels. Ce délai est exprimé en millisecondes.

Annuler une action répétée

À présent, essayons d'arrêter le compteur une fois le compte à rebours terminé. Nous allons en profiter pour modifier le texte de la page. Voici le code JavaScript de notre exemple, modifié pour atteindre ce résultat.

var compteurElt = document.getElementById("compteur");

// Diminue le compteur jusqu'à 0
function diminuerCompteur() {
    // Conversion en nombre du texte du compteur
    var compteur = Number(compteurElt.textContent);
    if (compteur > 1) {
        compteurElt.textContent = compteur - 1;
    } else {
        // Annule l'exécution répétée
        clearInterval(intervalId);
        // Modifie le titre de la page
        var titre = document.getElementById("titre");
        titre.textContent = "BOUM !!!";
    }
}

// Appelle la fonction diminuerCompteur toutes les secondes (1000 millisecondes)
var intervalId = setInterval(diminuerCompteur, 1000);

Dans la fonctiondiminuerCompteur, on ne décrémente le compteur que si sa valeur actuelle est strictement supérieure à 1. Dans le cas contraire, on appelle la fonctionclearIntervalpuis on modifie le contenu du titre affiché par la page.

La fonctionclearIntervalpermet de stopper une exécution répétée. Elle prend en paramètre l'identifiant de l'action, renvoyée par la fonctionsetIntervalet stockée dans notre exemple dans la variableintervalId.

Effectuer une action après un délai

Imaginons que l'on souhaite modifier le texte de notre page après son "explosion". Pour cela, nous pouvons modifier notre exemple de la manière suivante.

var compteurElt = document.getElementById("compteur");

// Diminue le compteur jusqu'à 0
function diminuerCompteur() {
    // Conversion en nombre du texte du compteur
    var compteur = Number(compteurElt.textContent);
    if (compteur > 1) {
        compteurElt.textContent = compteur - 1;
    } else {
        // Annule l'exécution répétée
        clearInterval(intervalId);
        // Modifie le titre de la page
        var titre = document.getElementById("titre");
        titre.textContent = "BOUM !!!";
        // Modification du titre au bout de 2 secondes
        setTimeout(function () {
            titre.textContent = "Tout est cassé :(";
        }, 2000);
    }
}

// Appelle la fonction diminuerCompteur toutes les secondes (1000 millisecondes)
var intervalId = setInterval(diminuerCompteur, 1000);

Une fois le compte à rebours terminé, on fait appel àsetTimeoutpour modifier de nouveau le titre après un délai de deux secondes.

La fonctionsetTimeoutpermet d'exécuter une fonction une seule fois après un certain délai, exprimé en millisecondes.

Animer des éléments de la page

Les solutions précédentes sont pratiques pour ajouter du dynamisme à nos pages, mais ne suffisent pas pour effectuer de véritables animations en temps réel. Pour cela, il existe une solution plus performante que nous allons aborder maintenant.

Prenons comme exemple le déplacement d'un élément de typedivde gauche à droite sur la page. Ajoutez l'extrait de code HTML suivant dans la balise<body> de la page web d'exemple.

<div id="cadre">
    <div id="bloc"></div>
</div>

Ajoutez également l'extrait suivant dans la balise<head> de la page.

<link rel="stylesheet" href="../css/cours.css">

Créez ensuite le fichiercours.css dans le répertoirechapitre_7/css.

#cadre {
    border: 1px solid red;
}

#bloc {
    width: 20px;
    height: 40px;
    background: red;
    position: relative; /* Permettra de décaler le bloc */
    left: 0px; /* Initialise la position gauche du bloc à déplacer */
}

L'attribut CSSposition: relative va nous permettre déplacer l'élément en modifiant sa propriété CSSleft depuis le code JavaScript.

Ouvrez la page web dans votre navigateur. Vous devez obtenir le résultat suivant.

Voici le code JavaScript qui permet de déplacer le bloc rouge vers la gauche.

var bloc = document.getElementById("bloc");
var vitesse = 7; // Valeur du déplacement en pixels

// Déplace le bloc sur sa gauche
function deplacerBloc() {
    // Conversion en nombre de la position gauche du bloc (valeur de la forme "XXpx")
    var xBloc = parseFloat(getComputedStyle(bloc).left);
    // Déplacement du bloc
    bloc.style.left = (xBloc + vitesse) + "px";
    // Demande au navigateur d'appeler deplacerBloc dès que possible
    requestAnimationFrame(deplacerBloc);
}
requestAnimationFrame(deplacerBloc); // Début de l'animation

Mettez à jour la page dans votre navigateur : ça marche...

... Ou pas : un peu comme notre compteur précédent, le bloc ne s'arrête jamais !

Débuter une animation

Notre exemple de code définit une fonctiondeplacerBlocdont le rôle est de déplacer le bloc sur sa gauche. Pour cela, elle récupère la position actuelle du bord gauche du bloc, puis lui ajoute la valeur contenue dans la variablevitesse, ce qui a pour effet de décaler le bloc sur sa droite.  Enfin, elle fait appel àrequestAnimationFramepour continuer l'animation.

Les valeurs des positions sont exprimées en pixels. Ce sont des chaînes de caractères de la forme "XXpx", ce qui nécessite l'utilisation de la fonctionparseFloatpour les convertir en valeurs numériques avant d'effectuer des calculs.

La fonctionrequestAnimationFramepermet de demander au navigateur d'exécuter dès que possible une fonction qui met à jour une animation. Le terme "dès que possible" signifie que le navigateur va optimiser la mise à jour de l'animation afin de la rendre fluide.

Voici comment utiliserrequestAnimationFrameen combinaison avec une fonction d'animation.

function animer() {
    // Code de l'animation
    // ...
    requestAnimationFrame(animer);
}
requestAnimationFrame(animer);

Stopper une animation

Voyons maintenant comment arrêter le bloc lorsqu'il arrive au bout du cadre qui le contient. Pour cela, il faut vérifier si la position du bord gauche du bloc est inférieure à la largeur du cadre, en tenant compte de l'épaisseur du bloc lui-même.

Voici le code JavaScript modifié à cet effet.

var bloc = document.getElementById("bloc");
var cadre = document.getElementById("cadre");
var vitesse = 7; // Valeur du déplacement en pixels
// Conversion en nombre du diamètre du bloc (valeur de la forme "XXpx")
var largeurBloc = parseFloat(getComputedStyle(bloc).width);
var animationId = null; // Identifiant de l'animation

// Déplace le bloc sur sa gauche jusqu'au bord du cadre
function deplacerBloc() {
    // Conversion en nombre de la position gauche du bloc (valeur de la forme "XXpx")
    var xBloc = parseFloat(getComputedStyle(bloc).left);
    // Conversion en nombre de la largeur du cadre (valeur de la forme "XXpx")
    var xMax = parseFloat(getComputedStyle(cadre).width);
    if (xBloc + largeurBloc <= xMax) { // Si le bloc n'est pas encore au bout du cadre
        // Déplacement du bloc
        bloc.style.left = (xBloc + vitesse) + "px";
        // Demande au navigateur d'appeler deplacerBloc dès que possible
        animationId = requestAnimationFrame(deplacerBloc);
    } else {
        // Annulation de l'animation
        cancelAnimationFrame(animationId);
    }
}

animationId = requestAnimationFrame(deplacerBloc); // Début de l'animation    

La nouvelle fonctiondeplacerBlocvérifie si le bloc est arrivé au bout du cadre avant de le déplacer. Si c'est le cas, elle arrête l'animation en appelantcancelAnimationFrame.

La fonctioncancelAnimationFrame permet de stopper une animation. Elle prend un paramètre l'identifiant de l'animation, stocké ici dans la variableanimationIdet renvoyé par chaque appel àrequestAnimationFrame.

Une alternative : les animations CSS

Nous venons de découvrir les principales possibilités offertes par JavaScript pour animer une page web. Sachez qu'il existe une alternative toute aussi intéressante : l'utilisation de CSS.

Exemple d'animation avec CSS

Ce sujet est trop riche pour être abordé dans ce cours. À titre d'exemple, je vais vous montrer comment on peut obtenir une animation similaire à la précédente en utilisant CSS à la place de JavaScript.

Modifiez le fichiercours.css pour y ajouter les éléments suivants.

#bloc {
    /* ... */
    margin-left: -20px; /* Simplifie le calcul des positions initiale et finale du bloc */
    animation-name: deplacerBloc; /* Nom de l'animation */
    animation-duration: 6s; /* Durée de l'animation */
    animation-fill-mode: forwards; /* Laisse le bloc dans sa position finale */
}

@keyframes deplacerBloc {
    from {
        /* Position initiale : bord gauche du cadre (en tenant compte de la marge négative) */
        left: 20px; 
    }
    to {
        /* Position finale : bord droit du cadre (en tenant compte de la marge négative) */
        left: 100%; 
    }
}

Sans rentrer dans les détails, ce code définit une animation CSS nomméedeplacerBlocpour le bloc, qui le fait passer du bord gauche au bord droit du cadre qui le contient.

Désactivez l'animation JavaScript en commentant la ligne qui la lance dans le fichiercours.js.

//animationId = requestAnimationFrame(deplacerBloc); // Début de l'animation

Mettez à jour la page dans le navigateur : le bloc se déplace... Grâce au CSS !

Choisir la technique d'animation adaptée

Comment choisir entresetIntervalrequestAnimationFrameet CSS pour effectuer une animation ?

La réponse à cette question dépend de plusieurs facteurs, notamment la complexité de l'animation à réaliser. A priori, les animations réalisées avec CSS sont plus efficaces du point de vue des performances. Encore faut-il qu'elles permettent d'obtenir l'objectif voulu : on ne peut pas tout faire avec CSS.

Je vous propose d'adopter la démarche suivante lorsque vous devez animer une page web :

  • Si l'animation n'est pas en temps réel et doit simplement se produire à intervalles réguliers, utilisezsetInterval.

  • Si l'animation est en temps réel et que vous savez qu'elle peut être effectuée via CSS, adoptez cette technique.

  • Pour tous les autres cas, utilisezrequestAnimationFrame.

En résumé

Voici l'essentiel à retenir de ce chapitre sur les animations avec JavaScript.

  • La fonctionsetIntervaldémarre une action répétée sous la forme d'une fonction appelée à intervalles réguliers. La fonctionclearIntervalannule une répétition démarrée avecsetInterval.

  • La fonctionsetTimeoutexécute une action une seule fois après un certain délai.

  • La fonctionrequestAnimationFramedemande au navigateur d'exécuter dès que possible une fonction qui met à jour une animation. Elle est à privilégier pour les animations en temps réel. La fonctioncancelAnimationFramestoppe une animation lancée avecrequestAnimationFrame.

  • Il est également possible d'animer une page web en utilisant CSS. Le choix de la technique dépend de l'animation à réaliser.

À vous de jouer !

C'est le moment de s'amuser un peu en animant des pages avec JavaScript. Réalisez ces exercices dans le répertoirechapitre_7.

Chronomètre (résultat à obtenir)

Écrivez une page webchrono.html associée à un fichier  chrono.jsqui permet de démarrer et d'arrêter un chronomètre qui compte le nombre de secondes écoulées.

Ballon rebondissant (résultat à obtenir)

Créez le fichier  ballon.html avec le contenu suivant.

<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="../css/ballon.css">
    <title>Ballon rebondissant</title>
</head>

<body>
    <p>
        <button id="demarrer">Démarrer</button>
        <button id="arreter" disabled>Arrêter</button>
    </p>

    <div id="cadre">
        <img id="ballon" src="../images/basketball.jpg">
    </div>

    <script src="../js/ballon.js"></script>
</body>

</html>

Téléchargez l'image du ballon en suivant ce lien puis copiez le fichier obtenu dans le répertoire  chapitre_7/images (à créer).

Créez ensuite le fichierballon.css  ayant le contenu suivant.

#ballon {
    position: relative;
    left: 0px;
}

Enfin, créez le fichier  ballon.js qui permet de faire rebondir le ballon de gauche à droite.

Solutions des exercices

Le code source des solutions est consultable en ligne.

Exemple de certificat de réussite
Exemple de certificat de réussite