mirror of https://github.com/kurisufriend/0x40-web
parent
0c28b13314
commit
bf556b1996
@ -0,0 +1,124 @@ |
||||
// callback is given a populated song object
|
||||
function loadSong(song, callback) { |
||||
if(song.buffer) { |
||||
callback(song); |
||||
return; |
||||
} |
||||
if(song.isLoading) { |
||||
return; // we're already trying to load this
|
||||
} |
||||
song.isLoading = true; |
||||
song.tmpBuf = {}; |
||||
if(song.buildUp) { |
||||
loadAudioFile(song, true, callback); |
||||
} |
||||
loadAudioFile(song, false, callback); |
||||
} |
||||
|
||||
function loadAudioFile(song, isBuild, callback) { |
||||
var filename = isBuild ? song.buildUp : song.file; |
||||
var req = new XMLHttpRequest(); |
||||
req.open('GET', filename, true); |
||||
req.responseType = 'arraybuffer'; |
||||
req.onload = function() { |
||||
audio.context.decodeAudioData( |
||||
req.response, |
||||
function(buffer) { |
||||
if(isBuild) { |
||||
song.tmpBuf.build = trimSilence(buffer); |
||||
} else { |
||||
song.tmpBuf.loop = trimSilence(buffer); |
||||
} |
||||
onSongLoad(song, callback); |
||||
}, |
||||
function() { |
||||
console.log('Error decoding audio "' + filename + '".'); |
||||
} |
||||
); |
||||
}; |
||||
req.send(); |
||||
} |
||||
|
||||
function onSongLoad(song, callback) { |
||||
// if this fails, we need to wait for the other part to load
|
||||
if(song.tmpBuf.loop && (!song.buildUp || song.tmpBuf.build)) { |
||||
if(song.buildUp) { |
||||
song.buffer = concatenateAudioBuffers(song.tmpBuf.build, song.tmpBuf.loop); |
||||
song.loopStart = song.tmpBuf.build.duration; |
||||
} else { |
||||
song.buffer = song.tmpBuf.loop; |
||||
song.loopStart = 0; |
||||
} |
||||
song.loopLength = song.buffer.duration - song.loopStart; |
||||
// free dat memory
|
||||
song.tmpBuf = null; |
||||
song.isLoading = false; |
||||
callback(song); |
||||
} |
||||
} |
||||
|
||||
// because MP3 is bad
|
||||
function trimSilence(buffer) { |
||||
// how much silence we have
|
||||
var minSilence = buffer.length; |
||||
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]; |
||||
} |
||||
} |
||||
|
||||
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; |
||||
}; |
@ -0,0 +1,92 @@ |
||||
body { |
||||
background-color:#ffffff; |
||||
height: 100%; |
||||
min-height: 100%; |
||||
margin: 0px; |
||||
} |
||||
|
||||
#waifu { |
||||
width: 100%; |
||||
|
||||
#position: absolute; |
||||
padding: 0; |
||||
top: 0; |
||||
left: 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: -5; |
||||
} |
||||
|
||||
#blackout { |
||||
background-color: #000; |
||||
display: none; |
||||
pointer-events:none; |
||||
width: 100%; |
||||
height: 100%; |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
z-index: 1; |
||||
} |
||||
|
||||
#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; |
||||
pointer-events:none; |
||||
animation-name: fadeout; |
||||
animation-duration: 3s; |
||||
-webkit-animation-name: fadeout; |
||||
-webkit-animation-duration: 3s; |
||||
} |
||||
|
||||
#controls { |
||||
font-family: monospace; |
||||
background-color:#ffffff; |
||||
width:800px; |
||||
#position: absolute; |
||||
top: 10px; |
||||
left: 10px; |
||||
z-index: 2; |
||||
} |
||||
|
||||
@keyframes fadein { |
||||
from {opacity: 0;} |
||||
to {opacity: 1;} |
||||
} |
||||
@keyframes fadeout { |
||||
from {opacity: 1;} |
||||
to {opacity: 0;} |
||||
} |
@ -0,0 +1,81 @@ |
||||
var canvas; |
||||
var needsRedraw = false; |
||||
|
||||
var waifuImgs = new Array(); |
||||
|
||||
var blurTime = 8; |
||||
var blurIterations = 20; |
||||
var blurMin = -blurIterations/2; |
||||
var blurMax = blurIterations/2; |
||||
var blurDistance = 4; |
||||
var xBlur = 0; |
||||
var yBlur = 0; |
||||
var shortBlackout = false; |
||||
|
||||
waifuCanvas = {}; |
||||
|
||||
waifuCanvas.init = function() { |
||||
canvas = document.getElementById("waifu").getContext("2d"); |
||||
canvas.drawImage(waifuImgs[0], 0, 0); |
||||
} |
||||
|
||||
waifuCanvas.preload = function() { |
||||
for(var waifu in waifus) { |
||||
newImg = new Image(); |
||||
newImg.onload = onFileLoad; |
||||
newImg.src = 'images/' + waifus[waifu].file; |
||||
waifuImgs[waifu] = newImg; |
||||
} |
||||
} |
||||
|
||||
waifuCanvas.redraw = function() { |
||||
canvas.clearRect(0,0,1280,720); |
||||
|
||||
if(xBlur) { |
||||
canvas.globalAlpha = 1/blurIterations; |
||||
for(var i=blurMin; i<blurMax; i++) { |
||||
canvas.drawImage(waifuImgs[nCurrentWaifu], blurDistance * i * xBlur, 0); |
||||
} |
||||
} else if(yBlur) { |
||||
canvas.globalAlpha = 1/blurIterations; |
||||
for(var i=blurMin; i<blurMax; i++) { |
||||
canvas.drawImage(waifuImgs[nCurrentWaifu], 0, blurDistance * i * yBlur); |
||||
} |
||||
} else { |
||||
canvas.globalAlpha = 1; |
||||
canvas.drawImage(waifuImgs[nCurrentWaifu], 0, 0); |
||||
} |
||||
|
||||
needsRedraw = false; |
||||
} |
||||
|
||||
waifuCanvas.animationLoop = function() { |
||||
if(xBlur) { |
||||
xBlur--; |
||||
waifuCanvas.redraw(); |
||||
} |
||||
else if(yBlur) { |
||||
yBlur--; |
||||
waifuCanvas.redraw(); |
||||
} else if(needsRedraw){ |
||||
waifuCanvas.redraw(); |
||||
} |
||||
} |
||||
|
||||
waifuCanvas.newWaifu = function() { |
||||
GetRandomWaifu(); // increments the waifu counter
|
||||
needsRedraw = true; |
||||
} |
||||
|
||||
waifuCanvas.xBlur = function() { |
||||
xBlur = blurTime; |
||||
yBlur = 0; |
||||
needsRedraw = true; |
||||
} |
||||
|
||||
waifuCanvas.yBlur = function() { |
||||
yBlur = blurTime; |
||||
xBlur = 0; |
||||
needsRedraw = true; |
||||
} |
||||
|
Loading…
Reference in new issue