Canvas is the way to go - rename to main index

serial
William Toohey 10 years ago
parent 6010f6707b
commit 92bd1193cc
  1. 382
      index.html
  2. 346
      index_canvas.html
  3. 95
      style.css
  4. 103
      style_canvas.css

@ -5,14 +5,11 @@
Clean up the damn code Clean up the damn code
if you're not mon, don't read any further, it's pretty bad JS if you're not mon, don't read any further, it's pretty bad JS
Performance in chrome
Loading screen
Volume controls Volume controls
Prettier ui Prettier ui
Song shuffle Song shuffle
Image pause Image pause / manual advance
Fine tune blur Keep arraybuffer in mem, load AudioBuffer as needed?
Keyboard shortcuts
Different colour palettes Different colour palettes
External respacks External respacks
Change short blackout to beat length / 1.7 Change short blackout to beat length / 1.7
@ -23,46 +20,20 @@
<title>0x40</title> <title>0x40</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" height="0">
<filter id="blur">
<feGaussianBlur stdDeviation="0 0">
<animate attributeName="stdDeviation" attributeType="XML"
begin="indefinite" end="indefinite" dur="0.1s"
fill="freeze" from="0 70" to="0 0"/>
<animate attributeName="stdDeviation" attributeType="XML"
begin="indefinite" end="indefinite" dur="0.1s"
fill="freeze" from="70 0" to="0 0"/>
</feGaussianBlur>
</filter>
</svg>
<!-- Won't work in the CSS without referencing index.html, yay -->
<style type='text/css'>
#waifu {
filter: url(#blur);
-webkit-filter: url(#blur);
}
</style>
<script type="text/javascript" src="0x40.js"></script> <script type="text/javascript" src="0x40.js"></script>
<script type="text/javascript" src="waifuCanvas.js"></script>
<script type="text/javascript" src="audioUtils.js"></script>
<script type="text/javascript"> <script type="text/javascript">
//debug //debug
var noAutoPlay = false; var skipPreloader = false;
var leftToLoad = waifus.length; var filesLoaded = 0;
var initialLoad = true; var initialLoad = 0;
var shortBlackout = false;
// Milliseconds! var preloaderSong = null;
var animationLoopTime = 50;
// Seconds!
var animationLookAhead = 0.2;
var tmpSong = {};
//--------------
// Audio Object
//--------------
var audio = { var audio = {
buffer: {}, buffer: null,
proceed: true, proceed: true,
songs: rgSongs, songs: rgSongs,
current_song: null, current_song: null,
@ -70,46 +41,56 @@
beat_pointer: 0, beat_pointer: 0,
} }
audio.play = function() { // Why does this exist? For smooth preloader transition on FF
if(audio.current_song && audio.current_song._playing) { audio.prep = function() {
return; var song = audio.songs[audio.current_index];
}
document.getElementById("songname").innerHTML = audio.songs[audio.current_index].name document.getElementById("songname").innerHTML = song.name
document.getElementById("blackout").style.display = "none"; waifuCanvas.clearBlackout();
// stop() destroys the old, must recreate // stop() destroys the old, must recreate
var newSong = audio.context.createBufferSource() var newSong = audio.context.createBufferSource()
audio.current_song = newSong; audio.current_song = newSong;
newSong.buffer = audio.buffer[audio.current_index]; newSong.buffer = song.buffer;
newSong.loop = true; newSong.loop = true;
newSong.loopStart = audio.buffer[audio.current_index]._loopStart; newSong.loopStart = song.loopStart;
newSong.loopEnd = audio.buffer[audio.current_index].duration; newSong.loopEnd = song.buffer.duration;
newSong._loopLength = audio.buffer[audio.current_index]._loopLength; newSong.loopLength = song.loopLength;
newSong.connect(audio.context.destination); newSong.connect(audio.context.destination);
var songInfo = audio.songs[audio.current_index]; newSong._build = song.buildUpRhythm || "";
newSong._build = songInfo.buildUpRhythm || ""; newSong._beats = newSong._build + song.rhythm;
newSong._beats = newSong._build + songInfo.rhythm;
audio.beat_pointer = -newSong._build.length;
newSong._loopWidth = newSong._loopLength / songInfo.rhythm.length; newSong._loopWidth = newSong.loopLength / song.rhythm.length;
newSong._buildWidth = newSong._build ? newSong.loopStart / newSong._build.length : 0; newSong._buildWidth = newSong._build ? newSong.loopStart / newSong._build.length : 0;
newSong._beatWidth = newSong._buildWidth; newSong._beatWidth = newSong._buildWidth;
audio.beat_pointer = -newSong._build.length;
document.getElementById("beets").innerHTML = wrapBeats(0, 100); document.getElementById("beets").innerHTML = wrapBeats(0, 100);
document.getElementById("timer").innerHTML = "T=0x0000" document.getElementById("timer").innerHTML = "T=0x0000"
}
newSong.start(0); audio.play = function(delay) {
if(!audio.current_song) {
audio.prep();
}
var cur = audio.current_song;
if(cur._playing) {
return;
}
delay = delay ? delay: 0;
cur.start(audio.context.currentTime + delay);
// offset to after the build // offset to after the build
newSong._startTime = audio.context.currentTime + newSong.loopStart; cur._startTime = audio.context.currentTime + cur.loopStart + delay;
newSong._playing = true; cur._playing = true;
} }
audio.stop = function() { audio.stop = function() {
if (audio.current_song && audio.current_song._playing) { if (audio.current_song && audio.current_song._playing) {
audio.current_song.stop(); audio.current_song.stop();
audio.current_song._playing = false; audio.current_song = null;
audio.current_song._startTime = 0;
} }
} }
@ -128,19 +109,17 @@
audio.playIndex = function(index) { audio.playIndex = function(index) {
audio.current_index = index; audio.current_index = index;
if(audio.buffer[index]) { loadSong(audio.songs[index], function() {
audio.stop(); audio.stop();
audio.play(); audio.play();
} else { });
loadSong(index);
}
} }
// In seconds, relative to the loop start // In seconds, relative to the loop start
function currentTime() { function currentTime() {
var cur = audio.current_song; var cur = audio.current_song;
var time = audio.context.currentTime - cur._startTime; var time = audio.context.currentTime - cur._startTime;
return time;// < 0 ? time : time % cur._loopLength; return time;
} }
function wrapBeats(start, length) { function wrapBeats(start, length) {
@ -165,39 +144,33 @@
} }
} }
function timerLoop() { function timerUpdate() {
window.requestAnimationFrame(timerLoop);
if(!audio.current_song || !audio.current_song._playing) { if(!audio.current_song || !audio.current_song._playing) {
return; return;
} }
var now = currentTime(); var now = currentTime();
if(now < 0) if(now < 0)
return; return;
now %= audio.current_song._loopLength; now %= audio.current_song.loopLength;
now = parseInt(now * 1000); now = parseInt(now * 1000);
document.getElementById("timer").innerHTML = "T=0x" + pad(now.toString(16).toUpperCase(), 4); document.getElementById("timer").innerHTML = "T=0x" + pad(now.toString(16).toUpperCase(), 4);
} }
function animationLoop() { function animationLoop() {
requestAnimationFrame(animationLoop); requestAnimationFrame(animationLoop);
//setTimeout(animationLoop, animationLoopTime); timerUpdate();
waifuCanvas.animationLoop();
var cur = audio.current_song; var cur = audio.current_song;
if(!cur || !cur._playing) if(!cur || !cur._playing) {
return; return;
}
var now = currentTime(); var now = currentTime();
var future = now + animationLookAhead;
if(audio.beat_pointer >=0) if(audio.beat_pointer >=0)
cur._beatWidth = cur._loopWidth; cur._beatWidth = cur._loopWidth;
for(var beatTime = audio.beat_pointer * cur._beatWidth; beatTime < future; for(var beatTime = audio.beat_pointer * cur._beatWidth; beatTime < now;
beatTime = ++audio.beat_pointer * cur._beatWidth) { beatTime = ++audio.beat_pointer * cur._beatWidth) {
var beat = getBeat(audio.beat_pointer); var beat = getBeat(audio.beat_pointer);
var timeout = (beatTime - now)*1000; handleBeat(beat, audio.beat_pointer, RequestNextColor(), nCurrentColor, cur);
// Either lagging behind or first note
if(timeout < 0)
timeout = 0;
setTimeout(
handleBeat, timeout,
beat, audio.beat_pointer, RequestNextColor(), nCurrentColor, cur);
} }
} }
@ -205,170 +178,94 @@
// we have changed song since we were scheduled // we have changed song since we were scheduled
if(current != audio.current_song) if(current != audio.current_song)
return; return;
document.getElementById("beets").innerHTML = wrapBeats(bp+1, 100); var beatLine = wrapBeats(bp+1, 100);
document.getElementById("beets").innerHTML = beatLine; // add reversed bit later
// I probably shouldn't have so much on one line // I probably shouldn't have so much on one line
document.getElementById("beatCount").innerHTML = "B=0x" + pad(bp < 0 ? 0: loopBeat(bp).toString(16).toUpperCase(), 4); document.getElementById("beatCount").innerHTML = "B=0x" + pad(bp < 0 ? 0: loopBeat(bp).toString(16).toUpperCase(), 4);
if(beat != '.') { if(beat != '.') {
if(beat == '|') { if(beat == '|') {
shortBlackout = true; shortBlackout = true;
document.getElementById("blackout").style.display = "block"; waifuCanvas.blackout();
return; return;
} }
if(beat == '+') { if(beat == '+') {
document.getElementById("blackout").style.display = "block"; waifuCanvas.blackout();
return; return;
} else { } else {
document.getElementById("blackout").style.display = "none"; waifuCanvas.clearBlackout();
} }
if(beat != ':' && beat != 'O' && beat != 'X') { if(beat != ':' && beat != 'O' && beat != 'X') {
var waifu = GetRandomWaifu(); waifuCanvas.newWaifu();
var waifuDiv = document.getElementsByClassName('waifuImg')[nCurrentWaifu]; document.getElementById("waifuName").innerHTML = waifus[nCurrentWaifu].name;
current = document.getElementsByClassName('active');
if(current.length) {
current[0].style.display = "none";
current[0].className = "waifuImg";
}
waifuDiv.style.display = "block";
waifuDiv.className = "waifuImg active";
document.getElementById("waifuName").innerHTML = waifu.name;
} }
if(beat != '*' && beat != 'X' && beat != 'O') { if(beat != '*' && beat != 'X' && beat != 'O') {
document.getElementById("waifuColour").style.backgroundColor = c; waifuCanvas.setColour(c);
document.getElementById("colourName").innerHTML = colors[cc]; document.getElementById("colourName").innerHTML = colors[cc];
} }
if(beat.toLowerCase() == 'o') { if(beat.toLowerCase() == 'o') {
$("#blur animate").get(1).beginElement(); waifuCanvas.xBlur();
} }
if(beat.toLowerCase() == 'x') { if(beat.toLowerCase() == 'x') {
$("#blur animate").get(0).beginElement(); waifuCanvas.yBlur();
} }
} }
if(shortBlackout) { if(shortBlackout) {
document.getElementById("blackout").style.display = "none"; waifuCanvas.clearBlackout();
shortBlackout = false; shortBlackout = false;
} }
} }
function loadSong(index) { function onFileLoad(file) {
leftToLoad++; filesLoaded++;
tmpSong[0] = tmpSong[1] = null; var percent = Math.floor(filesLoaded / initialLoad * 0x40);
if(audio.songs[index].buildUp) { document.getElementById("preloader").innerHTML = '0x' + pad(percent.toString(16), 2);
leftToLoad++; // Destroy FF lag
loadAudio(audio.songs[index].buildUp, index, 0); if(!skipPreloader && file && file.name == "Madeon - Finale") {
audio.prep();
} }
loadAudio(audio.songs[index].file, index, 1); if(filesLoaded >= initialLoad)
onAllLoaded();
} }
function loadAudio(filename, index, tmpArray) { function onAllLoaded() {
var req = new XMLHttpRequest(); waifuCanvas.init();
req.open('GET', filename, true); console.log("Completed inital load");
req.responseType = 'arraybuffer'; animationLoop();
req.onload = function() { document.getElementById("preloader").style.color = "#0F0";
audio.context.decodeAudioData( if(skipPreloader)
req.response,
function(buffer) {
tmpSong[tmpArray] = trimSilence(buffer);
if(!--leftToLoad) {
onFilesLoaded(index);
}
},
function() {
console.log('Error decoding audio "' + filename + '".');
}
);
};
req.send();
}
function onFilesLoaded(index) {
var buf;
// is there a buildup?
if(tmpSong[0]) {
buf = concatenateAudioBuffers(tmpSong[0],tmpSong[1]);
} else {
buf = tmpSong[1];
}
buf._loopStart = tmpSong[0] ? tmpSong[0].duration : 0;
buf._loopLength = buf.duration - buf._loopStart;
audio.buffer[index] = buf;
if(initialLoad) {
document.getElementById('waifu').className = "loaded";
initialLoad = false;
if(noAutoPlay)
return; return;
var fileProgress = (audio.context.currentTime - preloaderSong.started) % madeonPreload.loopStart;
var timeToFade = madeonPreload.loopStart - fileProgress;
audio.play(preloaderSong.buffer.duration - fileProgress);
setTimeout( function() {
document.getElementById("preloader").className = "loaded"
}, timeToFade * 1000);
// hacky disgusting chrome workaround
if (/Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor)){
preloaderSong.stop();
preloaderSong = chromeHacks(madeonPreload, fileProgress);
} else {
preloaderSong.loop = false;
} }
audio.playIndex(index); preloaderSong.onended = function() {
} // get around issues on mobile where pointer-events
// doesn't work
// because MP3 is bad document.getElementById("preloader").style.display = "none";
function trimSilence(buffer) { document.getElementById("waifu").className = "loaded"
// how much silence we have // free dat memory
var minSilence = buffer.length; preloaderSong = null;
var maxSilence = 0;
for(var i=0; i<buffer.numberOfChannels; i++) {
var tmp = buffer.getChannelData(i);
for(var j=0; j < tmp.length; j++) {
// end of silence
if(tmp[j] != 0) {
if(j < minSilence) {
minSilence = j;
}
break;
}
}
// because just padding 1 end isn't enough for this codec
for(var j=tmp.length-1; j >= 0 ; j--) {
if(tmp[j] != 0) {
if(j > maxSilence) {
maxSilence = j;
}
break;
}
}
}
// 1152 = one frame, makes the sync better because ID3 tags
// take up that space or some garbage
var ret = audio.context.createBuffer(buffer.numberOfChannels, maxSilence-minSilence-1152, buffer.sampleRate);
for(var i=0; i<buffer.numberOfChannels; i++) {
var oldBuf = buffer.getChannelData(i);
var newBuf = ret.getChannelData(i);
for(var j=0; j<ret.length; j++) {
newBuf[j] = oldBuf[minSilence + j + 1152];
} }
} }
function chromeHacks(song, time) {
var ret = audio.context.createBufferSource()
ret.buffer = song.buffer;
ret.connect(audio.context.destination);
ret.started = audio.context.currentTime;
ret.start(0, time);
return ret; return ret;
} }
function concatenateAudioBuffers(buffer1, buffer2) {
if (!buffer1 || !buffer2) {
console.log("no buffers!");
return null;
}
if (buffer1.numberOfChannels != buffer2.numberOfChannels) {
console.log("number of channels is not the same!");
return null;
}
if (buffer1.sampleRate != buffer2.sampleRate) {
console.log("sample rates don't match!");
return null;
}
var tmp = audio.context.createBuffer(buffer1.numberOfChannels, buffer1.length + buffer2.length, buffer1.sampleRate);
for (var i=0; i<tmp.numberOfChannels; i++) {
var data = tmp.getChannelData(i);
data.set(buffer1.getChannelData(i));
data.set(buffer2.getChannelData(i),buffer1.length);
}
return tmp;
};
window.onload = function() { window.onload = function() {
// Check Web Audio API Support // Check Web Audio API Support
try { try {
@ -380,37 +277,60 @@
alert('Web Audio API not supported in this browser.'); alert('Web Audio API not supported in this browser.');
} }
// preloads, don't update leftToLoad as that's up top // normal, xBlur, yBlur, songs
for(var waifu in waifus) { initialLoad = waifus.length + audio.songs.length;
o = document.createElement('img');
o.src = "images/" + waifus[waifu].file; // Sexy audio preloader
o.onload = function() {if(!--leftToLoad) onFilesLoaded(0);}; if(!skipPreloader) {
} loadSong(madeonPreload, function(song) {
preloaderSong = audio.context.createBufferSource()
preloaderSong.buffer = song.buffer;
preloaderSong.loop = true;
preloaderSong.loopStart = 0;
preloaderSong.loopEnd = song.loopStart;
// actual images preloaderSong.connect(audio.context.destination);
var container = document.getElementById('waifu');
for(var waifu in waifus) { preloaderSong.started = audio.context.currentTime;
o = document.createElement('div'); preloaderSong.start(0);
o.style.backgroundImage = 'url("images/' + waifus[waifu].file + '")'; });
o.className = "waifuImg"; } else {
container.appendChild(o); document.getElementById("preloader").className = "loaded";
document.getElementById("preloader").style.display = "none";
document.getElementById("waifu").className = "loaded";
} }
var megumi = document.getElementsByClassName("waifuImg")[0];
megumi.style.display = "block";
megumi.className = "waifuImg active";
setTimeout( function() { for(var song in audio.songs) {
if (audio.proceed) { loadSong(audio.songs[song], onFileLoad);
audio.playIndex(0);
animationLoop();
timerLoop();
} }
}, 400);
// preload images
waifuCanvas.preload();
}; };
$(document).keydown(function(e) {
switch(e.which) {
case 37: // left
break;
case 38: // up
audio.next();
break;
case 39: // right
break;
case 40: // down
audio.prev();
break;
default: return; // exit this handler for other keys
}
e.preventDefault(); // prevent the default action (scroll / move caret)
});
</script> </script>
</head> </head>
<body> <body>
<div id="preloader">
0x00
</div>
<div id="beets">.xoxoxoxoxoxo</div>
<canvas id="waifu" width="1280" height="720"></canvas>
<div id="controls"> <div id="controls">
<a href="#" onclick="void(audio.stop());">stop</a> <a href="#" onclick="void(audio.stop());">stop</a>
<a href="#" onclick="void(audio.play());">play</a> <a href="#" onclick="void(audio.play());">play</a>
@ -419,14 +339,8 @@
<div id="beatCount">B=0x0000</div> <div id="beatCount">B=0x0000</div>
<div id="timer">T=0x0000</div> <div id="timer">T=0x0000</div>
<div id="songname"></div> <div id="songname"></div>
<div id="beets"></div>
<div id="waifuName"></div> <div id="waifuName"></div>
<div id="colourName"></div> <div id="colourName">white</div>
</div> </div>
<div id="blackout"></div>
<div id="waifu"></div>
<div id="waifuColour"></div>
</body> </body>
</html> </html>

@ -1,346 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" >
<!--
TODO:
Clean up the damn code
if you're not mon, don't read any further, it's pretty bad JS
Volume controls
Prettier ui
Song shuffle
Image pause / manual advance
Keep arraybuffer in mem, load AudioBuffer as needed?
Different colour palettes
External respacks
Change short blackout to beat length / 1.7
Blur into blackout? iunno
-->
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>0x40</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<link rel="stylesheet" href="style_canvas.css">
<script type="text/javascript" src="0x40.js"></script>
<script type="text/javascript" src="waifuCanvas.js"></script>
<script type="text/javascript" src="audioUtils.js"></script>
<script type="text/javascript">
//debug
var skipPreloader = false;
var filesLoaded = 0;
var initialLoad = 0;
var preloaderSong = null;
var audio = {
buffer: null,
proceed: true,
songs: rgSongs,
current_song: null,
current_index: 0,
beat_pointer: 0,
}
// Why does this exist? For smooth preloader transition on FF
audio.prep = function() {
var song = audio.songs[audio.current_index];
document.getElementById("songname").innerHTML = song.name
waifuCanvas.clearBlackout();
// stop() destroys the old, must recreate
var newSong = audio.context.createBufferSource()
audio.current_song = newSong;
newSong.buffer = song.buffer;
newSong.loop = true;
newSong.loopStart = song.loopStart;
newSong.loopEnd = song.buffer.duration;
newSong.loopLength = song.loopLength;
newSong.connect(audio.context.destination);
newSong._build = song.buildUpRhythm || "";
newSong._beats = newSong._build + song.rhythm;
newSong._loopWidth = newSong.loopLength / song.rhythm.length;
newSong._buildWidth = newSong._build ? newSong.loopStart / newSong._build.length : 0;
newSong._beatWidth = newSong._buildWidth;
audio.beat_pointer = -newSong._build.length;
document.getElementById("beets").innerHTML = wrapBeats(0, 100);
document.getElementById("timer").innerHTML = "T=0x0000"
}
audio.play = function(delay) {
if(!audio.current_song) {
audio.prep();
}
var cur = audio.current_song;
if(cur._playing) {
return;
}
delay = delay ? delay: 0;
cur.start(audio.context.currentTime + delay);
// offset to after the build
cur._startTime = audio.context.currentTime + cur.loopStart + delay;
cur._playing = true;
}
audio.stop = function() {
if (audio.current_song && audio.current_song._playing) {
audio.current_song.stop();
audio.current_song = null;
}
}
audio.next = function() {
audio.current_index++;
audio.current_index %= audio.songs.length;
audio.playIndex(audio.current_index);
}
audio.prev = function() {
if(audio.current_index-- <= 0) {
audio.current_index = audio.songs.length - 1;
}
audio.playIndex(audio.current_index);
}
audio.playIndex = function(index) {
audio.current_index = index;
loadSong(audio.songs[index], function() {
audio.stop();
audio.play();
});
}
// In seconds, relative to the loop start
function currentTime() {
var cur = audio.current_song;
var time = audio.context.currentTime - cur._startTime;
return time;
}
function wrapBeats(start, length) {
var ret = '';
for(var i=start; i < start+length; i++) {
ret += getBeat(i);
}
return ret;
}
function loopBeat(index) {
return index %
(audio.current_song._beats.length-audio.current_song._build.length);
}
function getBeat(index) {
var cur = audio.current_song;
if(index < 0) {
return cur._beats.charAt(index + cur._build.length);
} else {
return cur._beats.charAt(loopBeat(index) + cur._build.length);
}
}
function timerUpdate() {
if(!audio.current_song || !audio.current_song._playing) {
return;
}
var now = currentTime();
if(now < 0)
return;
now %= audio.current_song.loopLength;
now = parseInt(now * 1000);
document.getElementById("timer").innerHTML = "T=0x" + pad(now.toString(16).toUpperCase(), 4);
}
function animationLoop() {
requestAnimationFrame(animationLoop);
timerUpdate();
waifuCanvas.animationLoop();
var cur = audio.current_song;
if(!cur || !cur._playing) {
return;
}
var now = currentTime();
if(audio.beat_pointer >=0)
cur._beatWidth = cur._loopWidth;
for(var beatTime = audio.beat_pointer * cur._beatWidth; beatTime < now;
beatTime = ++audio.beat_pointer * cur._beatWidth) {
var beat = getBeat(audio.beat_pointer);
handleBeat(beat, audio.beat_pointer, RequestNextColor(), nCurrentColor, cur);
}
}
function handleBeat(beat, bp, c, cc, current) {
// we have changed song since we were scheduled
if(current != audio.current_song)
return;
var beatLine = wrapBeats(bp+1, 100);
document.getElementById("beets").innerHTML = beatLine; // add reversed bit later
// I probably shouldn't have so much on one line
document.getElementById("beatCount").innerHTML = "B=0x" + pad(bp < 0 ? 0: loopBeat(bp).toString(16).toUpperCase(), 4);
if(beat != '.') {
if(beat == '|') {
shortBlackout = true;
waifuCanvas.blackout();
return;
}
if(beat == '+') {
waifuCanvas.blackout();
return;
} else {
waifuCanvas.clearBlackout();
}
if(beat != ':' && beat != 'O' && beat != 'X') {
waifuCanvas.newWaifu();
document.getElementById("waifuName").innerHTML = waifus[nCurrentWaifu].name;
}
if(beat != '*' && beat != 'X' && beat != 'O') {
waifuCanvas.setColour(c);
document.getElementById("colourName").innerHTML = colors[cc];
}
if(beat.toLowerCase() == 'o') {
waifuCanvas.xBlur();
}
if(beat.toLowerCase() == 'x') {
waifuCanvas.yBlur();
}
}
if(shortBlackout) {
waifuCanvas.clearBlackout();
shortBlackout = false;
}
}
function onFileLoad(file) {
filesLoaded++;
var percent = Math.floor(filesLoaded / initialLoad * 0x40);
document.getElementById("preloader").innerHTML = '0x' + pad(percent.toString(16), 2);
// Destroy FF lag
if(!skipPreloader && file && file.name == "Madeon - Finale") {
audio.prep();
}
if(filesLoaded >= initialLoad)
onAllLoaded();
}
function onAllLoaded() {
waifuCanvas.init();
console.log("Completed inital load");
animationLoop();
document.getElementById("preloader").style.color = "#0F0";
if(skipPreloader)
return;
var fileProgress = (audio.context.currentTime - preloaderSong.started) % madeonPreload.loopStart;
var timeToFade = madeonPreload.loopStart - fileProgress;
audio.play(preloaderSong.buffer.duration - fileProgress);
setTimeout( function() {
document.getElementById("preloader").className = "loaded"
}, timeToFade * 1000);
// hacky disgusting chrome workaround
if (/Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor)){
preloaderSong.stop();
preloaderSong = chromeHacks(madeonPreload, fileProgress);
} else {
preloaderSong.loop = false;
}
preloaderSong.onended = function() {
// get around issues on mobile where pointer-events
// doesn't work
document.getElementById("preloader").style.display = "none";
document.getElementById("waifu").className = "loaded"
// free dat memory
preloaderSong = null;
}
}
function chromeHacks(song, time) {
var ret = audio.context.createBufferSource()
ret.buffer = song.buffer;
ret.connect(audio.context.destination);
ret.started = audio.context.currentTime;
ret.start(0, time);
return ret;
}
window.onload = function() {
// Check Web Audio API Support
try {
// More info at http://caniuse.com/#feat=audio-api
window.AudioContext = window.AudioContext || window.webkitAudioContext;
audio.context = new window.AudioContext();
} catch(e) {
audio.proceed = false;
alert('Web Audio API not supported in this browser.');
}
// normal, xBlur, yBlur, songs
initialLoad = waifus.length + audio.songs.length;
// Sexy audio preloader
if(!skipPreloader) {
loadSong(madeonPreload, function(song) {
preloaderSong = audio.context.createBufferSource()
preloaderSong.buffer = song.buffer;
preloaderSong.loop = true;
preloaderSong.loopStart = 0;
preloaderSong.loopEnd = song.loopStart;
preloaderSong.connect(audio.context.destination);
preloaderSong.started = audio.context.currentTime;
preloaderSong.start(0);
});
} else {
document.getElementById("preloader").className = "loaded";
document.getElementById("preloader").style.display = "none";
document.getElementById("waifu").className = "loaded";
}
for(var song in audio.songs) {
loadSong(audio.songs[song], onFileLoad);
}
// preload images
waifuCanvas.preload();
};
$(document).keydown(function(e) {
switch(e.which) {
case 37: // left
break;
case 38: // up
audio.next();
break;
case 39: // right
break;
case 40: // down
audio.prev();
break;
default: return; // exit this handler for other keys
}
e.preventDefault(); // prevent the default action (scroll / move caret)
});
</script>
</head>
<body>
<div id="preloader">
0x00
</div>
<div id="beets">.xoxoxoxoxoxo</div>
<canvas id="waifu" width="1280" height="720"></canvas>
<div id="controls">
<a href="#" onclick="void(audio.stop());">stop</a>
<a href="#" onclick="void(audio.play());">play</a>
<a href="#" onclick="void(audio.prev());">prev</a>
<a href="#" onclick="void(audio.next());">next</a>
<div id="beatCount">B=0x0000</div>
<div id="timer">T=0x0000</div>
<div id="songname"></div>
<div id="waifuName"></div>
<div id="colourName">white</div>
</div>
</body>
</html>

