[ Javascript 30] Programming An 808s & Heartbreak-Inspired Drum Kit
By: Nicholas Echevarria
Tags: Kanye West, JavaScript, Javascript30, Programming

On my journey to better understand Vanilla Javascript, I came across Wes Bos’ Javascript 30 Challenge. It’s simple: there are 30 different projects solely built with Vanilla Javascript, complete with starter files, completed files, and video tutorials explaining Wes’ approach at completing the challenge.

To be a better programmer, I have to program, right? I’m watching each video once and attempting to solve it until I absolutely need to refer to the video or the internet for an answer. And while Javascript 30 is meant to be done in 30 days, I’m aiming to take my time and really absorb everything I’m learning.

The first challenge is to create Vanilla Javascript single page application that functions as a drum kit. It’s a bit generic, though, so I have some stretch goals that include stylizing it to reflect the aesthetic and sound of Kanye West’s seminal 808s & Heartbreak. Let’s get started.

Spinning Up A Vanilla JS Project

The great thing about Vanilla Javascript is how simple it is. Let’s begin by creating an index.html. Functioning as the first file that’s analyzed by the server, it’s essentially a home page. In this single page application, it’s the entire application.

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>JS Drum Kit</title>

<link rel="stylesheet" href="style.css">

</head>

<body> <div class="keys">

<div data-key="65" class="key">

<kbd>A</kbd>

<span class="sound">clap</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">kick</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">boom</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">snare</span>

</div>

<div data-key="75" class="key">

<kbd>K</kbd>

<span class="sound">tom</span>

</div>

<div data-key="76" class="key">

<kbd>L</kbd>

<span class="sound">tink</span>

</div>

</div> <audio data-key="65" src="sounds/clap.wav"></audio>

<audio data-key="83" src="sounds/hihat.wav"></audio>

<audio data-key="68" src="sounds/kick.wav"></audio>

<audio data-key="70" src="sounds/openhat.wav"></audio>

<audio data-key="71" src="sounds/boom.wav"></audio>

<audio data-key="72" src="sounds/ride.wav"></audio>

<audio data-key="74" src="sounds/snare.wav"></audio>

<audio data-key="75" src="sounds/tom.wav"></audio>

<audio data-key="76" src="sounds/tink.wav"></audio> <script> </script> </body>

</html>

This sets up a page this page:

But I want this project to be my own thing, so we’re going to change this up a bit to reflect the aesthetic inspiration:

We have to account for two more keys as well, so our index.html is going to slightly change:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>808's + JS</title>

<link rel="stylesheet" href="style.css">

</head> <body>

<div class="keys">

<div data-key="65" id="first-instrument" class="key">

<kbd>A</kbd>

<span class="sound">boom</span>

</div>

<div data-key="83" id="second-instrument" class="key">

<kbd>S</kbd>

<span class="sound">clap</span>

</div>

<div data-key="68" id="third-instrument" class="key">

<kbd>D</kbd>

<span class="sound">hihat</span>

</div>

<div data-key="70" id="fourth-instrument" class="key">

<kbd>F</kbd>

<span class="sound">kick</span>

</div>

<div data-key="71" id="fifth-instrument" class="key">

<kbd>G</kbd>

<span class="sound">openhat</span>

</div>

<div data-key="72" id="sixth-instrument" class="key">

<kbd>H</kbd>

<span class="sound">ride</span>

</div>

<div data-key="74" id="seventh-instrument" class="key">

<kbd>J</kbd>

<span class="sound">snare</span>

</div>

<div data-key="75" id="eight-instrument" class="key">

<kbd>K</kbd>

<span class="sound">tink</span>

</div>

<div data-key="76" id="ninth-instrument" class="key">

<kbd>L</kbd>

<span class="sound">tom</span>

</div>

<div data-key="186" id="tenth-instrument" class="key">

<kbd>;</kbd>

<span class="sound">boom2</span>

</div>

<div data-key="222" id="eleventh-instrument"class="key">

<kbd>'</kbd>

<span class="sound">clap2</span>

</div>

</div> <audio data-key="65" src="sounds/boom.wav"></audio>

<audio data-key="83" src="sounds/clap.wav"></audio>

<audio data-key="68" src="sounds/hihat.wav"></audio>

<audio data-key="70" src="sounds/kick.wav"></audio>

<audio data-key="71" src="sounds/openhat.wav"></audio>

<audio data-key="72" src="sounds/ride.wav"></audio>

<audio data-key="74" src="sounds/snare.wav"></audio>

<audio data-key="75" src="sounds/ride.wav"></audio>

<audio data-key="76" src="sounds/snare.wav"></audio>

<audio data-key="186" src="sounds/tink.wav"></audio>

<audio data-key="222" src="sounds/tom.wav"></audio> </body>

</html>

Now, on to the Javascript.

Programming the Drum Kit

To start, we’ll need to add an eventListener to the window in order to register key presses:

window.addEventListener(‘keydown’, playSound);

Let’s define that playSound function:

function playSound(e) {

const audio = document.querySelector(`audio[data key="${e.keyCode}"]`);

const key = document.querySelector(`div[data-key="${e.keyCode}"]`); if (!audio) return; // skip if no audio is found key.classList.add('playing');

audio.currentTime = 0;

audio.play();

}

With this function, we add a class of playing so that a CSS transition can be applied, set the audio file’s currentTime to 0 so that we can tap on a button multiple times in a second without having to wait for the file to finish, and then run the .play method unique to audio elements.

Afterward, we need to remove the playing class. First, we create an array from the list of instruments:

const keys = Array.from(document.querySelectorAll('.key')); keys.forEach(key => key.addEventListener('transitionend', removeTransition));

Then, define removeTransition():

function removeTransition(e) {

if (e.propertyName !== 'transform') return;

e.target.classList.remove('playing');

}

And that’s it! With that last step wrapped up, you can now play basic sounds with your keyboard. My stretch goals for this project include inputting elements of Kanye West songs from the album 808s &Heartbreak to customize this tool and allow users to create their own melodies. I’m excited!