Metrônomo com JavaScript

Metrônomo com JavaScript

Tulio Faria
Tulio Faria26 de maio de 2017
O metrônomo um dispositivo que deixa uma batida constante e ajuda os músicos a manterem um ritmo quando estão treinando. Esse ritmo pode aumentar ou diminuir de acordo com a escolha do músico.
Teremos um HTML simples, e primeiro vamos criar um input type range para gerar uma barra que será onde vamos controlar a velocidade do nosso metrônomo. Nele conseguimos colocar qual o valor mínimo e qual o valor máximo. Vamos pegar o do google como exemplo, o mínimo será 40 e o máximo 218. Um value inicial e um ID para conseguirmos recuperar este valor.
Em seguida, vamos colocar o áudio que será tocado (no meu caso tenho um clap.wav e um botão play para controlar o metrônomo).

<html> <head> <tittle>Metronomo</tittle> </head> <body> <input type="range" min="40" max="218" value="40" id="bpm"/> <audio src="clap.wav"></audio> <button id="play">Play</button> </body> <html>

Ele ficará assim:
Exemplo 1
Também é interessante colocarmos antes do input um H1 com o número inicial de batida que está configurado.

<h1>40bpm</h1>

Feito isso, podemos começar a adicionar um pouco de comportamento. Vamos colocar o script no corpo do HTML mesmo, pois a intenção no exemplo é só demonstrar como poderíamos reconstruir o metrônomo.
Toda vez que trocar o valor do range tem que ser trocado o que está escrito em H1. Então vamos pegar o BPM e o H1. Toda vez que o BPM mudar, ou seja, dar um change, o h1 tem que mudar também. Lembrando que essa técnica de colocar todos os seletores em cima é chamada de cash.
Primeiro faremos um teste com um valor fixo criando uma função que faz o play. Vamos chamá-la de tick e um intervalo fixo, que em sequência vamos resolver.
Nessa função tick, temos que pegar o áudio

<script> const bpm = document.getElementById('bpm') const h1 = document.querySelector('h1') const play = document.getElementByld('play') const.audio = document.querySelector('audio') let currentBpm = 40 function tick(){ audio.currentTime= 0 audio.play() } bpm.addEventListener('change', function(){ h1.innerHTML = this.value + ' bpm' currentBpm = parseInt(this.value) }) play.addEventListener('click', function(){ const timer = setInterval(tick, 100) }) </script>

Agora vamos pensar um pouco: Se precisamos ter 40 batimentos por minuto e o minuto tem 60 segundos, 60 segundos tem 60 mil milissegundos, temos que distribuir 40 batidas dentro de 60 mil, então vamos dividir isso no valor do Bpm, ficando assim:

play.addEventListener('click', function () { const timer = setInterval(tick, (60 * 1000) / currentBpm) })

Precisamos agora de uma forma para desligar essa batida, para isso vamos usar declarar o let isPlaying, o timer, e um if para, caso ele estiver tocando, darmos um clearInterval nesse timer.

<script> const bpm = document.getElementById('bpm') const h1 = document.querySelector('h1') const play = document.getElementByld('play') const.audio = document.querySelector('audio') let currentBpm = 40 let isPlaying = false let timer = null function tick(){ audio.currentTime= 0 audio.play() } bpm.addEventListener('change', function(){ h1.innerHTML = this.value + ' bpm' currentBpm = parseInt(this.value) }) play.addEventListener('click', function(){ if(isPlaying){ clearInterval(timer) } else { const timer = setInterval(tick, (60*1000)/currentBpm) } isPlaying = !isPlaying }) </script>

Uma vez que estartamos o timer, ele começa a tocar. Ao clicar novamente, ele para, pois carrega na página com valor null. Ao clicarmos, damos um valor para ele e clicando de novo ele cai no isPlaying = !isPlaying que faz ele voltar a Null. Chamamos isso de toggle.
Também podemos trocar o texto do botão para play caso esteja tocando e Stop para quando estiver parado. Perceba que, ao apertar o play, ele começa a tocar apenas no próximo tick, pois o setInterval demora esse tick. Podemos fazer ele começar já com esse tick.

play.addEventListener('click', function () { if (isPlaying) { play.innerHTML = 'Play' clearInterval(timer) } else { tick() play.innerHTML = 'Stop' const timer = setInterval(tick, (60 * 1000) / currentBpm) } isPlaying = !isPlaying })

Para esse valor atualizar sempre que mudamos o range, temos que fazer um if, que vai limpar o intervalo e começar um novo valor baseado no cálculo.

bpm.addEventListener('change', function () { h1.innerHTML = this.value + ' bpm' currentBpm = parseInt(this.value) if (isPlaying) { clearInterval(timer) timer = setInterval(tick, (60 * 1000) / currentBpm) } })

Com isso, acabamos de construir um metrônomo.
Essa é uma ideia do que se pode construir com javaScript e HTML. Algumas outras ideias faremos posteriormente.
Confira o passo a passo em vídeo:
9M7OY47OFzg
Assistir vídeo
Curta o DevPleno no Facebook, inscreva-se no canal e não se esqueça de cadastrar seu e-mail para não perder as novidades. Abraço!
Tulio Faria
Autor
Tulio Faria26 de maio de 2017

Últimas do Blog