Infoforall

Javascript 10 : Musique ! Gérons les sons

Dans l'activité précédente, vous avez appris à placer les éléments directement via le CSS, le javascript, à utiliser le hasard et à utiliser les tableaux pour stocker des données.

Nous allons aujourd'hui apprendre à réaliser une interface ressemblant à cela :

Nous allons voir comment y placer de petits sons liés à des événements. La gestion d'un morceau de musique entier (avec les boutons PLAY/PAUSE et la barre de progression) n'est pas compliquée en soit mais nous verrons cela plus tard dans une autre activité.

Concentrons nous ici uniquement sur les petits effets sonores.

1 - Interface basique

Nous allons commencer par voir comment créer l'interface graphique.

Remarque : Dans l'activité suivante, nous verrons comment créer cette même interface en plaçant le nom des images dans le script javascript plutôt que dans le fichier HTML lui-même. Cela nous permettra ainsi de placer les images au hasard, de modifier la taille, ect ...

01° Téléchargez le fichier HTML, le fichier CSS et les 9 images. Placez le tout dans un même dossier.

Regardons le code HTML : on crée une balise div-conteneur js090_test1 qui contient plusieurs divs (de a11 à c33) dont on fixe la couleur dans le CSS en utilisant l'identifiant des balises. Chacune de ces balises contient une balise img qui correspond à un animal.

Dans chacune des balises colorées, nous plaçons une image.

<!DOCTYPE html>

<html>

    <head>

        <meta charset="UTF-8" />

        <title>Musique !</title>

        <meta http-equiv="content-Language" content="fr" />

        <link rel="stylesheet" href="animaux-feroces-9.css" />

        <script src="animaux-feroces-9.js"></script>

    </head>

    <body>


        <header>

            <h3>MON TEST D'INTERFACE</h3>

        </header>


        <section>


            <div id="js090_test1">


                <div id="a11">

                    <img title="agneau" src = "agneau.jpg" width="140" height="104" />

                </div>


                <div id="a12">

                    <img title="tigre" src = "tigre.jpg" width="140" height="104" />

                </div>


                <div id="a13">

                    <img title="canard" src = "canard.jpg" width="140" height="104" />

                </div>


                <div id="b21">

                    <img title="lapin" src = "lapin.jpg" width="140" height="104" />

                </div>


                <div id="b22">

                    <img title="tarentule" src = "tarentule.jpg" width="140" height="104" />

                </div>


                <div id="b23">

                    <img title="chaton" src = "chaton.jpg" width="140" height="104" />

                </div>


                <div id="c31">

                    <img title="suricate" src = "suricate.jpg" width="140" height="104" />

                </div>


                <div id="c32">

                    <img title="ecureuil" src = "ecureuil.jpg" width="140" height="104" />

                </div>


                <div id="c33">

                    <img title="koala" src = "koala.jpg" width="140" height="104" />

                </div>


            </div>

        </section>


    </body>

</html>

02° En regardant le code, les images JPG doivent-elles être dans le même répertoire que le fichier HTML ou dans un sous-dossier images ?

Voici pour le fichier CSS nommé animaux-feroces-9.css :

#js090_test1{

    margin: auto;

    padding: 0px;

    border: 1px solid #660000;

    width:800px;

    height:650px;

    position: relative;

}


#js090_test1 div {

    display: inline-block;

    margin: 0px;

    padding: 0px;

    width: 150px;

    height: 150px;

    border: 1px solid #777777;

}


#js090_test1 div img {

    display: block;

    margin: auto;

    padding: 0px;

    margin-top: 50%;

    transform: translateY(-50%); /* tirée de la moitié de sa propre hauteur */

}


#a11 {

    background-color:blue;

    position:absolute;

    top:50px;

    left:50px;

}


#a12 {

    background-color:orange;

    position:absolute;

    top:50px;

    left:300px;

}


#a13 {

    background-color:green;

    position:absolute;

    top:50px;

    left:550px;

}


#b21 {

    background-color:red;

    position:absolute;

    top:250px;

    left:50px;

}


#b22 {

    background-color:yellow;

    position:absolute;

    top:250px;

    left:300px;

}


#b23 {

    background-color:black;

    position:absolute;

    top:250px;

    left:550px;

}


#c31 {

    background-color:cyan;

    position:absolute;

    top:450px;

    left:300px;

}


#c32 {

    background-color:grey;

    position:absolute;

    top:450px;

    left:550px;

}


#c33 {

    background-color:purple;

    position:absolute;

    top:450px;

    left:50px;

}

2 - Script javascript

Il vous reste à créer votre fichier javascript nommé animaux-feroces-9.js.

03° Nous allons utiliser l'objet this qui permet d'obtenir le noeud de la balise qui a activé l'événement click. Pourquoi ne pas utiliser d'attributs onclick directement dans le HTML ?

...CORRECTION...

Si on place un onclick dans le document HTML, c'est le document HTML lui même qui va activer la fonction.

La variable this va alors contenir le noeud du document et pas le noeud de l'image.

