JavaScript 30 – Day 1: JavaScript Drum Kit

Written by Thorsten Frommen

Thorsten is a certified PHP engineer, web development professional and tester. He has been working on the web since 2000, and with (and on) WordPress since 2005. Thorsten is a Senior WordPress Engineer at Human Made.

Objective

On Day 1, the task is to build a JavaScript drum kit. In essence, this should allow to be played via some predefined keys, which are also displayed on the screen.

The provided starter files include an HTML file that contains both the UI and the <audio> tags, a CSS file that takes care of all the styling, and all the sounds that will be used for the drum kit. This means the only missing part is the JavaScript code to actually make the drum kit play (and indicate the pressed key).

I stopped the video right after the objective has been made clear, and started implementing it on my own.

Conception

Thinking about how to bring this drum kit to life, I wrote down some comments to outline how the code could look like. I’m not sure if you can call this four-liner comment-driven development, though. 🙂

Implementation

First off, I never did anything with <audio> elements before. I did, however, have in mind their interface was pretty straightforward, so I basically expected a simple .play() method, or similar. To find out, I read my way through <audio> to HTMLAudioElement to HTMLMediaElement, and guess what: audio.play() it is. 😀

The above code does pretty much exactly what the comment already included. I set up a single keydown event handler that grabs the according <audio> element and plays it, and adds the playing class to the <div> element so the styling kicks in. Removing the classes is handled by individual timers for each key.

One thing that I didn’t like very much was that I couldn’t play one and the same audio element (and thus file) again if it was still playing. So I searched for some .stop() or .rewind() method, but I couldn’t find any. 🙁

Refinement

Feeling somewhat OK with the above code, I continued the video to see how Wes realized the drum kit.

Improvement number one was fixing the thing that I didn’t like: quickly playing a sound multiple times. The solution is to set the (public) property currentTime of the <audio> element to 0, and thus rewind the sound. When I looked through the documentation, I honestly didn’t look at the properties at all. I guess this is thanks to me being a PHP developer with a passion for (writing and using) proper object-oriented code as well as immutable objects. 😉

Next, Wes talked about using setTimeout() to remove the playing class (and thus styling), which is exactly what I did. However, Wes didn’t seem to like it very much, because he wanted the <div> to have the class only as long as the CSS transition lasts. This can be done by using an individual transitionend event handler for each <div> element.

My final code looks like the following, which is almost my original code, with the addition of rewinding a sound before playing it (again):

first of all, as you already know, I didn’t watch the whole video, but started right after the introduction. That’s why I didn’t know about Wes wanting the second transition to directly follow after the first one.

For me, having the key box highlighted is all there is to it. And I didn’t think about, nor do I think it necessary having a single in—out transition sequence.

I hope that makes sense.

BTW, on another day, I of course made use of the transitionend event. And I would’ve done here as well, if the objective had clearly included to have a single smooth transition. 😉

in the above code, I never initialize a variable and redefine (i.e., set) its value later on. With ES6, there are two new ways to define a variable, one of which is const. If this is news to you, you might want to have a look at this and that post.

Jimmy

Hi! Thx for your nice posts, really inspiring! I was experimenting a bit with adding a click event to the drums as well, that is when you click the boxes with the mouse it plays the sound. I didn’t get it right… at all. Do you have any suggestions or quick tips?