Веб-приложения являются обычным явлением, но веб-приложения, не требующие доступа в Интернет, — нет.

В этой статье я покажу вам, как я сделал счетчик BPM на простой HTML-странице в сочетании с ванильным javascript (см. здесь). Если этот виджет загружен, его можно использовать в автономном режиме — он идеально подходит для музыкантов, которые хотят творить, но не всегда имеют доступ в Интернет. Более того, с помощью приложения панели инструментов OSX (которое раньше никогда не казалось таким полезным) мы можем сделать этот счетчик BPM очень быстрым в использовании.

🔗 Получите код счетчика BPM на Github 📔

Как это должно выглядеть?

Очевидно, что ответ на вопрос зависит от мнения. Моя позиция заключается в том, что он должен быть очень простым и делать только то, что нужно счетчику BPM: подсчитывать удары в минуту. Поэтому все, что нужно, это кнопка и значение счетчика.

Логика

Оценить BPM так же просто, как измерить время между двумя последовательными ударами и подсчитать, сколько из них вы могли бы уместить в минуту.

let prev_click = new Date(); 
const getBPM = function (){
 const currentTime = new Date();
 const interval = (currentTime - prev_click)/1000;
 const bpm = 60/interval;
 prev_click = currentTime;
 return bpm;
} 
get_bpm(); // e.g. 120

Я пошел дальше, усредняя 3 предыдущих удара следующим образом:

const averaging = 3;
const prev_bpms = [60];
const getBPM = function() {
 const currentTime = new Date();
 const interval = (currentTime - prev_click) / 1000;
 const bpm = 60 / interval;
 prev_click = currentTime;
 while (prev_bpms.length > prev_bpm_list_max_length) {
    prev_bpms.shift();
 }
 prev_bpms.push(bpm);
 average_bpm = prev_bpms.reduce((acc, cVal) => acc + cVal) / prev_bpms.length;
 return bpm;
} 

get_bpm(); // e.g. 120

Кроме того, не все хотят нажимать кнопку, а, может быть, вместо этого клавишу:

// space bar trigger
window.addEventListener('keypress', (e) => {
 if(e.code === 32) getBPM();
});
// instant ability
document.querySelector('.clicker button').focus();

Теперь пользователи также могут нажать пробел, как только страница загрузится.

Услышьте свой BPM

Вы нажали на свой BPM, но теперь хотите воспроизвести его, чтобы поджемовать в своем любимом темпе.

Для этого мы должны издать звук. Но как? У нас есть два встроенных в браузер Аудио API варианта: использовать звуковой файл или создать синтезатор.

Сначала мы воспользуемся синтезатором для создания звукового сигнала:

const AudioContext = window.AudioContext || window.webkitAudioContext;
let context, oscillator;
const bpm = 60;
const bpmInterval = 60/bpm * 1000; //ms
setInterval(beep, bpmInterval);
const beep = function (){
      if(!context) context = new AudioContext();
      oscillator = context.createOscillator();
      oscillator.type = "sine";
      oscillator.start(0);
      oscillator.connect(context.destination);
      setTimeout(oscillator.disconnect, 150, context.destination);
    }

Теперь давайте сделаем то же самое, используя вместо этого аудиофайл:

const click = new Audio('./cowbell.mp3');
const bpm = 60;
const bpmInterval = 60/bpm * 1000; //ms
setInterval(beep, bpmInterval);
const beep = function (){
      click.play();
      setTimeout(()=>{ 
          click.pause(); 
          click.currentTime = 0.0;
        }, 150);
    };

Наконец, добавляем логику, которая их контролирует:

// HTML
<div class="player">
        <button class="controler" onclick="togglePlayerOutput()">
          &#9654;
        </button>
</div>

// JS
let isPlayerPlaying = false;
let bpmRepeaterId;
const togglePlayerOutput = function (){
        const button = document.querySelector('.player button');
        if (!isPlayerPlaying){
          button.innerHTML = '&#9724;';
          bpmRepeaterId = setInterval(beep, bpmInterval);
        }
        else{
          button.innerHTML = '&#9654;';
          clearInterval(bpmRepeaterId);
        }
        isPlayerPlaying = !isPlayerPlaying;
    };

Собираем все вместе

Теперь, объединив все функции и добавив немного стилей (которые я не буду объяснять), у нас есть этот конечный продукт:

Я не знаю, сколько кода люди действительно хотят видеть непосредственно в статье, поэтому полный код ищите на Github.

Эффективное использование (только для пользователей OSX)

Если вы раньше использовали Mac, вы, возможно, наткнулись на родное приложение Dashboard, но, вероятно, не задержитесь надолго.

Я никогда не использовал его… до сих пор.

В Safari вы можете щелкнуть правой кнопкой мыши на странице, что иногда вызывает всплывающее окно выбора действия, включая открыть на панели управления…

Нажав на нее, вы увидите создателя виджета веб-страницы. Вы можете выбрать часть страницы, которую хотите добавить на панель инструментов. Это довольно крутая функция, но для нашего случая это супер крутая функция.

Открыв счетчик BPM, который мы только что создали, вы можете выбрать следующее поле:

Теперь используйте сочетание клавиш F12. БУМ. Еще никогда не было так просто создавать виджеты самостоятельно, быстро и легко.

Вам может быть интересно, почему в этом нет функции воспроизведения метронома. Когда я попытался использовать его на приборной панели, программа не смогла надежно воспроизвести звук :( Но, по крайней мере, Logic может легко сделать эту часть.

И причина, по которой я показал вам, как создавать звуки двумя разными способами, заключается в том, что версия Audio Context с использованием синтезатора не будет работать внутри приборной панели.

Наконец, вы не можете просто нажать F12 и перейти к использованию пробела, чтобы получить темп, вы должны нажать кнопку напрямую, что является понижением.

Но я думаю, что теперь я могу делать маленькие виджеты именно так. Если у вас есть классные идеи для этого, покажите мне, когда вы их реализовали :)

🔗 Получите код счетчика BPM на Github 📔

Спасибо за чтение

Посетите T3chFlicks.org для более технологичного образовательного контента (YouTube, Instagram, Facebook, Twitter).