Welcome

Welcome to the tutorial site for "noteFramework.js"
I built this framework so a web developer can easily add a piano and drum machine to their website.
The framework is based on HTML5 buttons that play back audio samples. With some creativity, you can create your own unique musical interfaces that your website's visitors will enjoy.
The framework uses HTML's audio component. The framework looks for mp3 files stored in a folder called "sounds." You can add our provided "sounds" folder to your site's root folder. Download the sounds and framework folder here. The "sounds" folder comes with enough mp3 files to make a piano and a basic drum machine.

Getting Started

Start by adding the framework as a JavaScript reference in your HTML code. Then, add the following line to the head of your HTML file:


    <head>
        <script src="noteFramework.js"> </script>
    </head>
    
Next, you need to create an instance of the framework in your project. You do that by calling the makeNoteFramework() method. That code look like this:

    <script type="text/javascript">
    // myNoteFW will be the variable that
    // holds your noteFramework object
    var myNoteFrameWork = makeNoteFramework();
    </script>
    

Now that you have created a noteFramework object, you can use that to make notes. Create a button in HTML and give it a unique id. You will use this button for your Note.

    <body>
        <button id="myFirstNote"></button>
    </body>

    

Then call the "makeNote" method to create a note. When you call this method you must pass in the id of the button that will play the note. The code looks like this:

    <script type="text/javascript">

    // myNoteFW will be the variable that
    // holds your noteFramework object
    var myNoteFrameWork = makeNoteFramework();

    // noteOne will be the variable to hold your Note object.
    var noteOne = myNoteFW.makeNote({
            //below is the id parameter of the button you just created
            id: "myFirstNote"
        } //end parameter passing
    ); //end var noteOne = myNoteFW.makeNote

    </script>

    

If we put it all together, the code looks like this:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" type="text/css" href="styles.css">
        <!--reference my javascript file-->
        <script src="noteFramework.js">
        </script>

        <title>My Great Piano</title>
    </head>

    <body>

    <button id="myFirstNote"></button>

    <script type="text/javascript">

        // myNoteFW will be the variable that
        // holds your noteFramework object
        var myNoteFrameWork = makeNoteFramework();

        // noteOne will be the variable to hold your Note object.
        var noteOne = myNoteFrameWork.makeNote({
                //below is the id parameter of the button you just created
                id: "myFirstNote"
            } //end parameter passing
        ); //end var noteOne = myNoteFW.makeNote

    </script>

    </body>

    </html>

    

Example 1:

When we run the code above we get the a button. When you click the button you should hear a note. Run the example code here: Example 1

Why does the button look like that and play the note C? What does that 'Z' under the 'C' mean?

The notes have many default properties, including playing the sound file C.mp3, and being assigned to keycode 90. Keycode 90 corresponds to the 'Z' key on your QWERTY keyboard.
The inner HTML of the button displays the sound file it will play, and underneath that, the keyboard key that plays it.
So this button plays the 'C' sound file, and you play it with the 'Z' key on your keyboard.
I'll explain more about keycodes later in this tutorial. Below are the default parameters and style attributes of a button that the framework assigns.

    // by default set the keyboard key that plays the note to keycode 72.
    params.keyboard_Key = (params.keyboard_Key || 72); /*middle c*/
    // by default play the mp3 file for the C note.
    params.soundName = (params.soundName || 'C');
    // set style elements for the notes
    noteObjectFromDOM.style.height = params.height || "100px";
    noteObjectFromDOM.style.width = params.width || "50px";
    noteObjectFromDOM.style.backgroundColor = "light grey";
    noteObjectFromDOM.style.borderRadius = params.borderRadius || "10px";
    noteObjectFromDOM.style.border = "none";
    noteObjectFromDOM.innerHTML = params.soundName +'"<br>"'+ params.keyboard_Key;
    noteObjectFromDOM.style.margin = "2px";

    

When you are creating a Note, you should assign:

  1. the sound file in the "sounds" folder it will play, written in UPPERCASE. Example: C.mp3 or D2.mp3
  2. the keycode of the keyboard key that you want to play it with
Some file names you can try that are in the "sounds" folder are: E.mp3, F.mp3, G2.mp3

A keycode is a Unicode number associated with a keyboard key. To find a keycode, go to this website keycode.info and just hit the key you want to play your note with. A number will show up on the screen. That's the number you want to copy and paste when creating your note.

Example 2:

Let's create 3 buttons with the following properties: I would go to keycode.info and type in '1' to see that the keycode is 49, '2' is keycode 50, and '3' is keycode 51.
Two additional parameters you can change are the width and height of the button using the variables "width" and "height" as seen in the code below.


    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" type="text/css" href="styles.css">
        <!--reference my javascript file-->
        <script src="noteFramework.js">
        </script>

            <title>Note Framework Tutorial</title>
            </head>

            <body>

            <button id="myPianoNote1"></button>
            <button id="myPianoNote2"></button>
            <button id="myPianoNote3"></button>

                <script type="text/javascript">

            // myNoteFW will be the variable that
            // holds your noteFramework object
            var myNoteFrameWork = makeNoteFramework();

            // variable to hold your Note object.
            var p_note_1 = myNoteFrameWork.makeNote({
                    //below is the id parameter of the button you just created
                    id: "myPianoNote1",
                    soundName: 'E',
                    keyboard_Key: 49,
                    width: "60px",
                    height: "200px"
                } //end parameter passing
            ); //end var noteOne = myNoteFW.makeNote

            // variable to hold your Note object.
            var p_note_2 = myNoteFrameWork.makeNote({
                    //below is the id parameter of the button you just created
                    id: "myPianoNote2",
                    soundName: 'F',
                    keyboard_Key: 50,
                    width: "60px",
                    height: "200px"
                } //end parameter passing
            ); //end var noteOne = myNoteFW.makeNote

            // variable to hold your Note object.
            var p_note_3 = myNoteFrameWork.makeNote({
                    //below is the id parameter of the button you just created
                    id: "myPianoNote3",
                    soundName: 'G',
                    keyboard_Key: 51,
                    width: "60px",
                    height: "200px"
                } //end parameter passing
            ); //end var noteOne = myNoteFW.makeNote


            p_note_1.setBackgroundColor("#235313");


        </script>

        </body>

    </html>

    

Each button has a private variable for its background color. This can be set with the function "setBackgroundColor" in which you pass in a string with the color value.
If I want to change the first button's color to green, I can call that note's function and pass in "green."


    p_note_1.setBackgroundColor("green");
    

If we run the above code we create 3 buttons that are 60px wide, 200px high, and the first one is green.

Try the code here: Run the example code here: Example 2

Example 3:

You can continue in this way to create a whole piano one note at a time and customize each note, but I have also built in a function that receives a div and returns a piano. In this case, the default keyboard keys and notes will be assigned and are not changeable. You can pass in a "global" width, height, and color that will be applied to all of the keys.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>My New Piano</title>
        <script src="noteFramework.js"> </script>
    </head>

    <body>
    <!--create a div to hold your piano-->
    <div id="myPiano2"> </div>

    <script type="text/javascript">

        // a variable to hold your noteFramework object
        var myNoteFW3 = makeNoteFramework();

        // call the make piano method and pass in parameters
        myNoteFW3.makePiano({id: "myPiano2"}, "30px", "120px", "red");

    </script>

    </body>
    </html>

    

In the above example I am making a noteFramework object then calling the makePiano function. I am passing in these parameters: a width of 30px, a height of 120px, and the color "red."
Run the example code here: Example 3

Example 4

With some creativity, you can turn this into another kind of instrument.
Here is an example of a simple drum machine. Included in the "sounds" folder are some mp3 files with drum sounds.
I made three buttons, added notes to them that play the drum sounds, and assigned them to the numbers keys for '8', '9' , and '0.'
To make it look playful, I styled each button to be a circle by setting their width and height to the same number, and setting their border radius to half of the width.
I then used the setBackgroundColor function of the makeNote framework. When you call that function you pass in the new color for your Note. As you see, I create a note called "kick" then call kick.setBackgroundColor("#42e8f4");
Here is an example of the code:


    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <!--reference my javascript file-->
        <script src="noteFramework.js"> </script>
    </head>
    <body>

    <p>Play these with the number keys: 8, 9, 0</p>


    <div id="drumMachine">
        <button id="kick_button"></button>
        <button id="snare_button"></button>
        <button id="hat_button"></button>
    </div>


    <script type="text/javascript">


        var myNoteFW = makeNoteFramework();


        var kick = myNoteFW.makeNote({
                id: "kick_button",
                soundName: 'KICK2',
                keyboard_Key: 56,
                height: "100px",
                width: "100px",
                borderRadius: "50px"
            }
        );
        // use the framework's function to change the background color of a Note
        kick.setBackgroundColor("#42e8f4");

        var snare = myNoteFW.makeNote({
                id: "snare_button",
                soundName: 'SNARE2',
                keyboard_Key: 57,
                height: "100px",
                width: "100px",
                borderRadius: "50px"
            }
        );
        // use the framework's function to change the background color of a Note
        snare.setBackgroundColor("#d341f4");

        var hat = myNoteFW.makeNote({
                id: "hat_button",
                soundName: 'HAT',
                keyboard_Key: 48,
                height: "100px",
                width: "100px",
                borderRadius: "50px"
            }
        );
        // use the framework's function to change the background color of a Note
        hat.setBackgroundColor("#f4f441");


        // set each button's inner html to blank for a nice appearance
        kick_button.innerHTML = " ";
        snare_button.innerHTML = " ";
        hat_button.innerHTML = " ";


    </script>

    </body>
    </html>
    makeNote

    

If we run the code above we see:

Run the example code here: Example 4

Example 5

For another take on a creative idea, here is a page that creates a full piano, but hides the inner HTML and makes the keys white.
The effect is to create an invisible piano that still works. The code is shown below:


    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>My Invisible Piano</title>
        <script src="noteFramework.js"> </script>
    </head>
    <body>

    <!--create a div to hold your piano-->
    <div id="myPiano2" style="display: none"> </div>

    <script type="text/javascript">

        // a variable to hold your noteFramework object
        var myNoteFW3 = makeNoteFramework();

        // call the make piano method and pass in parameters
        myNoteFW3.makePiano({id: "myPiano2"}, "100px", "120px", "red");

    </script>
    </body>
    </html>

    

Run the example code here: Example 5

Example 6

For this final example, you can see how to create ways to let your user alter aspects of a note. I will explain a small part below. In HTML you can create a button and a text area. Then you can set the onclick function of your button to call the "setNoteLetter" function of your note framework. It can pass in the value held in the HTML text area.


    <input type ="button"
value="Set Note"
onclick ="myNoteObject.setNoteLetter(my$('newNoteLetter').value);"
/>
<input type ="text" id="newNoteLetter"/>

Run the example code here: Example 6

Building The Framework

Here I will explain the reasoning behind the framework and how to build one yourself.

Introduction to Writing The Framework

I built this framework to let the HTML programmer incorporate a piano onto their page. I created a JS file which starts with a makeNoteFramework function. With that function a variable "myNoteFW" is created. The framework then uses a function to find the HTML element this JS object should reference.
Then there are two principle methods. The "makeNote" function, and the "makePiano" which itself uses the "makeNote" function.
These two functions are too long to past their entirety here. You can easily see them by inspecting the noteFramework.js file.

Listener Events

For a piano note to be useful to someone visiting the site it needs to respond to two types of events: mouse clicks and key down events.
These two types of events are used differently. The mouse click event can be associated to a single button. However, the keydown event needs to be added to entire document. If the keydown event is added to a div or button instead of the document, the Note will not trigger unless that div is in focus. That results in an unreliable user experience. The click events also make this note function on mobile devices but I find the experience to be slow on mobile.

As you see in the code below, the document listener doesn't search for an id in the document, so they remain independent. You'll see it looks for the keyCode of the event. Each keyboard key has a unique Unicode number. This number can be detected and passed into a function. As you saw in the above Getting Started section, each Note has a "keyboard_Key" parameter. This "keyboard_Key" is a Unicode number. The keyCode for a keyboard key can be found on this website: keycode.info.
If the keyCode that was pressed matches the keyboard_Key of a Note, then the playNote function is called and the "soundNameToPlay" is passed in. "soundNameToPlay" references the file name to play.


    // if this note's keyboard key (qwerty keycode) is pressed, play this note
    // add an event listener to the document for qwerty key presseses
    document.addEventListener("keydown", function (event) {
        console.log("this keyboard key was just pressed: " + event.keyCode);
        if (event.keyCode == params.keyboard_Key) {
            playNote(soundNameToPlay);
        }
    }); /*end document.addEventListener("keydown", function(event)*/

    

The listener code related to a mouse click, or finger push, is simpler to implement. This listener is associated to the id of the HTML button that is passed in. If that button is clicked, the playNote function is called.


        /* button click listener to enable mouse, or fingers, to play the note*/
        noteObjectFromDOM.addEventListener("click", function (event) {

            playNote(soundNameToPlay);

        }); /*end document.addEventListener("keydown", function(event)*/

    

Playing A Sound

The framework's "playNote" function performs two operations. It plays the audio file passed in, and temporarily change's the background color of the Note's button.
The "playNote" function creates a new JS Audio object. It concatenates the name of the audio file passed in with the "sounds/" folder preceeding the filename, and ".mp3" after it. It then calls the .play method. I found help with this on W3 schools and Stack Overflow..