@ -1,41 +1,49 @@
html, body {
height: 100%;
margin: 0; padding: 0;
}
body { body {
background-color:#ffffff; background-color:#ffffff;
} }
#waifu { #controls {
width: 100%; font-family: monospace;
height: 100%; background-color:#ffffff;
position: absolute; position: absolute;
top: 0; bottom: 0px;
left: 0; left: 50%;
z-index: -10; transform: translate(-50%, 0);
z-index: 3;
opacity: 0;
#-webkit-transform: scale(3);
#transform: scale(3);
#-webkit-transform-origin: top left;
#transform-origin: top left;
} }
#waifu.loaded { #beets {
animation-name: fadein; font-family: monospace;
animation-duration: 1s; background-color:#ffffff;
opacity: 1; position: absolute;
top: 0px;
left: 50%;
transform: translate(-50%, 0);
z-index: 3;
} }
.waifuImg { #waifu {
background-repeat: no-repeat; display: block;
background-position: center center;
-webkit-background-size: cover;
background-size: cover;
width: 100%;
height: 100%; height: 100%;
display: none; #margin-left: auto;
#margin-right: auto;
padding: 0;
z-index: -10;
opacity: 0;
} }
.waifuImg.active { #waifu.loaded {
display: block; opacity: 1;
animation-name: fadein;
animation-duration: 0.5s;
-webkit-animation-name: fadein;
-webkit-animation-duration: 0.5s;
} }
#waifuColour { #waifuColour {
@ -46,31 +54,50 @@ body {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
z-index: -5; z-index: 1;
} }
#blackout { #blackout {
background-color: #000; background-color: #000;
display: none; display: none;
pointer-events:none;
width: 100%; width: 100%;
height: 100%; height: 100%;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
z-index: 1; z-index: 2;
} }
#controls { #preloader {
background-color: #FFF;
width: 100%;
height: 100%;
display:flex;
justify-content:center;
align-items:center;
font-family: monospace; font-family: monospace;
background-color:#ffffff; font-size: 30pt;
width:800px;
position: absolute; position: absolute;
top: 10px; top: 0;
left: 10px; left: 0;
z-index: 2; z-index: 10;
}
#preloader.loaded {
opacity: 0;
animation-name: fadeout;
animation-duration: 3s;
-webkit-animation-name: fadeout;
-webkit-animation-duration: 3s;
} }
@keyframes fadein { @keyframes fadein {
from {opacity: 0;} from {opacity: 0;}
to {opacity: 1;} to {opacity: 1;}
} }
@keyframes fadeout {
from {opacity: 1;}
to {opacity: 0;}
}

