Last active
April 2, 2017 21:06
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
Author
jbrains
commented
Apr 2, 2017
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment