medium

Вжух, вжух! Добавляем звук меча на любой странице

Время дурацких проектов.

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

Чтобы магия сработала, двигать мышкой нужно резко, потому что медленный меч не издаёт звука.

Логика программы

  1. Загружаем нужный звук на страницу.
  2. Начинаем отслеживать все движения мыши.
  3. Если резко — проигрываем звук меча.

Теперь сделаем всё по шагам.

Загружаем звук на страницу

Чтобы воспроизвести звук на странице, используют объект audio. С ним можно работать через JavaScript. Главное, что нужно сделать, — это указать путь к требуемому файлу.

Для ускорения работы мы сразу подгрузим его на страницу. Он будет висеть в памяти и в нужный момент воспроизведётся без задержки.

// Создаём новый аудиообъект на странице
var audio = new Audio();
// Подготавливаем звук, чтобы он сразу был готов к воспроизведению
audio.preload = 'auto';
// Указываем путь к аудиофайлу
audio.src = 'http://thecode.local/wp-content/uploads/2020/02/ninja-sword.mp3';

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

Следим за мышью

Наша задача — получить текущие координаты мыши. Кроме этого, нам нужно следить за временем, которое прошло с момента последнего движения. Суть в том, что зная время и расстояние, которое прошёл курсор, можно понять, с какой скоростью он двигался. Это нам понадобится на следующем этапе, поэтому сосредоточимся пока на координатах и времени. Сразу заведём нужные переменные:

// Переменные для отслеживания времени и координат мыши var timestamp = null; var lastMouseX = null; var lastMouseY = null;

Чтобы всегда быть в курсе, что мышь начала двигаться, добавим обработчик этого события. Всё остальное будем прописывать внутри него:

document.body.addEventListener("mousemove", function(e) {}

С этого момента скрипт сам будет следить за тем, двигается мышь или нет. Если двигается — скрипт выполнит то, что написано внутри обработчика.

Когда обработчик запустится первый раз, он не сможет посчитать расстояние, которое прошёл курсор, потому что он не запомнил начальную позицию и не засёк время. Исправим это:

// Если мы ещё не начали следить за временем…
if (timestamp === null) {
  // …то запоминаем текущее время 
  timestamp = Date.now();
  // и запоминаем координаты мыши
  lastMouseX = e.screenX;
  lastMouseY = e.screenY;
  // На первый раз сделали всё, что нужно, возвращаем управление назад 
  return;
}

Теперь у нас есть все данные, чтобы узнать пройденное расстояние и время. Логика простая: мы получаем свежие координаты и текущее время, находим разницу с предыдущими и получаем то, что нам нужно:

// Тут мы будем хранить текущее время
var now = Date.now();
// Тут — сколько времени прошло с момента последнего шевеления мышки
var dt = now - timestamp;
// А в этих двух переменных — расстояние по Х и У, которые прошёл курсор
var dx = e.screenX - lastMouseX;
var dy = e.screenY - lastMouseY;

Смотрим, быстрое движение или нет

Меч свистит в воздухе только при быстрых движениях, поэтому мы тоже должны посчитать скорость движения курсора по экрану. Для этого используем формулу из физики: скорость = расстояние / время.

К этому моменту мы знаем оба параметра, поэтому спокойно можем найти скорость курсора по каждой оси:

// Скорость — это расстояние, делённое на время. Сделаем отдельные переменные для скорости по Х и У
var speedX = Math.round(dx / dt * 100);
var speedY = Math.round(dy / dt * 100);
// Берём текущее время
timestamp = now;
// Запоминаем текущие координаты мыши
lastMouseX = e.screenX;
lastMouseY = e.screenY;

Последнее, что нам осталось сделать, — решить, какую скорость считать быстрой. Нам нравится число 400, но вы можете увеличить его, если вам нужен максимально быстрый меч.

Обратите внимание, что мы используем функцию модуля Math.abs(), когда работаем со скоростью. Дело в том, что при движениях снизу вверх и справа налево скорость будет отрицательной, потому что ноль находится в левом верхнем углу. Чтобы у нас скорость была всегда положительной, используем модуль числа — это такое же число, но без знака минус.

// Если скорость была больше 400 по любой оси — включаем звук меча     
if ((Math.abs(speedX) > 400) || ( Math.abs(speedY) > 400)) { audio.play(); };

// Создаём новый аудиообъект на странице
var audio = new Audio();
// Подготавливаем звук, чтобы он сразу был готов к воспроизведению
audio.preload = 'auto';
// Указываем путь к аудиофайлу
audio.src = 'http://thecode.local/wp-content/uploads/2020/02/ninja-sword.mp3';
// Переменные для отслеживания времени и координат мыши
var timestamp = null;
var lastMouseX = null;
var lastMouseY = null;
// Добавляем новый обработчик события, который следит за каждым движением мыши
document.body.addEventListener("mousemove", function (e) {
  // Если мы ещё не начали следить за временем…
  if (timestamp === null) {
    // …то запоминаем текущее время и дату
    timestamp = Date.now();
    // и запоминаем координаты мыши
    lastMouseX = e.screenX;
    lastMouseY = e.screenY;
    // На первый раз сделали всё, что нужно, возвращаем управление назад 
    return;
  }
  // Тут мы будем хранить текущее время
  var now = Date.now();
  // Тут — сколько времени прошло с момента последнего шевеления мышки
  var dt = now - timestamp;
  // А в этих двух переменных — расстояние по Х и У, которые прошёл курсор
  var dx = e.screenX - lastMouseX;
  var dy = e.screenY - lastMouseY;
  // Скорость — это расстояние, делённое на время. Сделаем отдельные переменные для скорости по Х и У
  var speedX = Math.round(dx / dt * 100);
  var speedY = Math.round(dy / dt * 100);
  // Берём текущее время
  timestamp = now;
  // Запоминаем текущие координаты мыши
  lastMouseX = e.screenX;
  lastMouseY = e.screenY;
  // Если скорость была больше 400 по любой оси — включаем звук меча
  if ((Math.abs(speedX) > 400) || (Math.abs(speedY) > 400)) { audio.play(); };
});

Как запускать

Точно так же, как и снежинки — используем инъекцию скрипта. Берите этот код, открывайте консоль браузера, вставляйте.

<span style="font-weight: 400;">var js = document.createElement('script'); 
js.src = "https://thecode.media/wp-content/uploads/2020/02/ninja_snd.js"; 
document.body.appendChild(js);</span>

Если нужно встроить этот код через исходный код страницы, используйте обычный импорт скрипта:

<span style="font-weight: 400;"><
script src="https://thecode.media/wp-content/uploads/2020/02/ninja_snd.js"></script>
</span>

Апскиллинг, как говорится
Апскиллинг — это, например, переход с уровня junior на уровень middle, а потом — senior. У «Яндекс Практикума» есть курсы ровно для этого: от алгоритмов и типов данных до модных фреймворков.
Изучить вопрос
Апскиллинг, как говорится Апскиллинг, как говорится Апскиллинг, как говорится Апскиллинг, как говорится
Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
medium