Skip to content

Instantly share code, notes, and snippets.

@jbrains
Last active April 2, 2017 21:06
Show Gist options
  • Save jbrains/4dbb425486fc4dcb14285d00c4d65016 to your computer and use it in GitHub Desktop.
Save jbrains/4dbb425486fc4dcb14285d00c4d65016 to your computer and use it in GitHub Desktop.
Finding functional/reusable bits in a small amount of Javascript. Especially trying to push details up the call stack.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Drum Kit</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="keys">
<div data-key="65" class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
<div data-key="83" class="key">
<kbd>S</kbd>
<span class="sound">hihat</span>
</div>
<div data-key="68" class="key">
<kbd>D</kbd>
<span class="sound">kick</span>
</div>
<div data-key="70" class="key">
<kbd>F</kbd>
<span class="sound">openhat</span>
</div>
<div data-key="71" class="key">
<kbd>G</kbd>
<span class="sound">boom</span>
</div>
<div data-key="72" class="key">
<kbd>H</kbd>
<span class="sound">ride</span>
</div>
<div data-key="74" class="key">
<kbd>J</kbd>
<span class="sound">snare</span>
</div>
<div data-key="75" class="key">
<kbd>K</kbd>
<span class="sound">tom</span>
</div>
<div data-key="76" class="key">
<kbd>L</kbd>
<span class="sound">tink</span>
</div>
</div>
<section id="drum-sounds">
<audio data-key="65" src="sounds/clap.wav"></audio>
<audio data-key="83" src="sounds/hihat.wav"></audio>
<audio data-key="68" src="sounds/kick.wav"></audio>
<audio data-key="70" src="sounds/openhat.wav"></audio>
<audio data-key="71" src="sounds/boom.wav"></audio>
<audio data-key="72" src="sounds/ride.wav"></audio>
<audio data-key="74" src="sounds/snare.wav"></audio>
<audio data-key="75" src="sounds/tom.wav"></audio>
<audio data-key="76" src="sounds/tink.wav"></audio>
</section>
<script>
// Generic Javascript
function applySafely(f, x) {
return (x ? f.call(null, x) : null);
}
// Generic DOM manipulation
// CONTRACT: turnElementOn and turnElementOff are functions of a DOM element
// ASSUMES that domElement generates a transition event when it is turned on
function pulseUiElement(domElement, turnElementOn, turnElementOff) {
// ASSUMES that the DOM event's target is the receiver of addEventListener()
domElement.addEventListener('transitionend', event => turnElementOff.call(null, event.target));
turnElementOn.call(null, domElement);
}
// Generic HTML element behavior
// "rewind" means "prepare the audio element to play again"
// CONTRACT: audioElement is an <audio> element, so it can be rewound and played
function rewindThenPlay(audioElement) {
audioElement.currentTime = 0;
audioElement.play();
}
// Specific to this document
// CONTRACT: I can change the CSS class on domElement
function markUiElementPlaying(domElement) {
domElement.classList.add("playing");
}
function markUiElementNotPlaying(domElement) {
domElement.classList.remove("playing");
}
function pulseUiElementPlaying(domElement) {
pulseUiElement(domElement, markUiElementPlaying, markUiElementNotPlaying);
}
function playSoundAndPulseUi(domElement, soundKeyCode) {
const audioElement = domElement.querySelector(`audio[data-key="${soundKeyCode}"]`);
applySafely(rewindThenPlay, audioElement);
const keyUiElement = domElement.querySelector(`.key[data-key="${soundKeyCode}"]`);
applySafely(pulseUiElementPlaying, keyUiElement);
}
window.addEventListener('keydown', event => playSoundAndPulseUi(document, event.keyCode));
</script>
</body>
</html>
@jbrains
Copy link
Author

jbrains commented Apr 2, 2017

$ gloga
* 43da0e7 (HEAD -> jbrains) We now declare functions with a syntax that @hughrawlinson told me provides better stack traces.
[...]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment