Améliorations

Parent Previous Next


Améliorations



L'interface réalisée précédemment est fonctionnelle, mais rudimentaire. Deux améliorations principales sont possibles :


Afficher le temps écoulé


Afficher le temps écoulé ? Ce n'est pas compliqué, il suffit d'utiliser la propriété currentTime. Le souci est que currentTime retourne le temps écoulé en secondes avec ses décimales. Il est donc possible de voir s'afficher un temps de lecture de 4,133968 secondes. Il convient donc de faire quelques opérations pour rendre ce nombre compréhensible. Voici la fonction formatTime() :

function formatTime(time) {

    var hours = Math.floor(time / 3600);

    var mins  = Math.floor((time % 3600) / 60);

    var secs  = Math.floor(time % 60);

     

    if (secs < 10) {

        secs = "0" + secs;

    }

     

    if (hours) {

        if (mins < 10) {

            mins = "0" + mins;

        }

         

        return hours + ":" + mins + ":" + secs; // hh:mm:ss

    } else {

        return mins + ":" + secs; // mm:ss

    }

}


On opère quelques divisions et arrondissements afin d'extraire le nombre d'heures, de minutes et de secondes. Puis on complète avec des 0 pour un affichage plus joli.


On peut donc ajouter ceci à notre fonction update() :

document.querySelector('#progressTime').textContent = formatTime(time);


Et modifier la barre de progression pour y ajouter un <span> dans lequel s'affichera le temps écoulé :

<div id="progressBarControl">

  <div id="progressBar">Pas de lecture</div>

</div>

<span id="progressTime">00:00</span>


Rendre la barre de progression cliquable


Ici, ça se corse un peu. Si on clique sur la barre de progression, le comportement attendu est la lecture du fichier audio à partir de cet endroit. Il va donc falloir calculer l'endroit où on a cliqué et positionner la lecture en conséquence, avec la propriété currentTime.


Pour savoir où l'on a cliqué au sein d'un élément, il faut connaître deux choses : les coordonnées de la souris et les coordonnées de l'élément. Ces coordonnées sont calculées à partir du coin supérieur gauche de la page. Voici une explication plus imagée :



Les coordonnées sont calculées à partir du coin supérieur gauche de la page




Pour connaître la distance représentée par la flèche turquoise, il suffit de soustraire la distance représentée par la flèche rouge (la position de la barre sur l'axe des X) à la distance représentée par la flèche bleue (la position X du curseur de la souris). C'est tout simple, mais la récupération des coordonnées n'est pas évidente.


L'exemple ici ne permet que de reculer dans la lecture, puisque seule la barre de progression est cliquable. Il est bien évidemment possible de coder un système pour avancer dans la lecture, en rendant cliquable le conteneur de la barre de progression.


Récupérer les coordonnées du curseur de la souris


Nous allons créer la fonction getMousePosition() qui recevra comme paramètre un événement et qui retournera les positions X et Y du curseur :

function getMousePosition(event) {

    if (event.pageX) {

        return {

            x: event.pageX,

            y: event.pageY

        };

    } else {

        return {

            x: event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft,

            y: event.clientY + document.body.scrollTop  + document.documentElement.scrollTop

        };

    }

}


Les propriétés pageX et pageY de l'objet event permettent respectivement de récupérer les positions sur l'axe des X et sur l'axe des Y. Ça fonctionne pour tous les navigateurs à l'exception d'Internet Explorer qui demande d'utiliser clientX et clientY. Mais en plus de cela, il faut additionner les valeurs du défilement horizontal et vertical. En effet, sans cela, Internet Explorer ne tient pas compte du défilement de la page…


Ce script est un script générique qui retournera un objet { x: "valeur", y: "valeur" }. Dans l'exemple ici, connaître Y n'est pas important, mais au moins vous pouvez réutiliser cette fonction.


Récupérer les coordonnées d'un élément


Comme l'élément n'est pas positionné de façon absolue, il n'est pas possible de connaître les coordonnées de son coin supérieur gauche via le CSS. Il va donc falloir calculer le décalage entre lui et son élément parent, puis le décalage entre cet élément parent et son parent… et ainsi de suite, jusqu'à arriver à l'élément racine, c'est-à-dire <html> :

function getPosition(element){

    var top = 0, left = 0;

     

    while (element) {

        left   += element.offsetLeft;

        top    += element.offsetTop;

        element = element.offsetParent;

    }

     

    return { x: left, y: top };

}


Trois nouvelles propriétés : offsetLeftoffsetTop et offsetParent. Ces trois propriétés ne sont pas standardisées, elles ont été introduites avec Internet Explorer, mais sont universellement reconnues.offsetLeft permet de connaître le nombre de pixels, sur l'axe horizontal, dont est décalé un élément enfant par rapport à son parent. offsetTop, c'est pareil, mais pour le décalage vertical.


offsetParent ressemble à parentNode, mais n'est pas identique. offsetParent retourne le premier élément parent positionné, c'est-à-dire qui est affiché par le navigateur. De manière générale, on utilise parentNode pour naviguer dans le DOM, et offsetParent pour tout ce qui concerne les mesures, comme c'est le cas ici.


On clique !


Maintenant que nous avons nos deux fonctions getMousePosition() et getPosition(), nous pouvons écrire la fonction clickProgress(), qui sera exécutée dès que l'internaute cliquera sur la barre de progression :

function clickProgress(idPlayer, control, event) {

    var parent = getPosition(control);    // La position absolue de la progressBar

    var target = getMousePosition(event); // L'endroit de la progressBar où on a cliqué

    var player = document.querySelector('#' + idPlayer);

   

    var x = target.x - parent.x;

    var wrapperWidth = document.querySelector('#progressBarControl').offsetWidth;

     

    var percent = Math.ceil((x / wrapperWidth) * 100);   

    var duration = player.duration;

     

    player.currentTime = (duration * percent) / 100;

}


On récupère la distance x, qui est la distance entre le bord gauche de la barre et l'endroit où on a cliqué. On divise x par la largeur totale du conteneur de la barre de progression (avec offsetWidth) et on multiplie par 100 pour obtenir un pourcentage. Ensuite, on calcule le currentTime en multipliant le temps total de la chanson par le pourcentage, le tout divisé par 100.


Et n'oublions pas de modifier le code HTML en conséquence :

<div id="progressBar" onclick="clickProgress('audioPlayer', this, event)">Pas de lecture</div>


Et ça marche !


Créé avec HelpNDoc Personal Edition: Création d'aide CHM, PDF, DOC et HTML d'une même source

Site à deux balles