@ -1,103 +0,0 @@
html, body {
height: 100%;
margin: 0; padding: 0;
}
body {
background-color:#ffffff;
}
#controls {
font-family: monospace;
background-color:#ffffff;
position: absolute;
bottom: 0px;
left: 50%;
transform: translate(-50%, 0);
z-index: 3;
}
#beets {
font-family: monospace;
background-color:#ffffff;
position: absolute;
top: 0px;
left: 50%;
transform: translate(-50%, 0);
z-index: 3;
}
#waifu {
display: block;
height: 100%;
#margin-left: auto;
#margin-right: auto;
padding: 0;
z-index: -10;
opacity: 0;
}
#waifu.loaded {
opacity: 1;
animation-name: fadein;
animation-duration: 0.5s;
-webkit-animation-name: fadein;
-webkit-animation-duration: 0.5s;
}
#waifuColour {
opacity: 0.7;
mix-blend-mode: hard-light;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
#blackout {
background-color: #000;
display: none;
pointer-events:none;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
#preloader {
background-color: #FFF;
width: 100%;
height: 100%;
display:flex;
justify-content:center;
align-items:center;
font-family: monospace;
font-size: 30pt;
position: absolute;
top: 0;
left: 0;
z-index: 10;
}
#preloader.loaded {
opacity: 0;
animation-name: fadeout;
animation-duration: 3s;
-webkit-animation-name: fadeout;
-webkit-animation-duration: 3s;
}
@keyframes fadein {
from {opacity: 0;}
to {opacity: 1;}
}
@keyframes fadeout {
from {opacity: 1;}
to {opacity: 0;}
}
Loading…
Cancel
Save