How To Build a JavaScript Drum Kit using Event Listeners 🥁

Let's learn to build a drum kit on your browser using JavaScript. However, the drums won't be drummed, but typed! We'll be using event listeners to accomplish this. If you're not already aware of what they are, I'll be explaining them to you and providing various examples as well.

This is what our completed project will look like. Every time the user clicked the displayed keys, the appropriate beats will be played. If the CSS doesn't look very appealing to you, I highly recommend you customize it yourself once you've built the project!

JavaScript Drum Kit - shivankjshacker.hashnode.dev

What are event listeners?

Event listeners are just functions in JavaScript that listen for events that occur on the web page and respond accordingly. These events include -

  • Mouse clicks

  • Mouse hovers

  • Key presses

  • Page loading

  • Page resizing

  • ...and many more

Example:

/* Method 1

<button id="clickBtn" onclick="alert('Clicked')">Click me</button>

*/

// Method 2

document.getElementById('clickBtn').onclick = () => alert('Clicked')

// Method 3

document.getElementById('clickBtn').addEventListener('click', () => {
    alert('Clicked')
})

In this example, when the HTML element with the ID "myButton" is clicked, the event listener triggers an anonymous function that displays an alert saying "Button clicked!".

By using event listeners, developers can enhance the interactivity of web pages, handle user inputs, and create responsive applications.

If you're enjoying this article and have already learnt something new, I'd highly recommend you click on the favourite button and write a helpful comment. It would greatly support me in reaching out and helping more people!

Setting up the HTML & CSS

  1. Go over to my drum kit repository on GitHub.

  2. Download all the files from the images and sounds folder and add them to your images and sounds folders in your main project folder.

  3. Make a new file called index.html at the root of the project folder. Paste the following code in it:

    ```xml <!DOCTYPE html>

    Drum Kit

    Drum 🥁 Kit

    Press me to activate drum kit!

    w a s d j k l
Made by Shivank Mitra


4. As you might've noticed, we need a *styles.css* file. Make it and paste the following code in. If you make some changes and it looks a lot better, link your GitHub repo in the comments, I'd love to see it!

    ```css
    body {
      text-align: center;
      background-color: #283149;
    }

    h1 {
      font-size: 5rem;
      color: #DBEDF3;
      font-family: "Arvo", cursive;
      text-shadow: 3px 0 #DA0463;

    }

    p {
      color: #DBEDF3;
      font-family: 'Arvo', cursive;
      font-size: 1.5rem;
      padding: 4px 10px;
    }

    p:hover {
      color: #dcdc18;
      cursor: pointer;
    }

    a {
      text-decoration: none;
      color: yellow;
    }

    footer {
      color: #DBEDF3;
      font-family: sans-serif;
    }

    .w {
      background-image: url("images/tom1.png");
    }

    .a {
      background-image: url("images/tom2.png");
    }

    .s {
      background-image: url("images/tom3.png");
    }

    .d {
      background-image: url("images/tom4.png");
    }

    .j {
      background-image: url("images/snare.png");
    }

    .k {
      background-image: url("images/crash.png");
    }

    .l {
      background-image: url("images/kick.png");
    }

    .set {
      margin: 10% auto;
    }

    .pressed {
      box-shadow: 0 3px 4px 0 #DBEDF3;
      opacity: 0.5;
    }

    .red {
      color: red;
    }

    .drum {
      outline: none;
      border: 10px solid #404B69;
      font-size: 5rem;
      font-family: 'Arvo', cursive;
      line-height: 2;
      font-weight: 900;
      color: #DA0463;
      text-shadow: 3px 0 #DBEDF3;
      border-radius: 15px;
      display: inline-block;
      width: 150px;
      height: 150px;
      text-align: center;
      margin: 10px;
      background-color: white;
    }

JS-ifying

Create a script.js file and add the following starter code in it.

let buttons = document.querySelectorAll('.drum')
let p = document.querySelector('p')
let keyArr = ['w', 'a', 's', 'd', 'j', 'k', 'l']
let soundArr = ['tom-1', 'tom-2', 'tom-3', 'tom-4', 'snare', 'crash', 'kick-bass']