Par contre, si on crée ces surveillances d'événements dans le code javascript, on pourra créer des liens propres entre certaines balises et certaines fonctions d'événements.

04° Créer le fichier javascript animaux-feroces-9.js et y placer le code suivant :

function bruitage() {

    var animal = this.title;

    alert("bruitage sur "+animal);

}


function demarrage() {

    var listeDiv = document.querySelectorAll("#js090_test1 div img");

    for (var i = 0; i < listeDiv.length; i++) {

        listeDiv[i].onclick = bruitage ;

    }

}


window.addEventListener("load",demarrage);

05° Quelle est la fonction qui se lance automatiquement lorsque toute la page (images comprises) est entièrement chargée ?

...CORRECTION...

C'est la fonction demarrage.

06° Le tableau listeDiv contient-il la liste des balises div colorées ou la liste des images contenues dans les div colorées ?

...CORRECTION...

Le tableau listeDiv contient la liste des noeuds des images. Le tableau contient donc un ensemble de références. L'index 0 correspond à l'image "agneau.jpg".

07° Quelle est la ligne qui permet d'associer une surveillance d'événement click à chacune des images ?

...CORRECTION...

On active la surveillance d'événement avec listeDiv[i].onclick = bruitage.

08° Que contient this si on clique sur la première image ? Que renvoie alors this.title ?

...CORRECTION...

this contient la référence du noeud de la première image, celle de l'agneau.

La propriété title de javascript fait référence à l'attribut title du HTML.

En regardant le HTML, on voit que pour la première image, on avait noté title="agneau".

var animal = this.title;

permet donc de placer le string contenant le nom de l'animal dans la variable animal.

09° Activer le code pour vérifier que nous parvenons bien à détecter la bonne image lorsqu'on clique dessus.

Et voilà. Nous avons désormais un code cohérent. Il nous reste à voir comment activer le lancement de son en fonction de l'image sélectionnée.

3 - Activer un son avec la méthode play

Pour activer les sons, il vous faut d'abord les télécharger sur votre poste.

10° Télécharger les différents sons et les placer dans le même dossier que vos autres fichiers.

Pour pouvoir activer les sons, nous allons avoir besoin de les insérer dans le HTML. Soit avec un code Javascript, soit directement dans le HTML.

Nous verrons dans l'activité suivante comment créer des éléments depuis le code javascript (nous allons rajouter des balises IMG). Pour l'instant, je me limite à l'insertion directe en tapant le code en dur.

Pour pouvoir accéder aux sons, nous allons devoir les "afficher" dans le code HTML. Ils ne se mettront pas automatiquement en route mais cela nous permettra de les activer depuis le javascript.

<audio id="agneau" src="agneau.mp3" ></audio>

<audio id="tigre" src="tigre.mp3" ></audio>

<audio id="canard" src="canard.mp3" ></audio>

<audio id="lapin" src="lapin.mp3" ></audio>

<audio id="tarentule" src="tarentule.mp3" ></audio>

<audio id="chaton" src="chaton.mp3" ></audio>

<audio id="suricate" src="suricate.mp3" ></audio>

<audio id="ecureuil" src="ecureuil.mp3" ></audio>

<audio id="koala" src="koala.mp3" ></audio>

11° Comparer les id des balises audio avec les title des balises img. Que remarquez-vous ? Que va permettre ce choix judicieux des noms ?

...CORRECTION...

Les deux contiennent rigoureusement les mêmes strings.

Cela va nous permettre d'activer le bon son en allant chercher le title de l'image sur laquelle on vient de cliquer.

Et comment trouver la bonne image ? En utilisant tout simplement l'objet this.

12° Insérer les balises audio juste sous la balise d'ouverture de la section.

Pour activer le son d'une des balises audio, il suffit de :

13° Remplacer la ligne alert("bruitage sur "+animal); par un code permettant d'activer le son du tigre quelque soit l'image sur laquelle on vient de cliquer.

...CORRECTION...

function bruitage() {

    var animal = this.title;

    document.getElementById("tigre").play();

}

N'oubliez pas le point entre l'objet-noeud visé et la méthode utilisée sur le noeud.

14° Utiliser le contenu du titre de l'image (qu'on a placé dans la variable animal) pour activer le bon son sur la bonne image.

...CORRECTION...

function bruitage() {

    var animal = this.title;

    document.getElementById(animal).play();

}


4 - Mini-projet

Voici un autre exemple de correction pour la question 14.

function bruitage() {

    var animal = this.title;

    var leSon = document.getElementById(animal)

    leSon.play();

}


function demarrage() {

    var listeDiv = document.querySelectorAll("#js090_test1 div img");

    for (var i = 0; i < listeDiv.length; i++) {

        listeDiv[i].onclick = bruitage ;

    }

}


window.addEventListener("load",demarrage);

Nous allons partir de cela pour vous demander de réaliser certaines tâches qui devraient vous permettre de réaliser l'interface du début :

15° A vous de jouer !