Build A Piano With JavaScript - Tutorial
Key Takeaways
Builds a piano using JavaScript and HTML
Full Transcript
Hello everyone. Today is going to be an exciting video cuz we're going to be building a piano entirely with JavaScript and you can check it out right up there. That's me playing the intro to Yankee Doodle which I somehow remember from fifth grade. I don't know why but either way, let's get into this video and actually make this piano. Welcome back to Web Dev Simplified. My name's Kyle and my job is to simplify the web for you. So, if that sounds interesting, make sure you subscribe to the channel for more videos just like this one. And now, as you can see on the right-hand side here, we have the finished product of the piano. We can click any of these keys and we can also play these keys with the keyboard if we want, which is in my opinion a lot easier. It's more like playing the real piano. And now, to get started creating this, the first thing that we need to do is we need to download all of the notes for the piano. I have all of these in the GitHub repository linked in the description of this video, but it's also pretty easy to find these types of files online and download them for free or even just record your own. So, with that out of the way, the next thing we need to do is create our index.html file. So, let's just create that index.html. Make sure it's in the root of our directory just like that. And now, we can just type exclamation point and hit enter and that's going to create all of the boilerplate code for us when it comes to setting up this HTML file. The next thing we need to do is just give it a title. We'll call it piano. And then, we're going to have a style sheet as well as a JavaScript page. So, we're going to need to come in here and we're going to want to add in a link. So, we'll just say link and this is going to be for styles.css which we're going to create in just a little bit. And we're also going to need a script tag which is just going to be script.js. We just want to make sure that we defer this so that it loads after all of the body of our HTML. Now, let's just create those files real quick. We have styles.css and we have script.js. And that's all the different files that we're going to need. Now we can actually work on designing the HTML for our piano, which is actually very straightforward. All we have are these different keys. We have white and black, and they're going to be inside of a piano container, which is going to center it on the screen. So let's first create a div, which is just called piano. So now we have a class of piano, and we have our div, and inside of here is where we're going to put all of our different keys. So for example, our first key inside of here, we're just going to give it a class, which is key, which all of our different keys are going to share. And then next, we're going to make this a white key. As you can see, it's our white key, which is the first one. Our next key is a black one, so we're just going to copy this, and we're going to put black in here. And one other thing that I need to note is that we want to make sure we say which note each of these keys are. So we're going to put a data note on here, and this is going to be the name of the file essentially that this is linking to. As you can see, we have A, A flat, B, B flat, and so on. And this very first key for us is just going to be our C key. And we want this to be on all of our divs, so let's copy this down onto our black key, and this black key here is just going to be a D flat. And what we need to do is just copy this down, so we have the exact structure of our piano over here. So I'm just going to copy this down. That's this key, this key, this key, this key, this key, this key, this key, this key, this key, and finally this key. So let's come in here. We have white, and then black, and then we have white, followed by another white key, and then we have black, followed by a white key, followed by a black key, followed by a white, then black, and then finally our one last white key. And as for our notes, we have D, D flat, and here we have E, and we have E flat, and then we have our F, which is going to go into our G flat, our G, our A, oops, A flat, sorry, and then A, and then here B flat, and finally B. And that's all of our different notes set up, as well as all of our different classes for our different keys. But, in order to play these sounds, we need to have audio tags for each one of our note files here. Because right now, we can't access these files unless they're in our HTML. So, we can do is just create an audio tag. And this audio tag is going to have an ID, which is going to match this data note. So, in our case, this will be C for our C key here. Then, we just want to put the source. This is going to be inside of our notes folder, and this is going to be our c.mp3, just like that. And then, we'll close off our audio. And we need one of these for each one of our keys. So, we're just going to copy this down a bunch of times. For example, we'll have D flat here, then D, E. We have E flat. Oops. F. We want G flat. G. A flat. A. Two more times. B flat and B. And we also need to make sure that copy's here. So, we have D flat. D. E. E flat. F. G flat. G. A flat. A. B flat and B. I'm sure that was riveting to watch me type. And also, while I was typing that, I noticed I had my E and E flat keys here flipped. So, let's make sure we fix that here, and then we'll just change it down here as well. It doesn't really matter if these are in order, but it's nice to have them in the same order as what's up here. Now, with that done, we have all of our HTML taken care of. As I said, it's really simple HTML. It's just going to be this right here. And if we open this with live server, by right clicking and open with live server, it's going to show up on the right here. And of course, it's going to be completely blank, cuz all of these are empty divs. And now, we need to actually work on our styles to make this work. And if you don't have this open with live server pop up, it's actually an extension for Visual Studio Code that you can download and then you can use just like I am. It allows it so that every time we make a change, it's going to refresh over here automatically. So the first thing I like to do in almost every style sheet is make sure to select every type of element. So in our case, we have our before, our after, and our wildcard selector. And I just want to change the box sizing here. Oops, to be border-box. This just makes working with widths and heights so much easier. The next thing that I want to do is actually set up the body. So we can select our body here and we want to set that cool blue background color that you saw. I've just copied this over. It's 143F6B. And if we save that, you can see we get that blue background color, which looks really nice. We also want to remove any margins on our body. We want to set the minimum height here to be 100 view height. This is going to make it so it's possible to center our piano in the middle. And then also to do the centering, we're going to use display flex, justify my content center, and align items in the center. And if you're unfamiliar with how flexbox and display flex works, I have an entire video on it. You can check out linked in the cards and description below. Now, let's actually work on the piano. And the thing that we need to do in here is make sure we change to display flex. This way all of our keys will line up next to each other instead of on top of each other up and down. We want them to be side by side. So display flex is going to do that for us. Now the next thing we have is our key selector as well as our white class and our black class here. And I'm going to start with the white class actually because it'll make it really easy to figure out what we need to do in the black class and then what we have to share between them. So the first thing I want to do inside of here is I want to set our width. And in our case, I'm just going to set the width here to be 100 pixels. And then we also need to set the height. And I'm just going to set the height to be four times the width. So now we have 400 pixels. And to make something actually show up, let's just change the background color here to white. And as you can see, we have this blob where all of our keys are. And if we want to see the distinction between them, we can put a border of 1 pixel solid, and let's just use this 333 color. It's kind of a dark gray. And now you can see all of our white keys right next to each other, which is perfect. The next thing we need to work on is adding in the black keys, and it's going to be very similar. I'm just going to actually copy this code, and I'm going to change the background color here to be black. And of course, we want to change this height. I'm just going to change it to 60 pixels and 240 pixels. So, it's about half the size of the white key. And we don't need the border on these because they're already black. And if we save that, you can see our keys are showing up, but they're spaced out from each other. We want the black keys to show up on top of the white keys. And a really easy way to do that is to make the margin left and the margin right be negative. So, we can change the margin right here and the margin left, and we want them to be the same amount negative. So, we can just take this width here and divide it by two. So, we'll say -30 pixels on the left and -30 pixels on the right. And as you can see, that's made it so that the black keys are showing up over top of our white keys, which is what we want. And to make it so that they show up over all the white keys, we can just change the Z index here to be two, for example. And now it's going to show up over top of our black keys. Obviously, this piano does not quite look like this piano though. So, it looks like we're missing one of our white keys. If we go into our HTML here, we can see that we accidentally capitalized this white here. So, if we now we save that, you can see that extra white key has shown up. And we have all of the keys inside of our piano exactly where they need to be with our styles right here. But you'll notice there's quite a bit of shared and duplicated code between these. For example, our width is always 1/4 of our height, and our margin left and margin right are going to be half of our width. So, what we can do inside of this key is we can actually set the height to be based on a variable, which is the width. So, we can see our height is going to be a calculation. And we're going to get a variable, so we just have to say var {dash} {dash}, and then this variable is called width. We just want to multiply that by four, cuz our height is four times our width, and then our width is just going to be set to that width variable. And this is using CSS variables. I have an entire video on these, so if you want to check that out, it's going to be in the cards and the description down below. Now, what we can do is we can change this width to our variable of width, and we can get rid of the height. We can also do the same thing with the black keys, get rid of the height, and if we save, you see that still works just as it did before. Everything is in the right positions. Also, we can change this margin left and margin right to be a calculation, which takes into account our width. And we just want to divide it by negative two. Essentially, we want half of our width, and we want it to be negative. So, let's copy that down here, save, and you see it still looks exactly the same. But we were able to clean up a lot of our code by putting all that shared logic in the key class, and making sure we can change our width at any time. For example, I could change this to be 80, and now all the keys resize, and everything looks perfectly fine, other than the fact this piano looks ridiculous. So, going back here to 100, and we're back to a much better looking piano. And that's all of the styling for the piano. We finally get to move on to the fun part, which is the JavaScript, where we can actually make the piano work. Now, the first thing that we need to do is to get all of the keys as elements. So, we can just create a variable here called keys, and we just want to do document.querySelectorAll. We want to get everything which has a class of key, so we can just say {dot} key. This is going to be all of our key elements. Then we can loop over those, so we can say keys.forEach, and what we want to do is for each key, we want to run this function. And inside of here, we're just going to add an event listener. And we want to do this whenever we click on the key. And all we want to do is run a function, which is going to call a function called play note with our key. And we're going to create this play note function. Essentially, it's going to play the audio for our note, and it's passing in the key that we want to play, for example, our element here. So, let's create that function, which is going to be called play note, and it's going to take in a key, like I mentioned earlier. Now, the first thing we want to do is we want to get the audio element from our HTML here based on the data note property for the key that we pressed. So, in order to do that, we can say our note audio is going to be equal to document. Whoops, .getElementById. And we're going to pass it the ID from that data set. So, we know data set.note is going to be equal to our ID. It essentially corresponds to this value right here. It is C, D flat, which all correspond to an ID down here. So, now we actually have our audio element inside this note audio variable, and we can just call .play on this. And now, what we can do is we can come over to our piano, and when we click on a key, it's actually going to play that sound. But we do have a small bug. If I click this really, really fast, for example, to play a note over and over again, it's only going to play it as soon as the audio file ends. It won't stop the audio file and restart it from the beginning, unlike a normal piano would. So, in order to get around that, we can do is we can take our note audio, and we want to do is change the current time to be zero. Essentially, it's restarting the file at the beginning, and then replaying it. So, if we save that, and now I click a key a bunch of times, it's going to play that sound over and over and over again right from the beginning, like a normal piano would. One thing you probably noticed though, is when I click on a key, it doesn't actually show me any form of animation. I can't tell I'm clicking on it. There's no press state. So, what we want to do is add a class to our key when we click on it. So, when the audio starts playing, we want to say key.classList.add and we're going to add an active class to our key. And then inside of our style sheet, we can just say for our white keys for example, we want to change our background color to be just a really off white. So, we'll say CCC. And then inside of our black keys, oops, black keys, we can do the same thing, but we'll just do an off black color. In this case, 333. Now, if we save that, we click a key, you can see that it has changed color both for black and for white, but that color is not going away. We need to remove the active class when the note is done playing. So, we can do is we can set up an event listener. We just say add event listener and we want to say ended. This is going to fire as soon as the audio clip finishes playing. And we just want to run inside of here key.classList.remove and we want to remove active. Now, when we click on a key, it's going to be active and as soon as it ends, it's going to go away and no longer be active. So, it's going to remove the color. The last thing we have left to do though, is to actually make it so we can play the piano using our keyboard. And what we need to do is determine which keys we want to use in order to play each note. So, what I like to do is I just want to use a row of keys on the very bottom because they are arranged kind of like a piano. They have keys above them that are about 50% of the way between each key, which kind of simulates the black notes. So, in order to save you the boredom of watching me type out all of these different letters, you can see we have a variable with all of our white keys and this is going to be essentially the bottom row of your keyboard, every single letter in it. And then the black keys is going to be the row above that which correspond with where these black keys would align on that row of your keyboard. And now all we need to do is set up a event listener that's going to listen to when we press these keys and actually allow us to play the note for the key that we pressed. So we can do is we can come into here, we can say document, whoops, document.addEventlistener. And we want to do this on key down. So as soon as we press the key down, it's going to fire this event and it's going to have an event variable inside of it. And one thing that's really important to make this function work is that our white keys variable and black keys variable are in the exact order of our keys that we're going to be getting. So our white keys, the Z is our left key and our M is our right key and the black keys S is the left one and J is the right one. They're in the exact correct order, which is really important. So now inside of here, what we want to do is we want to get the key we pressed. That's actually really easy. There's an e.key. We can just get the key that we pressed with this e.key. This is going to correspond with the actual letter of the key that we pressed. Then what we can do is we can get the index from our array. So we'll just say white key index is going to be equal to white keys .indexOf and we want to get that key. And the reason it's important these arrays are in the correct order is because we're going to use this index to get the correct white key based on that ordering. But the next thing we need to do is we want to check to see if it's in the black keys obviously and this is going to be our black key index. And now we want to do is if we have a white key index, we want to run some code. So if this is greater than -1 because -1 is returned when it can't find anything. So essentially, if it found something, what we want to do is we want to play our note. But we need to determine which key this is going to be. So what we need to do is actually get all of our white keys. So we'll say white keys is going to be equal to .keys.white and we want to get all of our black keys, which is going to be the same thing, but it's going to be the class black instead of the class white. So, we can just come in here and put black like that. Then, what we can do is we can say we want to get all of our white keys, and we want to get it for the index of that white key index. Essentially, what we're doing is we're finding the index of the key that we pressed, and then corresponding that to the index in this array, which we already know they're in the exact same order. So, this third key here is going to be our third white key. That's how this index trick works. We can do the same exact thing with our black key index. We just need to make sure that we iterate over the black keys, and that we do the black key index here. Now, if I go ahead and I press the Z key when I have this highlighted, you should see this left note be played, and you can see that worked. And M, for example, is over here. J is going to be right here, and so on. All of the keys now work, and I can actually play the piano if I wanted to. There's only one last bug with this code, and that's if I hold down a key to play it, it's going to sound really bad. Just listen. You can hear it's trying to repeat the sound over and over again, and that's because, generally, when you have a key held down, it'll call the key down method over and over again after a short delay. In order to check for that, we could just say if e.repeat. Essentially, what this means is that it's one of those repeat calls from holding the button down. If that's the case, all we need to do is just call return. We just don't want to do anything. And now, if I come over here and I hold down the key, you notice it's only going to play that note once, and it's not going to repeat it over and over and over again, which is incredibly annoying. And that's all there is to making this awesome JavaScript piano. If you like this video, make sure to check out my other project-based videos linked over here, and subscribe to my channel for more videos just like this one. Thank you very much for watching, and have a good day.
Original Description
🚨 IMPORTANT:
Part Two: https://youtu.be/d0-VH4MC0Rk
Learning web development can be tough and boring, but it doesn't have to be. In this video we take a look at creating a simple JavaScript piano which can be played using the mouse or keyboard. This is a great project for anyone just getting started with JavaScript or anyone that wants to create a fun project.
📚 Materials/References:
GitHub Code: https://github.com/WebDevSimplified/JavaScript-Piano
Flexbox Tutorial: https://youtu.be/fYq5PXgSsbE
CSS Variables Tutorial: https://youtu.be/oZPR_78wCnY
🧠 Concepts Covered:
- How to use flexbox to center elements
- Using CSS variables to reduce redundant code
- Playing audio in the browser
- How to bind click and keypress events in JavaScript
🌎 Find Me Here:
My Blog: https://blog.webdevsimplified.com
My Courses: https://courses.webdevsimplified.com
Patreon: https://www.patreon.com/WebDevSimplified
Twitter: https://twitter.com/DevSimplified
Discord: https://discord.gg/7StTjnR
GitHub: https://github.com/WebDevSimplified
CodePen: https://codepen.io/WebDevSimplified
#JavaScriptMusic #WDS #JavaScript
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Web Dev Simplified · Web Dev Simplified · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Introduction to Web Development || Setup || Part 1
Web Dev Simplified
Introduction to Web Development || Understanding the Web || Part 2
Web Dev Simplified
Introduction to HTML || Your First Web Page || Part 1
Web Dev Simplified
Introduction to HTML || Basic HTML Elements || Part 2
Web Dev Simplified
Introduction to HTML || Advanced HTML Elements || Part 3
Web Dev Simplified
Introduction to HTML || Links and Inputs || Part 4
Web Dev Simplified
Learn Git in 20 Minutes
Web Dev Simplified
5 Must Know Sites For Web Developers
Web Dev Simplified
10 Best Visual Studio Code Extensions
Web Dev Simplified
Learn CSS in 20 Minutes
Web Dev Simplified
How to Style a Modern Website (Part One)
Web Dev Simplified
How to Style a Modern Website (Part Two)
Web Dev Simplified
3D Flip Button Tutorial
Web Dev Simplified
How to Style a Modern Website (Part Three)
Web Dev Simplified
Animated Loading Spinner Tutorial
Web Dev Simplified
How to Write the Perfect Developer Resume
Web Dev Simplified
Animated Text Reveal Tutorial
Web Dev Simplified
Learn Flexbox in 15 Minutes
Web Dev Simplified
Custom Checkbox Tutorial
Web Dev Simplified
Start Contributing to Open Source (Hacktoberfest)
Web Dev Simplified
JavaScript Shopping Cart Tutorial for Beginners
Web Dev Simplified
Responsive Video Background Tutorial
Web Dev Simplified
1,000 Subscriber Giveaway
Web Dev Simplified
How To Prevent The Most Common Cross Site Scripting Attack
Web Dev Simplified
Transparent Login Form Tutorial
Web Dev Simplified
The Forgotten CSS Position
Web Dev Simplified
How to Code a Card Matching Game
Web Dev Simplified
10 Must Install Visual Studio Code Extensions
Web Dev Simplified
Learn CSS Grid in 20 Minutes
Web Dev Simplified
Learn JSON in 10 Minutes
Web Dev Simplified
10 Essential Keyboard Shortcuts For Programmers
Web Dev Simplified
What Is The Fastest Way To Load JavaScript
Web Dev Simplified
Differences Between Var, Let, and Const
Web Dev Simplified
How To Install MySQL (Server and Workbench)
Web Dev Simplified
Learn SQL In 60 Minutes
Web Dev Simplified
How To Solve SQL Problems
Web Dev Simplified
What Are Design Patterns?
Web Dev Simplified
Null Object Pattern - Design Patterns
Web Dev Simplified
Your First Node.js Web Server
Web Dev Simplified
How To Setup Payments With Node.js And Stripe
Web Dev Simplified
How To Learn Any New Programming Skill Fast
Web Dev Simplified
Asynchronous Vs Synchronous Programming
Web Dev Simplified
JavaScript ES6 Arrow Functions Tutorial
Web Dev Simplified
Are You Too Old To Learn Programming?
Web Dev Simplified
JavaScript Cookies vs Local Storage vs Session Storage
Web Dev Simplified
JavaScript Promises In 10 Minutes
Web Dev Simplified
Builder Pattern - Design Patterns
Web Dev Simplified
JavaScript == VS ===
Web Dev Simplified
JavaScript ES6 Modules
Web Dev Simplified
8 Must Know JavaScript Array Methods
Web Dev Simplified
CSS Variables Tutorial
Web Dev Simplified
JavaScript Async Await
Web Dev Simplified
How To Choose Your First Programming Language
Web Dev Simplified
Easiest Way To Work With Web Fonts
Web Dev Simplified
Singleton Pattern - Design Patterns
Web Dev Simplified
Responsive Navbar Tutorial
Web Dev Simplified
CSS Progress Bar Tutorial
Web Dev Simplified
Learn GraphQL In 40 Minutes
Web Dev Simplified
What is an API?
Web Dev Simplified
Learn How To Build A Website In 1 Hour!
Web Dev Simplified
More on: JavaScript Fundamentals
View skill →Related AI Lessons
⚡
⚡
⚡
⚡
Had my Frontend Developer interview with Capgemini (Application Developer) today, and I wanted to…
Medium · JavaScript
10 Frontend Developer Tools to Boost Productivity in 2026
Medium · Programming
10 Frontend Developer Tools to Boost Productivity in 2026
Medium · JavaScript
The US Frontend Engineer Market in 2026: A Data-Driven Reality Check (and the Bias That Stops Us Seeing It)
Dev.to AI
🎓
Tutor Explanation
DeepCamp AI