Exercice 16 - JS the musical
Dans cet exercice on va créer un des deux "instrument" de musique suivant en javascript: un espèce de "drum kit" ou un piano. Le principe reste le même, mais le piano va demander plus de travail au niveau du css. Chaque notes ou effets sonores sera associés à une touche du clavier. Quand on appuie sur cette touche, le bon son est joué et une animation est lancée sur la case note correspondante. On peut aussi cliquer sur la case et la même procédure est appliquée. Vous pouvez télécharger les fichiers sont --> ici <--
notions à utiliser
- Les attributs data.
- La balise HTML audio pour les sons
- Sélectionner plusieurs éléments HTML à la fois (querySelectorAll, getElementsByClassName)
- Associer un élément HTML à un événement en Javascript (addEventListener)
- Ajouter et enlever une classe d'un élément HTML(classList.Add() et classList.Remove())
- Utilisation de l'élément this
Consignes
HTML
- Créer une div pour chaque case représentant une touche et lui donner un attribut personnalisé avec la valeur du code de la touche à appuyé. Ex 65 pour la touche a. Pour connaître facilement le code des touches : https://www.toptal.com/developers/keycode
- Pour chaque case, ajoutez aussi une balise audio avec le même attribut personnalisé ainsi que le fichier son.
<div data-key="65" class="key">
<kbd>A</kbd>
<!-- La balise kbd indique qu'on s'attend à ce que l'usager entre cette touche.
c'est purement sémantique, ce n'est pas ça qui va faire que la touche est
reconnnue, on va tout faire en js -->
<span>clap</span>
</div>
...
<audio src="assets/sounds/boom.wav" data-key="65"></audio>
CSS
- Faire la disposition et la mise en forme des touches
- Créer une classe qui va faire l'animation de la touche. (Un peu comme on le faisait avec :hover mais ça va être dans une classe à part)
.key {
/* ... */
transition: all 70ms ease;
}
/* au lieu d'utiliser .key:hover on fait une autre classe qu'on
va ajouter ou supprimer à la div qui a la classe key. */
.selection {
transform: scale(1.2);
border-color: orange;
box-shadow: 0 0 10px orange;
border-radius: 5px;
}
JS
- Récupérer toutes les touches dans une variable globale.
- Associer les événements click et transitionend à toutes ces touches (utiliser une boucle forEach)
- Associer l'événement keydown à l'élément window pour capter les touches appuyées
window.addEventListener('keydown', maFonction); - Faire une fonction qui va recevoir en paramètre le code de la touche.
- Faire une fonction qui va être utilisée par l'événement click de la case, qui va récupérer l'attribut personnalisé de la case et qui va appeler la fonction qui joue le son avec la valeur de l'attribut en paramètre.
- Faire une fonction qui va être utilisé par l'événement keydown de window, qui va récupérer le code de la touche pressé par l'objet e et qui va appeler la fonction qui joue le son avec le code de la touche en paramètre. (voir code dans la section aide)
- Faire une fonction qui va être utilisée par l'événement transitionend de la case et qui va retirer la classe qui fait l'animation.
function boutonJoue() {
/* La fonction boutonJoue() a été lancé quand on a cliqué sur la case de la note,
ici this va être égale à cette case. Je peux donc accéder à ses attributs de cette
façon. La fonction joueSon sera lancé avec en paramètre la valeur de l'attribut data- key de la case note */
joueSon(this.getAttribute("data-key"));
}
function toucheJoue(e) {
/* Quand on lance une fonction depuis un événement, on a accès à l'objet e qui
représente l'événement en soit. Cette objet à plusieurs propriétés qui varies selont
l'événement. Ici, puisque qu'on réagit à l'événement keydown on a accès à la propriété keyCode qui nous donne le code de la clé pressée. */
joueSon(e.keyCode);
}
Aide
- Pour faire jouer un élément audio, récupérer l'élément HTML dans une variable, ensuite
// Redémarre l'enregistrement
monElement.currentTime = 0;
// Lance l'enregistrement
monElement.play();
- Associer un événement à un élément HTML
// Associe l'événement keydown à l'élément window et lance la fonction toucheJoue
// quand il est déclenché
window.addEventListener('keydown', toucheJoue);
// keys est un tableau d'élément html, voici une façon d'associer chaque élément
// du tableau à un événement
keys.forEach(function(key){
key.addEventListener('click',boutonJoue)
})
// La même chose mais avec une fonction fléchée
keys.forEach( key => key.addEventListener('click', boutonJoue))
- Récupérer le code de la touche qui a été pressé