Java, UX, HTML, CSS, WEB-design

Как создать отзывчивую 8-битную драм-машину, используя веб-аудио, SVG и мультитач

Краткое описание по статье Как создать отзывчивую 8-битную драм-машину, используя веб-аудио, SVG и мультитач

Название: Как создать отзывчивую 8-битную драм-машину, используя веб-аудио, SVG и мультитач . Краткое описание: [ad_1] ⭐ Дэвид Р . Дата публикации: 03.02.2022 . Автор: Алишер Валеев .

Для чего создан сайт Novosti-Nedeli.ru

Данный сайт посвящен новостям мира и мира технологий . Также тут вы найдете руководства по различным девайсам.

Сколько лет сайту?

Возраст составляет 3 года

[ad_1]

  • Дэвид Руссе

  • 0 Комментарии

Как создать отзывчивую 8-битную драм-машину, используя веб-аудио, SVG и мультитач

  • 9 минут чтения

  • Программирование, инструменты, SVG, веб-аудио

Краткое резюме ↬

В этом небольшом уроке я поделюсь некоторыми советами, которым я недавно следовал, чтобы создать забавную демонстрацию для Сборка 2016 конференция. Идея состояла в том, чтобы создать небольшую 8-битную драм-машину с 8-битными звуками и графикой: это небольшое веб-приложение использовалось в одной из наших демонстраций, чтобы проиллюстрировать, как вы можете легко обеспечить временный автономный режим, когда ваше размещенное веб-приложение теряет Интернет. подключение. Он работает во всех настольных браузерах, а также на всех смартфонах (iOS, Android и Windows Mobile).

В этом небольшом руководстве я поделюсь некоторыми советами, которым я недавно следовал, чтобы создать забавную демонстрацию для конференции Build 2016. Идея заключалась в том, чтобы создать небольшую 8-битную драм-машину с 8-битными звуками и графикой:

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

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

Дальнейшее чтение на SmashingMag:

  • Воссоздание терменвокса с помощью JS и веб-аудио API
  • Рекомендации по дизайну со звуком
  • Как улучшить рабочий процесс и снизить стресс с помощью звуков природы
  • Плейлисты Spotify для поддержки ваших сеансов кодирования и дизайна

Еще после прыжка! Продолжить чтение ниже ↓

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

Варианты обработки проверки попаданий

Рассмотрим изображение, использованное в демонстрации чуть ниже. Я построил его, понизив исходное изображение до 8-битного, как часть нашей маленькой ретро-шутки. Полный онлайн-опыт обеспечит лучшую графику и звук, в то время как офлайн-опыт предложит ухудшенную 8-битную версию.

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

У пожилых людей среди нас может возникнуть соблазн использовать карта изображенийс map и area теги. Мы можем определить области изображения с различными геометрическими формами, включая эллипсы и круги. Это может помочь.

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

  • Это на основе пикселей, поэтому он не будет масштабироваться для разных разрешений и устройств. Предположим, ваше растровое изображение имеет фиксированный размер 600 × 400 пикселей. Если бы вы определили области внутри него, вы бы построили их на основе этого разрешения 600 × 400. Как только вы расширяете или сжимаете изображение, чтобы оно соответствовало разрешению устройства, области больше не будут соответствовать изображению. Плагин jQuery RWD Image Maps будет динамически вычислять координаты области. Но я подумал, что добавление библиотеки jQuery и этого плагина только для этой простой демонстрации для проверки попаданий было бы слишком. Я искал что-то попроще.
  • Функция была изначально определено для включения навигации по URL-адресам. Я бы предпочел вызвать функцию JavaScript, чтобы использовать веб-аудио для воспроизведения звуков. Тем не менее, вы можете использовать этот прием, определив href="#" и регистрация события щелчка в области.

Следующей моей идеей было поместить его в 2D холст, который я мог растянуть до текущего разрешения с помощью CSS. Это решение может работать, но это будет очень сложная реализация для такого простого веб-приложения. Действительно, это повлечет за собой:

  • ручное определение зон попадания по коду;
  • обработка события щелчка на холсте, определение точных координат мыши x и y для щелчка и масштабирование до текущего разрешения;
  • вычисляя алгоритм проверки попаданий, проверяя, находятся ли эти 2D-координаты в одном из эллипсов, которые мы определили в коде.

Это не очень сложно, но это довольно сложная математика для чего-то, что должно быть просто построить. Кроме того, если вы хотите сохранить соотношение сторон изображения, метод 2D-холста также влечет за собой изменение размера холста путем вычисления в коде соотношения на этапе загрузки и внутри окна. onresize событие.

Наконец, я подумал о том, что должно быть самым очевидным решением. Когда вы думаете о том, что масштабируется на устройствахоблегчает проверка на попадание и ручки соотношение сторонответ естественно SVG. «S» означает «масштабируемый» — мы можем определить окно просмотра с некоторыми параметрами, чтобы зафиксировать соотношение сторон.

Конечно, но вы, вероятно, спросите: «Как это поможет нам определить зоны попадания на изображении?» Не говоря уже о том, что мы работаем с растровым изображением, а не с вектором?

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

Сохраните изображение 8-битной драм-машины на своем компьютере.

Нам нужен инструмент, который будет сгенерировать XML нашего SVG содержание. Я буду использовать InkScape, бесплатное приложение, но вы, вероятно, можете сделать то же самое с SVG Edit в браузере.

Откройте Inkscape, перейдите в «Файл» → «Свойства документа» и измените значения «Нестандартный размер» на 160 × 90.

Перейдите в «Файл» → «Импорт» и выберите 8bitsdrummachine.jpg файл, который вы сохранили. Выберите «Ссылка» в качестве типа импорта и оставьте остальные параметры без изменений. Затем растяните изображение, чтобы отобразить нашу зону рисования:

Создание небольшой 8-битной адаптивной драм-машины с использованием веб-аудио, SVG и мультитач-изображения

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

Создание небольшой 8-битной адаптивной драм-машины с использованием веб-аудио, SVG и мультитач-изображения

Эти семь эллипсов будут нашими зонами поражения.

Чтобы иметь возможность легко найти эти формы SVG в нашем коде, щелкните правой кнопкой мыши каждую из них, выберите «Свойства объекта» и измените его свойства «ID» и «Метка» на button1 (вплоть до button7) и #button1 (вплоть до #button7), соответственно:

Создание небольшой 8-битной адаптивной драм-машины с использованием веб-аудио, SVG и мультитач-изображения

Теперь, когда мы точно определили зоны поражения, давайте сделаем их прозрачный, а не прятать их под изображением. Щелкните правой кнопкой мыши на каждом из них, выберите «Заливка и обводка» и установите значение альфа («А») на 0:

Создание небольшой 8-битной адаптивной драм-машины с использованием веб-аудио, SVG и мультитач-изображения

Примечание: Здесь мы используем простые эллипсы, но вы можете нарисовать любую сложную форму, разрешенную SVG, поверх изображения, чтобы добиться аналогичного результата.

Сохранить результат на жестком диске, выбрав в меню «Файл» → «Сохранить как…».

Откройте этот файл в своем любимом редакторе (Notepad++, Sublime, Visual Studio Code и т. д.) и добавьте следующую строку XML сразу после viewBox атрибут:

preserveAspectRatio="xMidYMin meet"

Документация Mozilla объясняет, что делает этот атрибут SVG.

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

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

Что насчет веб-аудио?

Я уже подробно рассказывал о веб-аудио в другом месте. Я повторно использую часть этого кода, включая Sound объект:

var Sound = (function () {
    function Sound(url, audioContext, masterGain, loop, callback) {
        this.url = url;
        this.audioContext = audioContext;
        this.masterGain = masterGain;
        this.loop = loop;
        this.callback = callback;
        this.gain = this.audioContext.createGain();
        this.gain.connect(this.masterGain);
        this.isReadyToPlay = false;
        this.loadSoundFile(url);
    }
    Sound.prototype.loadSoundFile = function () {
        if (canUseWebAudio) {
            var that = this;
            // make XMLHttpRequest (AJAX) on server
            var xhr = new XMLHttpRequest();
            xhr.open('GET', this.url, true);
            xhr.responseType = 'arraybuffer';
            xhr.onload = function (e) {
                // decoded binary response
                that.audioContext.decodeAudioData(this.response,
                function (decodedArrayBuffer) {
                    // get decoded buffer
                    that.buffer = decodedArrayBuffer;
                    that.isReadyToPlay = true;
                    if (that.callback) {
                        that.callback();
                    }
                }, function (e) {
                    console.log('Error decoding file', e);
                });
            };
            xhr.send();
        }
    };
    Sound.prototype.play = function () {
        if (canUseWebAudio && this.isReadyToPlay) {
            // make source
            this.source = this.audioContext.createBufferSource();
            // connect buffer to source
            this.source.buffer = this.buffer;
            this.source.loop = this.loop;
            // connect source to receiver
            this.source.connect(this.gain);
            // play
            this.source.start(0);
        }
    };
    return Sound;
})();

Затем, как я уже объяснял в другом месте, нам нужно обрабатывать веб-аудио особым образом для iOS, разблокировав AudioContext:

try {
    if (typeof AudioContext !== 'undefined') {
        audioContext = new AudioContext();
        canUseWebAudio = true;
    } else if (typeof webkitAudioContext !== 'undefined') {
        audioContext = new webkitAudioContext();
        canUseWebAudio = true;
    }
    if (/iPad|iPhone|iPod/.test(navigator.platform)) {
        this._unlockiOSaudio();
    }
    else {
        audioUnlocked = true;
    }
15.} catch (e) {
    console.error("Web Audio: " + e.message);
17.}
18. 
19.function unlockiOSaudio() {
    var unlockaudio = function () {
        var buffer = audioContext.createBuffer(1, 1, 22050);
        var source = audioContext.createBufferSource();
        source.buffer = buffer;
        source.connect(audioContext.destination);
        source.start(0);
        setTimeout(function () {
            if ((source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE)) {
                audioUnlocked = true;
                window.removeEventListener('touchend', unlockaudio, false);
            }
        }, 0);
    };
    window.addEventListener('touchend', unlockaudio, false);
}

