TOLERABLE KEYBOARD!

Easy to set up HTML custom keyboard. Mouse and key bindings, no dependencies, easy to plug into the web audio API.

DOWNLOAD

Grab the full script, or the minified version.

SET UP

Add the tolerableKeyboard.min.js file to your project, create a (tolerable) keyboard object and a div to hold it, and voila. You can start playing the final countdown.


          // In Script file

          // Set up the keyboard. Settings will fall back on default values if not provided
          // By default, the keyboard will be 3 octaves, starting on a C2
          //   and will connect to a simple square synth 
          let basicKeyborad = new TolerableKeyboard()


          // In HTML file

          // If not divID was specified during creation, the script looks for <div id="tolerableKeyboard">
          // If it is not present in the HTML page, the constructor will 
          //   create and append one on the bottom of the page.
          // For further styling, its better to include it manually where needed
          <div id="tolerableKeyboard"></div>;
        

It can be played with the mouse, or, by default, with the keys A through K for the middle octave.

CUSTOM SET UP

The keyboard looks, key bindings, and action happening on pressing/releasing a note can also be customized


        // In Script file

        // Set up the keyboard. 

        // Settings are optional and will fall back on default values if not provided
        // Here is the full list:
        let customKeyboard = new TolerableKeyboard({
          divID: 'customKeyboard', //The id of the div that will contain the keyboard
          // If empty, a new div of class "tolerableKeyboard" will be appended to the page's body
          octaves: 2, //Number of octaves
          width:600, //Width of the full keyboard in px
          height:150, //Height of the white notes
          firstNote: 'F#2',//Starting note
          showKey:true, //Display the keybindings on the notes, if any
          autoSetUp:false, //If true, will set up an audio context and a simple synth. 
                           //If not, pressNote and releaseNote functions need to be written
                           //No audio context will be created
          selectColor:'#7FDBFF', //Highlight color of any pressed note
          whiteNoteColor: '#F8F8FF', //Color of the white notes
          blackNoteColor: '#001f3f', //Color of the black notes
          // Borders/Casing of the keyboard.
          borderSize: 20, // Size of the left and right borders
          borderSizeOffset: -5, //Difference between the side borders height and the notes heights
          borderSizeTop: 100, //Size of the top border
          borderColor: '#579EBF', //Color of the borders
          borderBorderSize: 5, //Size of the border's borders
          borderBorderColor: '#001f3f', //Color of the border's borders and of the text
          borderRadius: 10, //Radius of the borders 
          borderText: 'BOOYA!', //Text of the top border
        })

        // Because we dont use autoSetUp, we need to initialize a context and gain
        let context, gain, nodes = [];

        context = new AudioContext();
        mixNode = context.createGain();
        mixNode.gain.value = 0.3;
        mixNode.connect(context.destination); 

        // If autoSetUp == true, the pressNote and releaseNote functions will be prefilled
        // If not, they need to be filled with the sound playing logic.
        // We will set up a simple synth 

        // For each note, the synth will play 2 detuned oscillators at the note frequency
        customKeyboard.pressNote = function(frequency){
          let oscillators = [];

          let osc = context.createOscillator();
          osc.type = 'square';
          oscillators.push(osc)

          let osc2 = context.createOscillator();
          osc2.type = 'sawtooth';
          osc2.detune.value = 10;
          oscillators.push(osc2)

          oscillators.forEach(o =>{
            o.frequency.value = frequency ;
            o.connect(mixNode);
            o.start(0);
            nodes.push(o);
          })
        }

        // For each key released, the synth will loop through the oscillators,
        //   check the frequency, and stop them if they match 
        customKeyboard.releaseNote = function(frequency){
          let newNodes = [];
            for (let i = 0; i < nodes.length; i++) {
              if (Math.round(nodes[i].frequency.value) === Math.round(frequency)) {
                nodes[i].stop(0);
                nodes[i].disconnect();
              } else {
                  newNodes.push(nodes[i]);
                }
              }
          nodes = newNodes;
        }

        //example of adding a new key binding
        //by default keys A through L are binded to C3 through C4
        //only one keyboard (the last one created) can be hooked up to the keys
        //thats one the first one is not working
        customKeyboard.addKeyBinding('Z','F#2')
        customKeyboard.addKeyBinding('X','F#4')

        // In HTML file

        <div id="tolerableKeyboard"></div>;
      
the code and it shall appear in its magnificent glory.