On the first and second lines, we're querying the document for the .drum class and the p element and saving them in variables called buttons and p.

Next, we're storing a list of the keys that we will want to listen to keydown events from in an array called keyArr. Also, we're storing the names of the sound files for further use in an array called soundArr.

We need to enable the user to activate the drum kit now. Let's add that in:

p.addEventListener('click', (e)=>{
    if (p.classList[0] == 'unactive') {
        p.textContent = 'Press me to deactivate drum kit!'
    } else {
        p.textContent = 'Press me to activate drum kit!'
    }
    p.classList.toggle('unactive')
    p.classList.toggle('active')
})

We're adding an event listener to p to listen to clicks from the user. If the p element already has a class called unactive, then we change the text to entice the user into pressing the button and vice-versa. Then we use the toggle() function that adds or removes a class of an element depending on whether or not it is already there.

Next, we need to listen to keydown events of the user. Let's add that code in:

document.addEventListener('keydown', (e)=>{
    if (keyArr.includes(e.key.toLowerCase())) {
        if (p.classList[0] == 'active') {
            let indexOfKey = keyArr.indexOf(e.key.toLowerCase())
            playMusic(indexOfKey)
            animate(keyArr[indexOfKey])
        } else {
            alert('Activate Drum Kit first!')
        }
    }
})

The following code listens to keydown events. It checks if keyArr contains that particular key that got pressed. Following that, if the program is in the active state (check the last section), we store the index of the key that is pressed using the indexOf() function. Then, we execute the playMusic() and animate() functions. However, we haven't made these functions yet. Let's make them now!

function playMusic(index) {
    let audio = new Audio('sounds/'+soundArr[index]+'.mp3')
    audio.play()
}

This audio code might be new to you. What we're doing is: we're creating a new Audio object. We're initializing it with our sound file. We are getting the name of the sound file from the soundArr array, by accessing the index we obtained in our event listener. Next, we simply play the audio using the .play() function.

Adding Animation ✨

Add this function at the bottom of your code file:

function animate(char) {
    let btn = document.querySelector('.'+char)
    btn.classList.add('pressed')

    setTimeout(()=>{
        btn.classList.remove('pressed')
    }, 100)
}

We're simply accessing the button which has the same class as the character which got pressed on the keyboard. Next, we add the pressed class to it. This class contains different styles. Check styles.css for these extra styles. We are using the setTimeout() function to remove the class after an interval of 100 milliseconds or 0.1 seconds, which I have found to be the most ideal for this animation.

Voila! Run the code and start hammering at your keyboard!

Here's the finished code:

let buttons = document.querySelectorAll('.drum')
let p = document.querySelector('p')
let keyArr = ['w', 'a', 's', 'd', 'j', 'k', 'l']
let soundArr = ['tom-1', 'tom-2', 'tom-3', 'tom-4', 'snare', 'crash', 'kick-bass']

p.addEventListener('click', (e)=>{
    if (p.classList[0] == 'unactive') {
        p.textContent = 'Press me to deactivate drum kit!'
    } else {
        p.textContent = 'Press me to activate drum kit!'
    }
    p.classList.toggle('unactive')
    p.classList.toggle('active')
})

document.addEventListener('keydown', (e)=>{
    if (keyArr.includes(e.key.toLowerCase())) {
        if (p.classList[0] == 'active') {
            let indexOfKey = keyArr.indexOf(e.key.toLowerCase())
            playMusic(indexOfKey)
            animate(keyArr[indexOfKey])
        } else {
            alert('Activate Drum Kit first!')
        }
    }
})

function playMusic(index) {
    let audio = new Audio('sounds/'+soundArr[index]+'.mp3')
    audio.play()
}

function animate(char) {
    let btn = document.querySelector('.'+char)
    btn.classList.add('pressed')

    setTimeout(()=>{
        btn.classList.remove('pressed')
    }, 100)
}

Thanks for reading! I hope you enjoyed this article and learnt something new. I would really appreciate you clicking the favourite button and giving me some much-needed feedback in the comments section. Also, if you're interested in more JS, check out my blog and keep learning!