Instantly share code, notes, and snippets.
Last active
September 17, 2018 21:20
-
Save wincentbalin/0db1e179558e413a1694e8b26f4ca3f1 to your computer and use it in GitHub Desktop.
Simple browser-based sampler
This file contains 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> | |
<head> | |
<title>Audio buttons</title> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<style type="text/css"> | |
html, | |
body | |
{ | |
width: 99.5%; | |
height: 99%; | |
overflow: hidden; | |
} | |
div.audiobutton | |
{ | |
/* | |
background: #000; | |
color: #fff; | |
//*/ | |
display: inline-block; | |
box-sizing: border-box; | |
-moz-box-sizing: border-box; | |
margin: 5px; | |
border: #888 2px solid; | |
position: relative; | |
} | |
.button-text | |
{ | |
font-size: 2em; | |
} | |
div.label | |
{ | |
text-align: center; | |
color: #f00; | |
margin-top: 10%; | |
} | |
div.status | |
{ | |
text-align: center; | |
color: #f00; | |
margin-top: 10%; | |
font-family: monospace; | |
font-weight: bold; | |
} | |
progress | |
{ | |
width: 99%; | |
position: absolute; | |
bottom: 2px; | |
} | |
</style> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
var createAudioButton = function(fileinfo, hp, vp) | |
{ | |
var filelabel, | |
filename, | |
statusPlaying = '||', | |
statusPaused = '>', | |
buttonElement, | |
labelElement, | |
statusElement, | |
audioElement, | |
createElement = function(tag, html) | |
{ | |
var el = document.createElement(tag); | |
if (html) | |
el.innerHTML = html.trim(); | |
return el; | |
}; | |
if (typeof(fileinfo) === 'string') | |
{ | |
filelabel = fileinfo; | |
filename = fileinfo; | |
} | |
else | |
{ | |
filelabel = fileinfo.label; | |
filename = fileinfo.filename; | |
} | |
buttonElement = createElement('div'); | |
buttonElement.setAttribute('name', filename); | |
buttonElement.classList.add('audiobutton'); | |
labelElement = createElement('div', filelabel) | |
labelElement.classList.add('label'); | |
labelElement.classList.add('button-text'); | |
statusElement = createElement('div', statusPaused); | |
statusElement.classList.add('status'); | |
statusElement.classList.add('button-text'); | |
progressElement = createElement('progress'); | |
progressElement.setAttribute('value', '0'); | |
progressElement.setAttribute('max', '1'); | |
audioElement = createElement('audio'); | |
audioElement.setAttribute('src', filename); | |
buttonElement.append(labelElement); | |
buttonElement.append(statusElement); | |
buttonElement.append(progressElement); | |
buttonElement.append(audioElement); | |
buttonElement.style.width = 'calc(' + hp + '% - 10px)'; | |
buttonElement.style.height = 'calc(' + vp + '% - 10px)'; | |
audioElement.addEventListener('ended', function(event) | |
{ | |
var status = this.parentNode.querySelector('div.status'), | |
audio = this; | |
status.innerHTML = statusPaused; | |
audio.currentTime = 0; // Rewind on end | |
}); | |
audioElement.addEventListener('timeupdate', function(event) | |
{ | |
var progress = this.parentNode.querySelector('progress'), | |
audio = this; | |
progress.value = audio.currentTime / audio.duration; | |
}); | |
buttonElement.addEventListener('mousedown', function(event) | |
{ | |
var status = this.querySelector('div.status'), | |
audio = this.querySelector('audio'); | |
if (audio.paused) | |
{ | |
audio.play(); | |
status.innerHTML = statusPlaying; | |
} | |
else | |
{ | |
audio.pause(); | |
status.innerHTML = statusPaused; | |
} | |
}); | |
buttonElement.addEventListener('contextmenu', function(event) | |
{ | |
var status = this.querySelector('div.status'), | |
audio = this.querySelector('audio'); | |
audio.pause(); | |
audio.currentTime = 0; | |
status.innerHTML = statusPaused; | |
return false; // Or else the real context menu will appear! | |
}); | |
return buttonElement; | |
}; | |
var createAudioButtons = function(fileinfos) | |
{ | |
// Calculate amount of columns and rows | |
// We just calculate the upper bound from the square root of the amount of filenames | |
var amount = fileinfos.length, | |
dim = Math.ceil(Math.sqrt(amount)), | |
rows = (amount % dim === 0) ? amount / dim : Math.floor(amount / dim) + 1, | |
hp = 100 /* % */ / dim, // horizontal percentage | |
vp = 100 / rows, // vertical percentage | |
documentElement = document.querySelector('body'), | |
buttonElements = [], | |
buttonElement; | |
for (var i = 0, col = 0; i < amount; i++) | |
{ | |
if (col < dim) | |
col++; | |
else | |
col = 0; | |
buttonElement = createAudioButton(fileinfos[i], hp, vp); | |
documentElement.append(buttonElement); | |
buttonElements.push(buttonElement); | |
} | |
document.addEventListener('contextmenu', function(event) { event.preventDefault(); return false; }); | |
}; | |
window.createAudioButtons = createAudioButtons; | |
</script> | |
<script type="text/javascript"> | |
var audiofiles = | |
[ | |
{ 'label': 'Anfang Computer', 'filename': 'audio/01_Anfang_Computer.wav' }, | |
{ 'label': 'Skrip+Gespräche', 'filename': 'audio/02_Skrip_dweri_+_Gespraeche.wav' }, | |
{ 'label': 'Skrip kurz', 'filename': 'audio/04_Skrip_dweri_kurz.wav' } | |
]; | |
if (document.attachEvent ? document.readyState === 'complete': document.readyState !== 'loading') | |
createAudioButtons(audiofiles); | |
else | |
document.addEventListener('DOMContentLoaded', function() { createAudioButtons(audiofiles) }); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment