Webbteknik 2

Laboration 5B

Spela ljud med audio-elementet

Ljud är ett kraftfullt sätt att ge feedback till användaren, särskilt i spel. I denna laboration ska vi lära oss grunderna i hur man hanterar ljud på webben.

0 - Förberedelser

Skapa en ny mapp lab-5b.

  1. Skapa index.html och script.js.
  2. Packa upp arbetsmaterialet för denna laboration i din mapp. Du skall då få en undermapp som heter sound och som innehåller några ljudfiler.

1 - Spela upp ett ljud

Det enklaste sättet att spela upp ett ljud i JavaScript är att använda audio-elementet.

  1. I index.html, skapa en knapp “Spela ljud” och ett audio-element med src="sound/cat.mp3".
  2. I script.js:
    1. Hämta ut refereser till knappen och audio-elementet med document.getElementById eller document.querySelector.
    2. Koppla en klick-lyssnare till knappen som anropar play() på audio-elementet.

Förslag på lösning HTML

<button id="play">Spela ljud</button>
<audio id="sound" src="sound/cat.mp3"></audio>

javascript

const button = document.getElementById("play");
const sound = document.getElementById("sound");
button.addEventListener("click", function () {
  sound.play();
});

2 - Metronom

Nu ska vi kombinera ljud med det vi lärt oss om timers (setInterval) och bygga en enkel metronom.

  1. I index.html:
    1. Lägg till ett audio-element med src="sound/click.mp3" och id="metronom".
    2. Skapa två knappar: “Starta metronom” och “Stoppa metronom”.

Fortsätt sedan i script.js:

  1. Hämta ut refereser till knapparna och audio-elementet (i koden nedan har vi döpt variabeln för audio-elementet till clickSound).
  2. Skapa en variabel bpm (Beats Per Minute) och sätt den intialt till 120.
  3. Räkna ut intervallet i millisekunder: const interval = 60000 / bpm;.
  4. Skapa en funktion playBeat() som spelar ljudet.
    • Obs: För att kunna spela ljudet snabbt igen kan du behöva sätta currentTime = 0 innan du spelar:
      clickSound.currentTime = 0;
      clickSound.play();
      
  5. Använd setInterval för att anropa playBeat med det uträknade intervallet.
Förslag på lösning

HTML

<button id="start">Starta metronom</button>
<button id="stop">Stoppa metronom</button>
<audio id="metronom" src="sound/click.mp3"></audio>

javascript

const start = document.getElementById("start");
const stop = document.getElementById("stop");
const clickSound = document.getElementById("metronom");
let bpm = 60;
let interval = 60000 / bpm;
let intervalId;

function playBeat() {
  clickSound.currentTime = 0;
  clickSound.play();
}

start.addEventListener("click", function () {
  intervalId = setInterval(playBeat, interval);
});

stop.addEventListener("click", function () {
  clearInterval(intervalId);
});

3 - Metronom inställningar

Nu skall vi låta användaren få möjlighet att justera BPM och volymen.

Vi börjar med bpm:

  1. Skapa en <input type="range" id="bpm-input" min="30" max="200" step="1"> i HTML.
  2. Lyssna på input-händelsen på slidern (det eventet körs varje gång användaren justerar värdet i slidern).
  3. I eventhanteraren:
    1. Sätt bpm till värdet från slidern (event.target.value).
    2. Uppdatera intervallet (du måste stoppa den gamla med clearInterval och starta ett nytt).

Vi kan också ändra volymen med egenskapen volume (ett tal mellan 0.0 och 1.0).

  1. Skapa en likadan slider för volymen, med attributen min="0" max="1" step="0.05" i HTML.
  2. Lyssna på input-händelsen på volym-slidern.
  3. I eventhanteraren, sätt sound.volume till värdet från slidern (event.target.value).

Förslag på lösning HTML

<input type="range" id="bpm-input" min="30" max="200" step="1" value="120">
<input type="range" id="volume-input" min="0" max="1" step="0.05" value="1">

javascript

const bpmInput = document.getElementById("bpm-input");
const volumeInput = document.getElementById("volume-input");

bpmInput.addEventListener("input", function (event) {
  bpm = event.target.value;
  interval = 60000 / bpm;
  clearInterval(intervalId);
  intervalId = setInterval(playBeat, interval);
});

volumeInput.addEventListener("input", function(event) {
  clickSound.volume = event.target.value;
});

4 - Utmaning - jobba vidare

  1. Som du själv kanske redan märkt så blir det bananas om man klickar “Starta metronom” flera gånger utan att stoppa den först. Fixa detta genom att kontrollera om en interval redan är igång. Det kan du göra antigen genom att kolla om intervalId har ett värde, eller genom att skapa en separat variabel för att hålla koll på om metronomen är igång eller inte, t.ex. isPlaying.
  2. Skapa ett element som visualiserar metronomen. Du kan använda transform: rotate tillsammans med transition. För varje tick kan du växla mellan två värden i rotate för att få elementet rotera fram och tillbaka. Du kan även sätta transform-origin för att få elementet rotera runt en annan punkt än mitten.