I recently signed up for the 30 Day JavaScript Coding Challenge by Wes Bos, and I was blown away by the first installment involving audio files. I’m not sure if I will dive as much in depth on each installment as I did for this one, but it immediately inspired me to play around and make a JavaScript guitar sound controller using what I learned.
The Challenge
In the video, Wes demonstrates how he created a JavaScript Drum Kit. This little mini-project blew me away on many levels.
For starters, I had always assumed (and probably not thought about it much) that one needs a complicated, bloated library to play audio files on a web page. It turns out I was wrong, you can just use an audio
HTML element and give it a src
.
Like Wes explains, one should be aware that not all browsers support the audio
element, although all modern browsers do.
What I Learned
When you listen for the keydown
event in JavaScript, you can access a keyCode
property that indicates which key was pressed by the user. This was central to Wes’s app, since all of the drum sounds are triggered by keyboard input.
I like the idea of using keyboard shortcuts on websites, so this was a good reminder to me that they are not time consuming to implement, and also they are FUN.
The other main takeaway for me was this:
document.querySelector('audio#my-audio').play()
Upon seeing this I thought, “How did I not know this already”…and then I proceeded to pick up my guitar to start making some noises. Based on everything I had seen in the video, I was excited to dice up the sound clips and to be able to manipulate them with JavaScript.
What I Did Differently
Wes’s basic strategy was super simple and solid, but of course I had to tinker around with things a little. This is a tutorial challenge after all, is it not?
To help keep things simple, I am using the word key in the following discussion to refer to the inputs available to the user (i.e. Q
, W
, E
, etc…), which are the triggers that play the different sounds in the app. I also use the word key to encompass the markup and functionality associated with a single user input.
Here are the main things that I did differently/expanded on from the video:
1. Template for key/button elements
Instead of repeating many HTML elements for the keys and using HTML data attributes, I decided to make a repeatable HTML template and then insert JS object data into copies of the template.
I then queried for the template in my JavaScript by targeting its id
attribute:
2. Array to serve as a list of key objects
Each key starts out as an object with just a few properties, and each object will eventually fill a copy of the above template in order to form the HTML for the keys.
I like this approach because if I ever want to expand on the HTML for the key items or give the keys extra properties, then I am set up to quickly do so.
Once unique properties for each key are defined, I add the common functionality to each key using the factory approach.
3. Key factory
The key factory approach is an attempt to generalize the functionality inherent within a single key. For the sake of brevity, I have only shown the parts here that are significantly different from Wes’s example in the tutorial.
Finally, I pass each key through the Key factory by invoking Key.call()
on each item of the keys
array.
4. Onclick and Touchstart
As I was building out my demo based on the video, I noticed that it was virtually impossible to use on my phone’s browser. The issue wasn’t with the audio support, but rather there was no obvious way to get my phone’s keypad to appear while viewing the web page. For this reason, I added listeners for onclick
and touchstart
to enable users to trigger the sounds without using a keyboard.
Other than adding my own sound clips, those are just about all of the things I did different from Wes’s excellent video.
Since I enjoyed this exercise so much, my hope is that the extra steps I took will make it easier for me to do things in the future like add extra sound clips, experiment with looping and other sound alteration techniques, and even create additional mini-apps with different kinds of noises and musical elements.
Demo
Go ahead, rock out a little bit!
Leave a Reply