The first thing we need to do is add keycodes.js
to our application. This file contains a global static object named keyCodes
that maps keys on the keyboard to their associated key code. For example, keyCodes.ENTER
is equal to 13
. Using this will make our code more readable than using key code numbers.
The next thing we need to do is open the HTML and add a new custom data attribute to the piano-key
elements. We will call it data-keycode
and it will be set to the value in the keyCode
object we want to associate with the piano key:
<div data-note="2C" data-keycode="Q" class="piano-key white" title="C2"></div> <!—elements not shown --> <div data-note="4C" data-keycode="COMMA" class="piano-key white" title="C4"></div>
Now we need to map key codes to the notes. We will add an object to our application called keyCodesToNotes
to hold our mappings. We will initialize it in the initKeyboard()
method:
function initKeyboard() { // Code not shown... $keys.each(function() { var $key = $(this); var keyCode = keyCodes[$key.data("keycode")]; keyCodesToNotes[keyCode] = $key.data("note"); }); }
Here, we iterate over all piano-key
elements, getting the data-keycode
custom attribute for each one and using that to get the key code from the keyCodes
object. Then we add the mapping to keyCodesToNotes
by setting it to the element's data-note
custom attribute. For example, the key code for the Q key is 81 and the associated piano key note is 2C. So keyCodesToNotes[81]
will be set to 2C
.
Now let's add the keyboard event handlers. When checking for key down, up, or pressed events, you need to attach your event handlers to the HTML document. Let's add keydown
and keyup
event handlers in the start()
method of our application:
this.start = function() { // Code not shown... $(document).keydown(onKeyDown) .keyup(onKeyUp); }
The keydown
event handler calls the onKeyDown()
method. The keyup
handler calls onKeyUp()
:
function onKeyDown(e) { var note = keyCodesToNotes[e.which]; if (note) { pressPianoKey(note); } }
In the onKeyDown()
method we look up the note for the key that was pressed using the keyCodesToNotes
object. jQuery defines a which
field on the key event object that contains the key code. If the key code matched to a note on our keyboard, then we call the pressPianoKey()
method passing it the note
parameter:
function onKeyUp(e) { var note = keyCodesToNotes[e.which]; if (note) { releasePianoKey(note); } }
The onKeyUp()
method works the same way except that we call the
releasePianoKey()
method.
function pressPianoKey(note) { var $key = getPianoKeyElement(note); keyDown($key); }
In the pressPianoKey()
method, we get the name of the note to play as a parameter. Then we call getPianoKeyElement()
to get the piano key element associated with that note. Finally, we pass that element into the keyDown()
method that we already implemented when we added mouse and touch events. In this way, we simulate the user clicking a piano key element on the screen.
function releasePianoKey(note) { var $key = getPianoKeyElement(note); keyUp($key); }
The releasePianoKey()
method works exactly the same way except it calls the existing keyUp()
method.
function getPianoKeyElement(note) { return $(".keyboard .piano-key[data-note=" + note + "]"); }
In the getPianoKeyElement()
method, we find the piano-key
element associated with a note by using a jQuery select matching on the data-note
custom attribute.
We added keyboard key event handlers to the HTML document of our application. We mapped the key codes when a key is pressed to a piano key, so that the user can press keys on the keyboard to play the piano. By passing the piano-key
element into keyDown()
and keyUp()
, we simulate the user clicking on those keys. They get the down
class added to them so it looks like they are really being pressed.
Check it out for yourself. Try pressing two or three keys at a time and play some chords.
3.22.248.208