DEV Community

Cover image for Design and Code a Playable Piano with Figma, HTML, SCSS, and JavaScript
Miltiadis Bouchalakis
Miltiadis Bouchalakis

Posted on

Design and Code a Playable Piano with Figma, HTML, SCSS, and JavaScript

Introduction to the Digital Piano Project

Welcome to an exciting journey through the world of web development and design, as I share my experience in creating a digital piano from scratch. This project is more than just a showcase of technical skills; it's a vivid illustration of how creativity and coding can harmoniously intertwine to bring a digital masterpiece to life.

Whether you're a seasoned developer, a design enthusiast, or someone curious about the intricacies of web development, this tutorial is designed to provide valuable insights, practical tips, and a bit of inspiration. Let’s dive into the fascinating process of transforming a simple idea into an interactive and visually appealing digital piano.

If you want to watch the video instead, you can watch it by clicking the YouTube video below:

All the code is available for free on GitHub ( You can find the GitHub link within the video description )

Designing the Piano in Figma

The journey begins with the design phase, where I use Figma to create the interface for our digital piano. Figma, known for its adaptability and ease of use, is an excellent tool for such a task.

Laying the Foundation

I start by setting up a new design file in Figma, focusing initially on the basic layout. This involves establishing the dimensions of the piano and its positioning on the screen.

Link to YouTube Video

Designing the Piano Keys

A key aspect of the design phase in Figma is setting up and using a grid. The grid serves as a foundational tool to ensure that all elements of the piano, especially the keys, are aligned precisely and proportionately.

I initiate the design process by defining a grid system. This grid helps maintain consistent spacing and alignment across the piano interface. It's particularly important for positioning the piano keys accurately, as their placement needs to mimic the layout of a traditional piano closely.

Link to YouTube Video

There we design the white and the black keys. The black keys are shorter and positioned slightly higher, just like on a real piano.

Link to YouTube Video
After the keys are in place, I add finer details to the design. This includes making the black and the white keys 3D

Link to YouTube Video

Developing the Piano with the use of Semantic HTML

Transitioning from the design to development, the first step is to set up the basic HTML structure of our digital piano. I begin by creating a foundational HTML document that will house all the components of our piano.

Creating the container

The buttons are organized within a parent container, maintaining a clean and logical HTML structure that mirrors the layout of a traditional piano.

Link to YouTube Video

Using Buttons for Piano Keys

A crucial aspect of this phase, as detailed in the tutorial, is the use of elements for the piano keys. Instead of using elements, I choose elements for each key because they are more semantically appropriate and accessible.

Buttons are inherently interactive and accessible, making them ideal for our piano keys. They support keyboard focus and click interactions out of the box, which is essential for the functionality of our digital piano.

For each key, I create a element. The white and black keys are differentiated by class names, allowing for specific styling and functionality to be applied later in the SASS and JavaScript phase.

I also ensure that each button is properly labeled with aria-labels, providing screen reader users with the necessary information about the function and note of each key.

Link to YouTube Video

To make the piano more user-friendly, especially for beginners or those learning music, I add hints to each key which helps identify which keyboard keys the user can use to play the notes.

Link to YouTube Video

Styling the Piano Keys with SCSS

Next, I delve into the styling aspect, using SASS or SCSS to be specific - a powerful CSS extension language. You’ll see my approach to organizing SASS files and utilizing its advanced features by using Maps instead of Variables to create a simple design system and our components.

Utilizing SCSS Maps for Theming

A key feature of my SCSS setup is the use of SCSS maps, particularly the $theme and $piano maps. These maps are crucial for organizing and managing the various colors, dimensions, and other stylistic properties used in the piano design.

The $theme map contains the color scheme and other general design elements that define the overall aesthetic of the piano. This approach allows for easy adjustments and theming, ensuring that changes to the design can be made quickly and consistently.

Link to YouTube Video

The $piano map specifically holds the properties related to the piano's design, such as key dimensions, border styles, and positioning. This separation of concerns makes the styling process more manageable, modular and easily updated from one place.

Link to YouTube Video

Moreover, if you have multiple themes, you can override them.

How you can create a new theme:

You can create a new dark theme or you can do multiple maps having the same keys but different values.

Link to YouTube Video

Merge the Themes: Merge the $theme and $dark-theme

After you do this you can create a new sass map that has the updated values.
Link to YouTube Video

Reassign $theme to $theme-dark: This is where you switch the theme.

And then have the new colours applied to the theme and frontend instantly.

Link to YouTube Video

Styling the White Keys

The white keys are styled with a focus on simplicity and elegance. Using the properties from the $piano map, I define the height, width, and background color for each white key.

Additional styles include border properties and subtle shadow effects to create a sense of depth. These shadows are especially important for achieving the 3D effect that makes the keys feel tactile and interactive.

Link to YouTube Video

Styling the Black Keys

The black keys require a different approach. They are smaller and positioned differently. Here, I use the values from the SASS maps to define their unique dimensions and positioning.

Link to YouTube Video

The color and shadow effects for the black keys are adjusted to make them stand out against the white keys. This involves setting a darker color and tweaking the opacity and spread of the shadows to enhance the 3D appearance.

3D interactive Key Styling in a Digital Piano

A standout feature in the digital piano's design is the realistic response of its keys when pressed. This effect is achieved through careful styling in SCSS, particularly in the .is-pressed state for both black and white keys.

Black Keys: A Deeper Perspective

For the black keys, pressing a key triggers a transformation defined by perspective(1500px) rotateX(-6deg). This effect creates a visual depth, making the key appear as if it's being pressed down. The larger perspective value enhances the depth illusion, while the rotateX tilt simulates the downward motion.

