Triggering Audio w/ Vanilla JS — Building a Drum Rack!

Jordan Panasewicz
4 min readMay 28, 2021

There are a lot of use cases where triggering audio can come in handy… whether that’s a simple sound effect to let a user know that something worked (or didn’t), or building something audio centric like a drum rack or a sound board.

Today we are going to build a super simple drum rack using Vanilla JavaScript. Here’s a quick demo:

Vanilla JS Drum Rack Demo Video

First let’s set up our environment.. in your terminal create and navigate into a new folder:

take vanilladrumrack

Then create the couple of files we will need:

touch index.html index.html index.css

And create a folder for your sounds:

mkdir sounds

The first thing I did was get some sounds ready for action. As a music producer I had plenty of samples sitting around to choose from, but if you don’t I recommend going to YouTube, search for several sounds, and use a converter such as https://ytmp3.cc/youtube-to-mp3/ to convert your sounds. Try searching for things like “808 kick sample”, “808 snare sample”, “808 hat sample” etc. *808 is a model of drum kit made by Roland, and made popular by hip hop and electronic music.*

Once you have some sounds downloaded, drop them into your sounds folder, and open the project file in your code editor.

I’ve named my sounds as such, where chat means closed hi hat, and ohat means open hi hat.

Now setting up our HTML:

  1. Link your CSS and JS to your HTML by including this in your HTML templates head:
<link rel="stylesheet" href="index.css" /><script defer src="index.js"></script>

2. Create html audio elements for each sound you’ve downloaded, do this at the bottom of the body section. The data-key input will be what signifies which key on the keyboard triggers each sound:

<audio data-key="65" src="sounds/Kick.wav"></audio><audio data-key="83" src="sounds/chat1.wav"></audio><audio data-key="68" src="sounds/snare.wav"></audio><audio data-key="70" src="sounds/ohat.wav"></audio><audio data-key="71" src="sounds/clap.wav"></audio><audio data-key="72" src="sounds/ride.wav"></audio><audio data-key="74" src="sounds/tom1.wav"></audio><audio data-key="75" src="sounds/tom2.wav"></audio><audio data-key="76" src="sounds/crash.wav"></audio>

3. Above the audio elements, create a div for your keys, each key will have it’s own div with the matched data-key number, as well as a class of key. In each div, we will include a <kbd></kbd> element, which define a keyboard input. The kbd element simply shows the keyboard character associated with that div, and hence that sound. Lastly, we will include a <span></span> element with class=”sound”, and the name of the sound as content to display.

<div class="keys">  <div data-key="65" class="key">    <kbd>A</kbd>    <span class="sound">kick</span>  </div>  <div data-key="83" class="key">    <kbd>S</kbd>    <span class="sound">hihat</span>  </div>  <div data-key="68" class="key">    <kbd>D</kbd>    <span class="sound">snare</span>  </div>  <div data-key="70" class="key">    <kbd>F</kbd>    <span class="sound">openhat</span>  </div>  <div data-key="71" class="key">    <kbd>G</kbd>    <span class="sound">clap</span>  </div>  <div data-key="72" class="key">    <kbd>H</kbd>    <span class="sound">ride</span>  </div>  <div data-key="74" class="key">    <kbd>J</kbd>    <span class="sound">tom1</span>  </div>  <div data-key="75" class="key">    <kbd>K</kbd>    <span class="sound">tom2</span>  </div>  <div data-key="76" class="key">    <kbd>L</kbd>    <span class="sound">crash</span>  </div></div>

The JavaScript & CSS Magic:

This part is surprisingly simple.

  1. We set up a couple of event listeners, one on the main window to watch for keydowns to trigger a sound. The other on each key to watch for keydowns to trigger a visual effect. In our index.js file:
const keys = Array.from(document.querySelectorAll(".key"));keys.forEach((key) => key.addEventListener("transitionend", removeTransition));window.addEventListener("keydown", playSound);

2. Create our functions to trigger a sound, and to trigger our visual effect. Below our event listeners:

function playSound(e) {const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);const key = document.querySelector(`div[data-key="${e.keyCode}"]`);if (!audio) return;key.classList.add("playing");audio.currentTime = 0;audio.play();}function removeTransition(e) {if (e.propertyName !== "transform") return;e.target.classList.remove("playing");}

Now our sounds are playing! We just need to add some CSS to create the visual effect as well, and feel free to add a backdrop, or change the flavor as you see fit!

3. Here’s the styling I’ve included in my CSS file. It is specifically the playing class’s transform and colors that are creating the visual effect you see in my clip.

@import url("https://fonts.googleapis.com/css2?family=Nerko+One&family=Pacifico&display=swap");body {font-size: 10px;background: url(https://i.imgur.com/vtuJKo5.jpeg);background-size: 100%;/* background-size: contain; */background-repeat: no-repeat;margin: 0;padding: 0;font-family: sans-serif;}h1 {font-family: "Nerko One", cursive;font-family: "Pacifico", cursive;font-size: 40px;margin-left: 2rem;color: rgb(255, 255, 255);}.keys {display: flex;flex: 1;min-height: 100vh;align-items: flex-start;justify-content: center;}.key {border: 0.9rem #ffc3bf;border-radius: 1rem;margin: 1rem;font-size: 1.5rem;padding: 1rem 0.5rem;transition: all 0.07s ease;width: 10rem;text-align: center;color: #ffffff;background: rgba(0, 0, 0, 0.3);text-shadow: 0 0 0.5rem pink;}.playing {transform: scale(1.3);border-color: #ff61f4;box-shadow: 0 0 1rem #d761ff;}kbd {display: block;font-size: 4rem;}.sound {font-size: 1.2rem;text-transform: uppercase;letter-spacing: 0.1rem;color: #ffe8e7;}

That’s it! Run your code using lite-server or whatever choice you may prefer… Have some fun why dontcha?!

If you simply want to fork & clone my repo and play around, feel free to access it here: GitHub Repo for VanillaDrumKit.

Cheers, I’ll see you again soon!

--

--

Jordan Panasewicz

Denver, CO based. Software Sales turned Software Engineer.