mirror of
https://github.com/captbaritone/webamp
synced 2024-11-22 07:40:51 +00:00
310 lines
9.7 KiB
JavaScript
Executable File
310 lines
9.7 KiB
JavaScript
Executable File
/* Helpful wrapper for the native <audio> element */
|
|
function Media (audioId) {
|
|
this.audio = document.getElementById(audioId);
|
|
|
|
/* Properties */
|
|
this.timeElapsed = function() {
|
|
return this.audio.currentTime;
|
|
}
|
|
this.timeRemaining = function() {
|
|
return this.audio.duration - this.audio.currentTime;
|
|
}
|
|
this.timeElapsedObject = function() {
|
|
return this._timeObject(this.timeElapsed());
|
|
}
|
|
this.timeRemainingObject = function() {
|
|
return this._timeObject(this.timeRemaining());
|
|
}
|
|
this.percentComplete = function() {
|
|
return (this.audio.currentTime / this.audio.duration) * 100;
|
|
}
|
|
|
|
/* Actions */
|
|
this.previous = function() {
|
|
this.audio.currentTime = 0;
|
|
};
|
|
this.play = function() {
|
|
this.audio.play();
|
|
};
|
|
this.pause = function() {
|
|
this.audio.pause();
|
|
};
|
|
this.stop = function() {
|
|
this.audio.pause();
|
|
this.audio.currentTime = 0;
|
|
};
|
|
this.next = function() {
|
|
this.audio.currentTime = this.audio.duration;
|
|
};
|
|
this.toggleRepeat = function() {
|
|
this.audio.loop = !this.audio.loop;
|
|
};
|
|
this.toggleShuffle = function() {
|
|
// Not implemented
|
|
};
|
|
|
|
/* Actions with arguments */
|
|
this.seekToPercentComplete = function(percent) {
|
|
this.audio.currentTime = this.audio.duration * (percent/100);
|
|
this.audio.play();
|
|
};
|
|
this.setVolume = function(volume) {
|
|
this.audio.volume = volume;
|
|
};
|
|
this.loadFile = function(file) {
|
|
this.audio.setAttribute('src', file);
|
|
};
|
|
|
|
/* Listeners */
|
|
this.addEventListener = function(event, callback) {
|
|
this.audio.addEventListener(event, callback);
|
|
};
|
|
|
|
/* Helpers */
|
|
this._timeObject = function(seconds) {
|
|
var minutes = seconds / 60;
|
|
var seconds = seconds % 60;
|
|
|
|
return [
|
|
Math.floor(minutes / 10),
|
|
Math.floor(minutes % 10),
|
|
Math.floor(seconds / 10),
|
|
Math.floor(seconds % 10)
|
|
];
|
|
}
|
|
}
|
|
|
|
function Winamp () {
|
|
self = this;
|
|
this.media = new Media('player');
|
|
this.media.setVolume(.5);
|
|
|
|
this.nodes = {
|
|
'close': document.getElementById('close'),
|
|
'position': document.getElementById('position'),
|
|
'fileInput': document.getElementById('file-input'),
|
|
'time': document.getElementById('time'),
|
|
'previous': document.getElementById('previous'),
|
|
'play': document.getElementById('play'),
|
|
'pause': document.getElementById('pause'),
|
|
'stop': document.getElementById('stop'),
|
|
'next': document.getElementById('next'),
|
|
'eject': document.getElementById('eject'),
|
|
'repeat': document.getElementById('repeat'),
|
|
'shuffle': document.getElementById('shuffle'),
|
|
'volume': document.getElementById('volume'),
|
|
'balance': document.getElementById('balance'),
|
|
'playPause': document.getElementById('play-pause'),
|
|
'winamp': document.getElementById('winamp'),
|
|
};
|
|
|
|
this.nodes.close.onclick = function() {
|
|
}
|
|
|
|
this.media.addEventListener('timeupdate', function() {
|
|
self.nodes.position.value = self.media.percentComplete();
|
|
self.updateTime();
|
|
});
|
|
|
|
this.media.addEventListener('ended', function() {
|
|
self.setStatus('stop');
|
|
self.media.previous();
|
|
});
|
|
|
|
this.nodes.time.onclick = function() {
|
|
this.classList.toggle('countdown');
|
|
self.updateTime();
|
|
}
|
|
|
|
this.nodes.previous.onclick = function() {
|
|
self.media.previous();
|
|
}
|
|
|
|
this.nodes.play.onclick = function() {
|
|
self.media.play();
|
|
self.setStatus('play');
|
|
}
|
|
this.nodes.pause.onclick = function() {
|
|
self.media.pause();
|
|
self.setStatus('pause');
|
|
}
|
|
this.nodes.stop.onclick = function() {
|
|
self.media.stop();
|
|
self.setStatus('stop');
|
|
}
|
|
this.nodes.next.onclick = function() {
|
|
self.media.next();
|
|
}
|
|
|
|
this.nodes.eject.onclick = function() {
|
|
self.nodes.fileInput.click();
|
|
}
|
|
|
|
this.nodes.fileInput.onchange = function(e){
|
|
var file = e.target.files[0];
|
|
var objectUrl = URL.createObjectURL(file);
|
|
self.loadFile(objectUrl, file.name);
|
|
self.media.play();
|
|
self.setStatus('play');
|
|
}
|
|
|
|
this.nodes.volume.oninput = function() {
|
|
setVolume( this.value / 100);
|
|
}
|
|
|
|
this.nodes.position.onmousedown = function() {
|
|
self.media.pause();
|
|
}
|
|
|
|
this.nodes.position.onchange = function() {
|
|
self.media.seekToPercentComplete(this.value);
|
|
}
|
|
|
|
this.nodes.balance.oninput = function() {
|
|
setBalance( this.value / 100);
|
|
}
|
|
this.nodes.repeat.onclick = function() {
|
|
toggleRepeat();
|
|
}
|
|
this.nodes.shuffle.onclick = function() {
|
|
toggleShuffle();
|
|
}
|
|
|
|
this.setStatus = function(className) {
|
|
self.nodes.playPause.removeAttribute("class");
|
|
self.nodes.playPause.classList.add(className);
|
|
}
|
|
function setVolume(volume) {
|
|
sprite = Math.round(volume * 28);
|
|
offset = (sprite - 1) * 15;
|
|
self.media.setVolume(volume);
|
|
self.nodes.volume.style.backgroundPosition = '0 -' + offset + 'px';
|
|
}
|
|
|
|
function setBalance(balance) {
|
|
offset = Math.abs(balance - .5) * 2;
|
|
sprite = Math.floor(offset * 28);
|
|
offset = (sprite - 1) * 15;
|
|
console.log(self.nodes.balance.style);
|
|
self.nodes.balance.style.backgroundPosition = '-9px -' + offset + 'px';
|
|
}
|
|
|
|
function toggleRepeat() {
|
|
self.media.toggleRepeat();
|
|
self.nodes.repeat.classList.toggle('selected');
|
|
}
|
|
|
|
function toggleShuffle() {
|
|
self.media.toggleShuffle();
|
|
self.nodes.shuffle.classList.toggle('selected');
|
|
}
|
|
|
|
this.updateTime = function() {
|
|
if(this.nodes.time.classList.contains('countdown')) {
|
|
digits = this.media.timeRemainingObject();
|
|
} else {
|
|
digits = this.media.timeElapsedObject();
|
|
}
|
|
html = digitHtml(digits[0]);
|
|
document.getElementById('minute-first-digit').innerHTML = '';
|
|
document.getElementById('minute-first-digit').appendChild(html);
|
|
html = digitHtml(digits[1]);
|
|
document.getElementById('minute-second-digit').innerHTML = '';
|
|
document.getElementById('minute-second-digit').appendChild(html);
|
|
html = digitHtml(digits[2]);
|
|
document.getElementById('second-first-digit').innerHTML = '';
|
|
document.getElementById('second-first-digit').appendChild(html);
|
|
html = digitHtml(digits[3]);
|
|
document.getElementById('second-second-digit').innerHTML = '';
|
|
document.getElementById('second-second-digit').appendChild(html);
|
|
}
|
|
|
|
this.loadFile = function(file, fileName) {
|
|
this.media.loadFile(file);
|
|
html = fontHtml(fileName);
|
|
document.getElementById('song-title').innerHTML = '';
|
|
document.getElementById('song-title').appendChild(html);
|
|
html = fontHtml("128");
|
|
document.getElementById('kbps').innerHTML = '';
|
|
document.getElementById('kbps').appendChild(html);
|
|
html = fontHtml("44");
|
|
document.getElementById('khz').innerHTML = '';
|
|
document.getElementById('khz').appendChild(html);
|
|
this.updateTime();
|
|
}
|
|
|
|
function digitHtml(digit) {
|
|
horizontalOffset = digit * 9;
|
|
div = document.createElement('div');
|
|
div.classList.add('digit');
|
|
div.style.backgroundPosition = '-' + horizontalOffset + 'px 0';
|
|
div.innerHTML = digit;
|
|
return div;
|
|
}
|
|
|
|
function fontHtml(string) {
|
|
parentDiv = document.createElement('div');
|
|
for (var i = 0, len = string.length; i < len; i++) {
|
|
char = string[i].toLowerCase();
|
|
parentDiv.appendChild(charHtml(char));
|
|
}
|
|
return parentDiv;
|
|
}
|
|
|
|
function charHtml(char) {
|
|
position = charPosition(char);
|
|
row = position[0];
|
|
column = position[1];
|
|
verticalOffset = row * 6;
|
|
horizontalOffset = column * 5;
|
|
|
|
div = document.createElement('div');
|
|
div.classList.add('character');
|
|
x = '-' + horizontalOffset + 'px';
|
|
y = '-' + verticalOffset + 'px'
|
|
div.style.backgroundPosition = x + ' ' + y;
|
|
div.innerHTML = char;
|
|
return div;
|
|
}
|
|
|
|
function charPosition(char) {
|
|
position = fontLookup[char];
|
|
if(!position) {
|
|
return fontLookup[' '];
|
|
}
|
|
|
|
return position;
|
|
}
|
|
|
|
/* XXX There are too many " " and "_" characters */
|
|
var fontLookup = {
|
|
"a": [0,0], "b": [0,1], "c": [0,2], "d": [0,3], "e": [0,4], "f": [0,5],
|
|
"g": [0,6], "h": [0,7], "i": [0,8], "j": [0,9], "k": [0,10],
|
|
"l": [0,11], "m": [0,12], "n": [0,13], "o": [0,14], "p": [0,15],
|
|
"q": [0,16], "r": [0,17], "s": [0,18], "t": [0,19], "u": [0,20],
|
|
"v": [0,21], "w": [0,22], "x": [0,23], "y": [0,24], "z": [0,25],
|
|
"\"": [0,26], "@": [0,27], " ": [0,29], "0": [1,0], "1": [1,1],
|
|
"2": [1,2], "3": [1,3], "4": [1,4], "5": [1,5], "6": [1,6], "7": [1,7],
|
|
"8": [1,8], "9": [1,9], " ": [1,10], "_": [1,11], ":": [1,12],
|
|
"(": [1,13], ")": [1,14], "-": [1,15], "'": [1,16], "!": [1,17],
|
|
"_": [1,18], "+": [1,19], "\\": [1,20], "/": [1,21], "[": [1,22],
|
|
"]": [1,23], "^": [1,24], "&": [1,25], "%": [1,26], ".": [1,27],
|
|
"=": [1,28], "$": [1,29], "#": [1,30], "Å": [2,0], "Ö": [2,1],
|
|
"Ä": [2,2], "?": [2,3], "*": [2,4], " ": [2,5]
|
|
};
|
|
}
|
|
|
|
keylog = [];
|
|
trigger = [78,85,76,27,76,27,83,79,70,84];
|
|
// Easter Egg
|
|
document.onkeyup = function(e){
|
|
keylog.push(e.which);
|
|
keylog = keylog.slice(-10);
|
|
if(keylog.toString() == trigger.toString()) {
|
|
document.getElementById('winamp').classList.toggle('llama');
|
|
}
|
|
}
|
|
|
|
winamp = new Winamp();
|
|
winamp.loadFile('http://jordaneldredge.com/projects/winamp2-js/llama.mp3', 'llama.mp3');
|