My First JavaScript Practice: Building a Drum Kit
Tags: webdev, javascript, beginners, frontend
Published: 2023-04-11 11:38:32

This is my first JavaScript practice and I’ll be learning how to build the Drum Kit from Wes Bos JavaScript 30 Playlist.

The Drum Kit project is a web-based application that allows users to play different drum sounds using their keyboard. The application consists of various drum sounds mapped to different keys on the keyboard. When a user presses a key on their keyboard, the corresponding drum sound plays, and an animation is displayed to indicate which key was pressed.

The application is built using Tailwind CSS and JavaScript. Tailwind CSS is used to create the user interface, while JavaScript is used to handle the logic behind the application.

{% embed https://vimeo.com/816487776#t=5 %}

## Logic Behind the Process

The logic behind the Drum Kit project is relatively straightforward. First, we need to create the HTML and CSS to display the user interface. Then we need to map the different drum sounds to specific keys on the keyboard. Finally, we need to write the JavaScript code to handle the user input and play the corresponding sound when a key is pressed.

To map the drum sounds to specific keys on the keyboard, we use the data-key attribute in HTML. We assign each drum sound a unique data-key value, and we assign each key on the keyboard a unique keyCode value. When a user presses a key on the keyboard, we check the keyCode value of the key to determine which drum sound to play.

To play the drum sound, we use the Audio object in JavaScript. We create an instance of the Audio object for each drum sound and store it in a variable. When a key is pressed, we use the data-key value to determine which Audio object to play.

To display the animation when a key is pressed, we use CSS. We create a custom class in CSS that applies the desired animation to the element, and we add this class to the element using JavaScript when a key is pressed. We then remove the class after a short delay to reset the animation.

## Step-by-Step Process

Now let's dive into the step-by-step process of building the Drum Kit project.

### Step 1: Create the HTML and CSS

The first step is to create the HTML and CSS to display the user interface. We will create a div for each drum sound and assign each div a unique data-key value. We will also create a custom CSS class to apply the animation to the div when a key is pressed.

We will create an audio element for each drum sound and assign each audio element a unique data-key value. We will also add the audio file for each drum sound. Each audio file is located in the sounds folder located in the same directory as my HTML file.

``` html
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <link rel="stylesheet" href="./dist/output.css">
   <link rel="icon" href="https://fav.farm/✅" />
   <title>Beat Maker</title>
</head>

<body class="antialiased bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-rose-100 to-teal-100">
   <!-- Container for the Keys -->
   <div class="flex gap-2 h-screen items-center justify-center place-items-center px-3">
       <!-- Key # -->
       <div data-key="65" class="key">
           <kbd>A</kbd>
           <span class="sound">CLAP</span>
       </div>
       <!-- Key # -->
       <div data-key="83" class="key">
           <kbd>S</kbd>
           <span class="sound">HIHAT</span>
       </div>
       <!-- Key # -->
       <div data-key="68" class="key">
           <kbd>D</kbd>
           <span class="sound">KICK</span>
       </div>
       <!-- Key # -->
       <div data-key="70" class="key">
           <kbd>F</kbd>
           <span class="sound">OPENHAT</span>
       </div>
       <!-- Key # -->
       <div data-key="71" class="key">
           <kbd>G</kbd>
           <span class="sound">BOOM</span>
       </div>
       <!-- Key # -->
       <div data-key="72" class="key">
           <kbd>H</kbd>
           <span class="sound">RIDE</span>
       </div>
       <!-- Key # -->
       <div data-key="74" class="key">
           <kbd>J</kbd>
           <span class="sound">SNARE</span>
       </div>
       <!-- Key # -->
       <div data-key="75" class="key">
           <kbd>K</kbd>
           <span class="sound">TOM</span>
       </div>
       <!-- Key # -->
       <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 src="./index.js"></script>
</body>
</html>

```

### Step 2: Create the JavaScript Code to Play the Sound and Show Animation

The next step is to create the JavaScript code to handle the user input and play the corresponding sound. We will use the Audio object to play the sound and add and remove the CSS class to display the animation.

``` javascript
// code to play the corresponding audio file when a key is pressed

function playSound(e) {
    // select an audio element that matches the corresponding data-key
    const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
    // select the key element for animations
    const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
    // stops the function from running if the key pressed has no associated data-key
    if(!audio) return
    // reset sounds so it can play on multiple taps without delay
    audio.currentTime = 0;
    audio.play();
    key.classList.add('playing');
}

```

I created a function to listen for a keydown event. A Keydown event happens when the key is pressed down, and auto repeats if the key is pressed down for long. The code listens for a keydown event and matches the keyCode value to the corresponding div element and Audio object using the querySelector method.

We then check if an Audio object exists for the key that was pressed. If no Audio object exists, we exit the function using the return statement. Otherwise, we set the currentTime property of the Audio object to 0 and call the play method to play the sound. The currentTime allows me to play a sound repeatedly without any delays. I also added the custom class(playing) to the div element using the classList.add method to display the animation.

### Step 3: Create the JavaScript Code to Stop the Animation After the Key is Pressed

The problem after creating the code above was that the animation still stays after the key is pressed. One cannot tell if the key pressed is repeated or not. Thus creating the need to add a code that removes the playing class after the key is pressed.

{% embed https://vimeo.com/816487077 %}

I tried the code in the practice and faced a bug where the animation was stuck on multiple presses. Thanks to the Youtube community and StackOverflow, I found a better way to do that with the Keyup event.

``` javascript
// code to stop transition after button is pressed

// listens for when a pressed key is released
window.addEventListener('keyup', function(e) {
   const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
   // stops the function from running if the key pressed and released has no associated data-key
   if (!key) return;
   // removes the playing class when the pressed key is released
   key.classList.remove('playing');
})

```
The code listens for a keyup event and removes the class of playing. I also added a return statement in case the wrong key is pressed.

---

This is the first of many practices I will be doing within a few months. My goal is to be good at JavaScript. I understand I can never be perfect and I will need to keep learning. However, I want to build muscle memory around this and understand how to logically approach every issue.

**_TIME TO FOCUS ON MY NEXT PRACTICE!!!_**