Skip to content

Instantly share code, notes, and snippets.

@dustMason
Created June 1, 2017 20:46
Show Gist options
  • Save dustMason/9768c1d98234057c4bd2ac757c4f1c55 to your computer and use it in GitHub Desktop.
Save dustMason/9768c1d98234057c4bd2ac757c4f1c55 to your computer and use it in GitHub Desktop.
Interactive OP-1 keys
(function(document, window) {
var fullWidth = 1111.0;
var img = document.querySelector("#op1-keys:not([data-ready])");
if (img) {
var keys = [
[[210, 58], [270, 173]], // F
[[211, 0], [298, 57]], // F#
[[269, 58], [327, 174]],
[[298, 0], [356, 57]],
[[327, 58], [387, 172]],
[[356, 0], [444, 58]],
[[385, 58], [444, 172]],
[[444, 58], [503, 172]],
[[444, 0], [532, 57]],
[[502, 58], [561, 172]],
[[531, 0], [619, 58]],
[[561, 58], [620, 173]],
[[619, 58], [679, 172]],
[[619, 0], [707, 57]],
[[678, 58], [737, 172]],
[[707, 0], [764, 57]],
[[736, 58], [795, 174]],
[[765, 0], [853, 58]],
[[795, 58], [854, 174]],
[[854, 58], [915, 174]],
[[854, 0], [943, 58]],
[[912, 58], [972, 175]],
[[942, 0], [1030, 59]],
[[972, 58], [1030, 174]] // E
];
var nKeys = keys.length;
function noteFromCoords(x, y) {
for (var i = 0; i < nKeys; i++) {
if (x > keys[i][0][0] && x < keys[i][1][0] && y > keys[i][0][1] && y < keys[i][1][1]) {
return i+53;
}
}
return -1;
}
function coordsFromNote(note) {
return keys[note-53];
}
img.addEventListener("mousemove", function(e) {
var x = e.offsetX;
var y = e.offsetY;
if (x > keys[1][0][0] && x < keys[nKeys-1][1][0] && y > keys[1][0][1] && y < keys[nKeys-1][1][1]) {
document.body.style.cursor = "pointer";
} else {
document.body.style.cursor = "default";
}
});
img.addEventListener("mouseleave", function(e) {
document.body.style.cursor = "default";
});
function handleKey(e) {
var coord = [e.offsetX, e.offsetY];
var scale = fullWidth / this.width;
var x = coord[0] * scale;
var y = coord[1] * scale;
var note = noteFromCoords(x, y);
if (note > -1) {
if (e.type === "mousedown" || e.type === "touchstart") {
document.dispatchEvent(new CustomEvent('midi-note-on', { 'detail': note }));
} else if (e.type == "mouseup" || e.type === "touchend") {
document.dispatchEvent(new CustomEvent('midi-note-off', { 'detail': note }));
}
}
}
img.addEventListener("mousedown", handleKey);
img.addEventListener("mouseup", handleKey);
img.addEventListener("touchstart", handleKey);
img.addEventListener("touchend", handleKey);
var noteShadows = {};
function showKeyShadow(e) {
if (!(e.detail in noteShadows)) {
var coords = coordsFromNote(e.detail);
var xOffset = img.offsetLeft;
var yOffset = img.offsetTop;
var scale = fullWidth / img.width;
var shadow = document.createElement("div");
var cont = document.querySelector("#op1-keys-container");
shadow.classList.add("key-shadow");
cont.appendChild(shadow);
shadow.style.left = (coords[0][0] / scale) + xOffset + "px";
shadow.style.top = (coords[0][1] / scale) + yOffset + "px";
shadow.style.width = (coords[1][0] - coords[0][0]) / scale + "px";
shadow.style.height = (coords[1][1] - coords[0][1]) / scale + "px";
shadow.style.opacity = 1;
noteShadows[e.detail] = shadow;
} else {
noteShadows[e.detail].style.opacity = 1;
}
}
function hideKeyShadow(e) {
if (e.detail in noteShadows) {
noteShadows[e.detail].style.opacity = 0;
}
}
document.removeEventListener('midi-note-on', showKeyShadow);
document.removeEventListener('midi-note-off', hideKeyShadow);
document.addEventListener('midi-note-on', showKeyShadow);
document.addEventListener('midi-note-off', hideKeyShadow);
window.addEventListener("resize", function() {
for (var n in noteShadows) { noteShadows[n].remove(); }
noteShadows = {};
});
img.setAttribute("data-ready", true);
}
})(document, window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment