11480 sujets

JavaScript, DOM et API Web HTML5

Bonjour, je suis bloqué depuis près d'une semaine sur un problème de boutons en .js ..
J'aimerais faire 3 boutons, un play (qui marche c'est bon), un pause qui met pause sur la musique et un bouton mute qui quand on appui il change d'image pour donner un bouton demute et qui du coup coupe et réactive la musique.

Si vous avez besoin de plus détails n'hésitez pas.. merci pour votre aide, j'en peux plus Smiley ohwell


window.onload = function() {
    
    button.onclick = function() {
      audio.src = "onigiri_audio.mp3";
      audio.load();
      audio.play();
      var context = new AudioContext();
      var src = context.createMediaElementSource(audio);
      var analyser = context.createAnalyser();
  
      var canvas = document.getElementById("canvas");
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      var ctx = canvas.getContext("2d");
  
      src.connect(analyser);
      analyser.connect(context.destination);
  
      analyser.fftSize = 256;
  
      var bufferLength = analyser.frequencyBinCount;
      console.log(bufferLength);
  
      var dataArray = new Uint8Array(bufferLength);
  
      var WIDTH = canvas.width;
      var HEIGHT = canvas.height;
  
      var barWidth = (WIDTH / bufferLength) * 2.5;
      var barHeight;
      var x = 0;
  
      function renderFrame() {
        requestAnimationFrame(renderFrame);
  
        x = 0;
  
        analyser.getByteFrequencyData(dataArray);
  
        ctx.fillStyle = "#000";
        ctx.fillRect(0, 0, WIDTH, HEIGHT);
  
        for (var i = 0; i < bufferLength; i++) {
          barHeight = dataArray[i];
          
          var r = barHeight + (25 * (i/bufferLength));
          var g = 250 * (i/bufferLength);
          var b = 50;
  
          ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
          ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
  
          x += barWidth + 1;
        }
      }
  
      audio.play();
      renderFrame();
    };
};



.musiquecontainer {
    background: black, url(img/onigirisound.png) center/cover no-repeat;
    width: 100%;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

.musiquecontainer img {
    width: 100px;
    
}

.musique {
    width: 85%;
    padding: 30px;
    background: var(--color6);
    box-sizing: border-box;
    border-radius: 10px;
    display: flex;
    align-items: center;
}

.controls {
    width: 7%;
    height: 7%;
    margin-top: 40px;
    display: flex;
    align-items: center;
  }

.controls img {
    width: 20px;
    margin-right: 20px;
    cursor: pointer;

  }

#button {
    background-image: url(img/play-solid.svg);
    background-color: var(--color6);
    color: var(--color1);
    padding: 16px;
    font-size: 10px;
    border: none;
    cursor: pointer;
  }
  #canvas {
    position: flex;
    left: 0;
    top: 0;
    width: 600px;
    height: 450px;
  }
  
  #audio {
    position: flex;
    left: 10px;
    bottom: 10px;
    width: calc(100% - 20px);
  }



<section class="musiquecontainer">
            <div id="content">
                <div class="musique">
                    <img src="img/onigiri/musique.png">
                    <div class="info">
                        <h1>OnigiSong</h1>
                        <p>Onigiri Music</p>
                    </div>                     
                    <div id="content">
                        <canvas id="canvas"></canvas>
                        <audio id="audio" loop></audio>
                        <div class="controls">
                            <input type="button" id="button">
                            <img src="img/pause-solid.svg" alt="" id="pause">
                            <img src="volume-high-solid.svg" alt="" id="volumebtn">
                        </div>
                      </div>
            </div>
        </section>


On m'a conseillé de mettre ça en .js pour changer le bouton quand on clic mais ça ne marche pas, ça ne mute pas et ça change non plus.


volumebtn.onclick = function(){
    audio.toggleMute()
    if(audio.muted){
        document.getElementById("volumebtn").src="volume-high-solid.svg";
    }else{
      image.src = 'volume-xmark-solid.svg'
    }
}

Modifié par CargoBobMan (23 Sep 2022 - 16:28)
Modérateur
Bonjour,

Plutôt que de changer l'aspect des boutons, il faut mieux avoir un bouton pour chaque fonctionnalité (un bouton "play", un bouton "pause", etc.). Et ensuite, quand on appuie sur un bouton, on affiche ou cache les boutons nécessaires.

Et comme tu décore des boutons avec des images, je suggère d'utilise la balise <button type="button"> au lieu de <input type="button">.

Par exemple (en faisant des modifications a minima), si on crée 4 boutons (play, pause, mute, demute), le html relatifs à ces boutons devient (j'ai ajouté une classe aux boutons pour les styler plus facilement) :
<div id="content">
	<canvas id="canvas"></canvas>
	<audio id="audio" loop></audio>
	<div class="controls">
		<button class="audioBtn" type="button" id="buttonPlay"><img src="img/play-solid.svg" alt="play"></button>
		<button class="audioBtn" type="button" id="buttonPause"><img src="img/pause-solid.svg" alt="pause"></button>
		<button class="audioBtn" type="button" id="buttonMute"><img src="img/mute-solid.svg" alt="mute"></button>
		<button class="audioBtn" type="button" id="buttonDemute"><img src="img/demute-solid.svg" alt="demute"></button>
	</div>
</div>

Dans le js, on rajoute les fonctions gérant ces nouveaux boutons (voir à la fin du js) :
window.onload = function() {
    
    buttonPlay.onclick = function() {
      audio.src = "onigiri_audio.mp3";
      audio.load();
      audio.play();
      var context = new AudioContext();
      var src = context.createMediaElementSource(audio);
      var analyser = context.createAnalyser();
  
      var canvas = document.getElementById("canvas");
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      var ctx = canvas.getContext("2d");
  
      src.connect(analyser);
      analyser.connect(context.destination);
  
      analyser.fftSize = 256;
  
      var bufferLength = analyser.frequencyBinCount;
      console.log(bufferLength);
  
      var dataArray = new Uint8Array(bufferLength);
  
      var WIDTH = canvas.width;
      var HEIGHT = canvas.height;
  
      var barWidth = (WIDTH / bufferLength) * 2.5;
      var barHeight;
      var x = 0;
  
      function renderFrame() {
        requestAnimationFrame(renderFrame);
  
        x = 0;
  
        analyser.getByteFrequencyData(dataArray);
  
        ctx.fillStyle = "#000";
        ctx.fillRect(0, 0, WIDTH, HEIGHT);
  
        for (var i = 0; i < bufferLength; i++) {
          barHeight = dataArray[i];
          
          var r = barHeight + (25 * (i/bufferLength));
          var g = 250 * (i/bufferLength);
          var b = 50;
  
          ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
          ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
  
          x += barWidth + 1;
        }
      }
  
      audio.play();
      renderFrame();
    };
    buttonPause.onclick = function()
		{
			audio.pause();
		};
    buttonMute.onclick = function()
		{
			audio.muted=true;
			buttonMute.style.display="none";
			buttonDemute.style.display="inline-block";
		};
    buttonDemute.onclick = function()
    	{
    		audio.muted=false;
			buttonMute.style.display="inline-block";
			buttonDemute.style.display="none";
    	};
};

Et on modifie le css pour que tout ça s'affiche correctement en remplaçant :
#button {
    background-image: url(img/play-solid.svg);
    background-color: var(--color6);
    color: var(--color1);
    padding: 16px;
    font-size: 10px;
    border: none;
    cursor: pointer;
}
par
.audioBtn {
	display: inline-block;
    background-color: var(--color6);
    color: var(--color1);
    padding: 16px;
    font-size: 10px;
    border: none;
    cursor: pointer;
    outline:10px solid red;
}

#buttonDemute {
	display: none;
}


Amicalement,
Meilleure solution
parsimonhi a écrit :
Bonjour,

Plutôt que de changer l'aspect des boutons, il faut mieux avoir un bouton pour chaque fonctionnalité (un bouton "play", un bouton "pause", etc.). Et ensuite, quand on appuie sur un bouton, on affiche ou cache les boutons nécessaires.

Et comme tu décore des boutons avec des images, je suggère d'utilise la balise &lt;button type="button"&gt; au lieu de &lt;input type="button"&gt;.

Par exemple (en faisant des modifications a minima), si on crée 4 boutons (play, pause, mute, demute), le html relatifs à ces boutons devient (j'ai ajouté une classe aux boutons pour les styler plus facilement) :
&lt;div id="content"&gt;
	&lt;canvas id="canvas"&gt;&lt;/canvas&gt;
	&lt;audio id="audio" loop&gt;&lt;/audio&gt;
	&lt;div class="controls"&gt;
		&lt;button class="audioBtn" type="button" id="buttonPlay"&gt;&lt;img src="img/play-solid.svg" alt="play"&gt;&lt;/button&gt;
		&lt;button class="audioBtn" type="button" id="buttonPause"&gt;&lt;img src="img/pause-solid.svg" alt="pause"&gt;&lt;/button&gt;
		&lt;button class="audioBtn" type="button" id="buttonMute"&gt;&lt;img src="img/mute-solid.svg" alt="mute"&gt;&lt;/button&gt;
		&lt;button class="audioBtn" type="button" id="buttonDemute"&gt;&lt;img src="img/demute-solid.svg" alt="demute"&gt;&lt;/button&gt;
	&lt;/div&gt;
&lt;/div&gt;

Dans le js, on rajoute les fonctions gérant ces nouveaux boutons (voir à la fin du js) :
window.onload = function() {
    
    buttonPlay.onclick = function() {
      audio.src = "onigiri_audio.mp3";
      audio.load();
      audio.play();
      var context = new AudioContext();
      var src = context.createMediaElementSource(audio);
      var analyser = context.createAnalyser();
  
      var canvas = document.getElementById("canvas");
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      var ctx = canvas.getContext("2d");
  
      src.connect(analyser);
      analyser.connect(context.destination);
  
      analyser.fftSize = 256;
  
      var bufferLength = analyser.frequencyBinCount;
      console.log(bufferLength);
  
      var dataArray = new Uint8Array(bufferLength);
  
      var WIDTH = canvas.width;
      var HEIGHT = canvas.height;
  
      var barWidth = (WIDTH / bufferLength) * 2.5;
      var barHeight;
      var x = 0;
  
      function renderFrame() {
        requestAnimationFrame(renderFrame);
  
        x = 0;
  
        analyser.getByteFrequencyData(dataArray);
  
        ctx.fillStyle = "#000";
        ctx.fillRect(0, 0, WIDTH, HEIGHT);
  
        for (var i = 0; i &lt; bufferLength; i++) {
          barHeight = dataArray[i];
          
          var r = barHeight + (25 * (i/bufferLength));
          var g = 250 * (i/bufferLength);
          var b = 50;
  
          ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
          ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
  
          x += barWidth + 1;
        }
      }
  
      audio.play();
      renderFrame();
    };
    buttonPause.onclick = function()
		{
			audio.pause();
		};
    buttonMute.onclick = function()
		{
			audio.muted=true;
			buttonMute.style.display="none";
			buttonDemute.style.display="inline-block";
		};
    buttonDemute.onclick = function()
    	{
    		audio.muted=false;
			buttonMute.style.display="inline-block";
			buttonDemute.style.display="none";
    	};
};

Et on modifie le css pour que tout ça s'affiche correctement en remplaçant :
#button {
    background-image: url(img/play-solid.svg);
    background-color: var(--color6);
    color: var(--color1);
    padding: 16px;
    font-size: 10px;
    border: none;
    cursor: pointer;
}
par
.audioBtn {
	display: inline-block;
    background-color: var(--color6);
    color: var(--color1);
    padding: 16px;
    font-size: 10px;
    border: none;
    cursor: pointer;
    outline:10px solid red;
}

#buttonDemute {
	display: none;
}


Amicalement,


Je sais pas comment te remercier, ça marche parfaitement !! ça faisait 1 semaine que j'étais bloqué. Merci beaucoup Smiley eek Smiley biggrin