<div class="container">
  <h2>Emulated MIDI Controller</h2>
  <p>The difficulty is every MIDI controller is different, so this is a stripped down AKAI LPD8, for demo purposes.</p>
  <p>Notice how the pads generate two values, one for on press and one for on release.</p>

  <div id="midi-container">
    <div id="midi-controller">
      <section id="pads">
        <div class="pad" data-midi="37">
          <p>PAD 1</p>
          <button></button>
        </div>
        <div class="pad" data-midi="38">
          <p>PAD 2</p>
          <button></button>
        </div>
        <div class="pad" data-midi="39">
          <p>PAD 3</p>
          <button></button>
        </div>
        <div class="pad" data-midi="40">
          <p>PAD 4</p>
          <button></button>
        </div>
        <div class="pad" data-midi="41">
          <p>PAD 5</p>
          <button></button>
        </div>
        <div class="pad" data-midi="42">
          <p>PAD 6</p>
          <button></button>
        </div>
        <div class="pad" data-midi="43">
          <p>PAD 7</p>
          <button></button>
        </div>
        <div class="pad" data-midi="44">
          <p>PAD 8</p>
          <button></button>
        </div>
      </section>
    </div>
  </div>
  
  <section id="midi-data">
    <ul></ul>
  </section>
  
  <p>Eventually I'd like to expand this out as a polyfill to 'appear' if you have no MIDI controller plugged in.</p>
</div>
$lightGrey: hsla(340,2%,90%,1);
$darkGrey: hsla(340,2%,20%,1);
$pink: hsla(340,85%,60%,1);

body {
  width:90%; max-width:840px;
  margin:0px auto; padding:2em;
  box-sizing:border-box;
  background: $lightGrey;
  font-family: 'Poppins', sans-serif;
  font-size:1em; line-height:1.3;
  h2, p {padding:0.5em 0;}
  h2 {border-bottom:2px solid $pink;}
}

#midi-container {}

#midi-controller {
  padding:1%;
  background: #333 no-repeat top left;
  display: flex;
  justify-content: space-between;
  border-radius:2px;
  box-shadow:2px 2px 4px 0px $darkGrey;
  
  section {
    width:100%;
    display: flex;
    justify-content: space-around;
    flex-wrap: wrap;
  }
}

.pad, .dial {
  width:25%; min-width:50px;
  box-sizing:border-box;
}

.pad {
  padding:1%;
  p {
    font-size:0.6em;
    color:$lightGrey;
  }
  button {
    display:block;
    width:100%; height:70px;
    box-sizing: border-box;
    background: lighten($darkGrey,10%);
    border: 3px solid $lightGrey;
    border-radius: 2px;
    box-shadow: 1px 1px 2px 0px black;
    cursor:pointer;
    &:focus {outline:none;}
    &:active {border-color:$pink;}
  }
}

#midi-data {
  position:relative; overflow:hidden;
  height: 200px;
  background:transparentize(white,0.1);
    border:10px solid transparentize($pink,0.3);
  ul {
    position:absolute; left:0px; bottom:0px;
    padding:1em;
    li {
      padding:0.2em 0.2em 0.2em 1em;
      font-size:1.2em;
      font-family: monospace;
      &:last-child, &:nth-last-child(2) {
        font-weight:bold;
        animation:flash 1s;
        &:before {content:"> "; margin-left:-1em;}
      }
    }
  }  
}
@keyframes flash {
  0% {color:$pink;}
  100% {color:black;}
}
View Compiled
var allPads = document.getElementsByClassName('pad'),
    dataList = document.querySelector('#midi-data ul')

for (var i=0; i<allPads.length; i++) {
  allPads[i].addEventListener('mousedown', function() {
    var newItem = document.createElement('li');
newItem.appendChild(document.createTextNode('[144,'+this.dataset.midi+',64]'));
    dataList.appendChild(newItem);
  });
    allPads[i].addEventListener('mouseup', function() {
    var newItem = document.createElement('li');
newItem.appendChild(document.createTextNode('[128,'+this.dataset.midi+',127]'));
    dataList.appendChild(newItem);
  });
}

External CSS

  1. https://fonts.googleapis.com/css?family=Poppins

External JavaScript

This Pen doesn't use any external JavaScript resources.