Обработка мультитач на разных устройствах

На мой взгляд, лучшая сенсорная спецификация для Интернета — это события указателя. Я уже подробно описал спецификацию. Мы будем использовать его для подключения нашего обработчика событий к нашим фигурам SVG.

В приведенном ниже коде мы имеем в виду все фигуры SVG, которые мы создали с помощью InkScape, — фигуры, с которыми мы связали идентификаторы (button1, button2, и т.д.). Затем мы загружаем различные 8-битные звуки с веб-сервера и декодируем их через наш Sound объект. Наконец, с помощью pointerdown событие, мы воспроизводим каждый звук, связанный с каждой формой SVG:

var soundsCollection = [];
var buttonsCollection = [];

    buttonsCollection.push(document.getElementById("button1"));
    buttonsCollection.push(document.getElementById("button2"));
    buttonsCollection.push(document.getElementById("button3"));
    buttonsCollection.push(document.getElementById("button4"));
    buttonsCollection.push(document.getElementById("button5"));
    buttonsCollection.push(document.getElementById("button6"));
    buttonsCollection.push(document.getElementById("button7"));

if (canUseWebAudio) {
    masterGain = audioContext.createGain();
    masterGain.connect(audioContext.destination);
    soundsCollection.push(new Sound("./8bits_sounds/clap.wav", audioContext, masterGain, false, newSoundLoaded));
    soundsCollection.push(new Sound("./8bits_sounds/cowbell.wav", audioContext, masterGain, false, newSoundLoaded));
    soundsCollection.push(new Sound("./8bits_sounds/hihat1.wav", audioContext, masterGain, false, newSoundLoaded));
    soundsCollection.push(new Sound("./8bits_sounds/kick1.wav", audioContext, masterGain, false, newSoundLoaded));
    soundsCollection.push(new Sound("./8bits_sounds/snare1.wav", audioContext, masterGain, false, newSoundLoaded));
    soundsCollection.push(new Sound("./8bits_sounds/tom1.wav", audioContext, masterGain, false, newSoundLoaded));
    soundsCollection.push(new Sound("./8bits_sounds/kick3.wav", audioContext, masterGain, false, newSoundLoaded));
}

var soundsLoaded = 0;

function newSoundLoaded() {
    soundsLoaded++;
    if (soundsLoaded == 7) {
        // Ready to rock & roll!
        for (var i = 0; i < 7; i++) {
            buttonsCollection[i].addEventListener("pointerdown", onPointerDown);
        }
    }
}
function onPointerDown(eventArgs) {
    var buttonClicked = eventArgs.currentTarget.id;
    var soundId = buttonClicked.substr(buttonClicked.length - 1) - 1;
    var soundToPlay = soundsCollection[soundId];
    soundToPlay.play();
}

С помощью этого кода мы поддерживаем мультитач простым способом. Но у него есть один недостаток: он работает только в браузере Microsoft Edge. Для поддержки всех браузеров и устройств вы можете использовать Polyfill событий указателя на основе jQuery.

<script src="https://code.jquery.com/pep/0.4.1/pep.min.js"></script>

Добавьте следующее свойство к элементу HTML, содержащему соответствующий пользовательский интерфейс (элемент body элемент в нашей демонстрации):

touch-action="none"

Идем дальше с синтезом

В этой небольшой демонстрации я скачал записанные образцы 8-битных звуков. Но у веб-аудио есть несколько замечательных функций, которые могут помочь вам генерировать звуки с помощью осцилляторов, например, как объясняет Крис Лоуис на Dev.Opera.

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

Эта статья является частью серии веб-разработок от технических евангелистов и инженеров Microsoft, посвященных практическому изучению JavaScript, проектам с открытым исходным кодом и передовым методам взаимодействия, включая браузер Microsoft Edge.

Мы рекомендуем вам проводить тестирование в разных браузерах и на разных устройствах, включая Microsoft Edge — браузер по умолчанию для Windows 10 — с помощью бесплатных инструментов на сайте dev.microsoftedge.com, включая инструменты разработчика F12 — семь отдельных, полностью документированных инструментов, которые помогут вам отлаживать, тестировать и ускорить ваши веб-страницы. Кроме того, посетите блог Edge, чтобы быть в курсе событий и получать информацию от разработчиков и экспертов Microsoft.

Сокрушительная редакция
(мс, иль, ал)



[ad_2]
Source: https://smashingmagazine.com

Заключение

Вы ознакомились с статьей — Как создать отзывчивую 8-битную драм-машину, используя веб-аудио, SVG и мультитач

Пожалуйста оцените статью, и напишите комментарий.

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован.

Кнопка «Наверх»