Link to YouTube Video

White Keys: A Subtler Motion

The white keys, in contrast, exhibit a more subtle motion with perspective(330px) rotateX(-2deg). This difference reflects the distinct physical characteristics of white piano keys. The transformation is less pronounced yet equally effective in conveying the sense of a key being pressed.

Link to YouTube Video

Both key types utilize transition: transform 0.2s to ensure the animation is fluid and natural. This careful timing makes the interaction feel responsive and intuitive.

Introducing interactivity with Vanilla JavaScript

As I reach the final part of my tutorial, I delve into how to add interactivity and code functionality using JavaScript. This phase is crucial as it transforms the digital piano from a static design into an interactive musical instrument.

Setting Up the JavaScript Environment

Initially, I discuss the JavaScript file setup. Given that we're using Webpack, I explain the use of dynamic imports for styles and how Webpack compiles them efficiently.

To maintain a clean codebase, I emphasize the importance of separating concerns. Hence, I create a dedicated JavaScript folder, paralleling the structure we used for styles.

Creating the Piano Component

The first step in coding the functionality is to create a component named Piano.js. This component is structured as a constructor function, allowing for reusability in different parts of the application.

I ensure to export the Piano component using the export operator.

Link to YouTube Video

The Piano function returns an object containing both playNote and playNoteByKey functions. This return statement makes these functions accessible to other parts of the application, adhering to the principles of the Module pattern.

The Piano.js file uses a modular pattern, a common and effective approach in JavaScript, to encapsulate functionality. It starts with importing keyboardMap from the keybinds module. This map is crucial as it correlates keyboard keys to musical notes, an essential aspect of the piano's interactivity.

playNote Function

Link to YouTube Video

The audio.play() method is then invoked to play the note. This simple yet effective line of code is the heart of the piano's sound functionality.

A key aspect of this function is the use of the HTML audio element, a powerful web API for manipulating audio files dynamically. This API allows for playing and pausing audio, which is crucial for a web application like a digital piano.

index.js Imports

Inside index.js or our entry point we import our Styles and Components.

import "./styles/main.scss";
Imports the main SASS stylesheet, ensuring all styles are applied to the piano interface.

import { Piano } from "./javascript/Piano";
Imports the Piano function, which encapsulates the core functionality for playing notes.

import { keyboardMap } from "./javascript/keybinds";
Imports the mapping of keyboard keys to piano notes, crucial for enabling keyboard interactivity.

Link to YouTube Video

Initializing the Digital Piano

const DigitalPiano = Piano();
Initializes the digital piano by invoking the Piano function. This instance, DigitalPiano, is now equipped with methods to play notes.

Link to YouTube Video

Creating UI Note-Keybind Map

This function creates a mapping between the data attributes of the piano keys (notes) and the HTML elements themselves. This map is used to find the corresponding DOM element efficiently when a note is played.

Link to YouTube Video

Handling Mouse Events

handleMouseDown and handleMouseUp are event handlers for mouse down and up events on each key. When a key is pressed (mouse down), it adds the .is-pressed class for visual feedback and plays the corresponding note. On mouse up, it removes the is-pressed class.
handleDocumentMouseUp removes the .is-pressed class from all keys, ensuring that any stuck keys are released if the mouse is released outside a key.

Link to YouTube Video

Handling Keyboard Events

findNoteAndNodeFromKeyPress is a utility function to find the note and corresponding DOM node based on a keyboard event.

handleDocumentKeyDown and handleDocumentKeyUp are event handlers for keyboard events. They use findNoteAndNodeFromKeyPress to play the corresponding note and toggle the .is-pressed class based on key down and up events.

Link to YouTube Video

Adding Event Listeners

The document-level event listeners for mouseup, keydown, and keyup handle global actions like releasing all keys when the mouse button is released, and playing notes based on keyboard input.
Each piano key node has event listeners for mousedown and mouseup to handle individual key interactions.

Link to YouTube Video

Conclusion

And there we have it—the final chord in our digital piano creation symphony. Through this journey, we've navigated the harmonious blend of design and development, starting from the conceptual sketches in Figma to the functional, interactive keys brought to life with JavaScript.

This project wasn't just about building a musical instrument; it was about harmonizing different technologies to create something beautiful and functional. I hope this experience leaves you with not only a deeper understanding of web development and design but also the inspiration to blend art and technology in your future projects.

Thank you for joining me on this melodious coding journey. Keep experimenting, keep learning, and let your creativity play the next tune!

If you want to watch the video instead, you can watch it by clicking the YouTube video below:

All the code is available for free on GitHub ( You can find the GitHub link within the video description )

Top comments (7)

Collapse
 
fyodorio profile image
Fyodor

Thanks, interesting approach 👍 one note: the GitHub link leads to YouTube, or is it only me?

Collapse
 
miltiadis profile image
Miltiadis Bouchalakis • Edited

Thanks for your comment @fyodorio, I've updated the link so it now directs to the section detailing how to install and run the repository locally. You can find the link within the video description as the first link and the Figma design files.

Additionally, here's the direct link to the GitHub repository for your convenience.

Collapse
 
arjuncodess profile image
Arjun Vijay Prakash

This is amazing! Thanks for sharing!

Collapse
 
miltiadis profile image
Miltiadis Bouchalakis

Hearing your positive feedback, Arjun, is truly rewarding. Glad you enjoyed it!

Collapse
 
francescoxx profile image
Francesco Ciulla

thanks for this article!

Collapse
 
miltiadis profile image
Miltiadis Bouchalakis

Thanks for your support Fransceco!!!

Collapse
 
francescoxx profile image
Francesco Ciulla

you are welcome!