This function also temporarily changes the background color of the button that plays the sound. This is just for a nice visual effect. It does this by holding the current color of the note. It then sets the background color to blue.
Finally, it uses a timed function to wait 70 milliseconds then call the setColor function to restore the note's color.
I found help with this function from W3 schools.
This background color change is unnecessary when you build your own framework. I added it for a nice touch.
This section of code is shown below:


    function playNote(noteTitle) {
            //temporarily hold the old background color so we can reset to it
            var oldColor = noteObjectFromDOM.style.backgroundColor;

            /* open up and play the audio file*/
            var noteSound = new Audio("sounds/" + noteTitle + ".mp3");
            noteSound.play();

            /* temporarily change the background color of the pressed key.*/
            noteObjectFromDOM.style.backgroundColor = 'blue';

            /* return the button's original color after a short time*/
            setTimeout(setColor, 70);
            function setColor() {
                noteObjectFromDOM.style.backgroundColor = oldColor;
            } /*end function setColor()*/

        } /*end function playNote(noteTitle)*/

    

Creating A Piano

This framework idea was first meant to let someone implement a Piano. It became tedious to program more than 8 notes at a time, so I created a function that provides the most likely desired notes. For this function, the HTML programmer creates a div, but no buttons. That div is passed in, and the framework runs through a loop to create 16 buttons, add ascending mp3 files from the sounds folder to them, style them, add listeners, then append them to the div. The result is that 16 rounded buttons are created instantly for the programmer. The code that creates and appends the button is shown below.



        var soundButton = document.createElement("button");
        soundButton.id = ("p" + i);

        //add this button to the passed in div
        noteObjectFromDOM.appendChild(soundButton);

    

In creating this function I did not allow the programmer to set what files would be played or what keyboard keys would be used to play them. I assumed most users will use a QWERTY keyboard and I put middle 'C' on the 'h' key, then worked from there. This "makePiano" function does allow the programmer to pass in height, width, and a color that will be applied to all keys.
The loop calls the "makeNote" function and passes in each of these parameters. The entire code is too long to copy and past here but you can easily see them by inspecting the noteFramework.js file.
You'll notice there is a switch statement that runs through the 16 Notes to be created and assigns them the required parameters.

Letting the User Change Aspects of a Note

There are two functions that allow a user to change the keyboard key used to play a Note, and what audio file should be played.
The function to set the keyboard key could be implemented with a text area with an associated submit button.
The function to change the letter of a note could also be implemented with a text area and submit button. In this framework, the "setNoteLetter" function will also change the inner HTML to show the file name passed in. These functions are not necessary if you build your own function if you don't want the user to set these parameters, but these functions are good examples since they use methods to alter private properties.


    // public modifier method to change which key will play the note
    noteObjectFromDOM.setKeyboardKey = function (newKey) {
    params.keyboard_Key = newKey;
    }; // end noteObjectFromDOM.setKeyboardKey = function (newKey)
    

    // public modifier method to change the Letter of a note
    // Important: this will NOT check if the file exists. It will try to assign
    // any file name passed in. It's up to the user to enter the file name correctly.
    noteObjectFromDOM.setNoteLetter = function (newLetter) {
    // show an alert if they push the button withouthe entering somethign
    if (newLetter == "") {
    alert("Sorry, but you must enter something.");
    return;
    } // end if

    soundNameToPlay = newLetter.toUpperCase(); // set private property
    noteObjectFromDOM.innerHTML = soundNameToPlay;

    }; // end noteObjectFromDOM.setNoteLetter = function (newLetter)

    

Styling the Note Buttons

This framework styles the buttons to a tall rectangle to lightly mimic the shape of a piano note.


    // set style elements for the notes
    noteObjectFromDOM.style.height = params.height || "100px";
    noteObjectFromDOM.style.width = params.width || "50px";
    noteObjectFromDOM.style.backgroundColor = "light grey";
    noteObjectFromDOM.style.borderRadius = params.borderRadius || "10px";
    noteObjectFromDOM.style.border = "none";
    var toInnerHtml = params.soundName +"<br>"+ String.fromCharCode(params.keyboard_Key);
    // if the piano name includes "sharp" display "#" instead
    var newInnerHtml =toInnerHtml.replace("sharp", "#");
    toInnerHtml = newInnerHtml;
    noteObjectFromDOM.innerHTML = toInnerHtml;
    noteObjectFromDOM.style.margin = "2px";
    noteObjectFromDOM.style.overflow = "hidden";

    

Summary

This framework begins with the idea of a note: a button that plays back one sound file when clicked or triggered by a specified keyboard key. It extends that to the idea of a Piano by creating 16 Notes in one function.
The framework is flexible enough to let the programmer create their own instruments by placing their own mp3 files into the "sounds" folder and referencing them when creating a note.
The essential aspects in building a similar framework are to:

I hope you enjoy creating something with this framework!