Skip to content

Instantly share code, notes, and snippets.

@richgcook
Created June 22, 2016 08:55
Show Gist options
  • Save richgcook/bf66c5d89dae08cb365a9af0506063e4 to your computer and use it in GitHub Desktop.
Save richgcook/bf66c5d89dae08cb365a9af0506063e4 to your computer and use it in GitHub Desktop.
$(function(){
var canvas = document.getElementById('aub');
var $canvas = $(canvas);
var ctx = canvas.getContext('2d');
var DPR = window.devicePixelRatio || 1;
var sounds = [];
var $window = $(window);
var $body = $('body');
var $counter = $('#count');
var $mute = $('#mute');
var currAub = 0;
var currOffset = 0;
var currFrame = 0;
var currFrameWrapped = 0;
var spinDistance = 0;
var numFrames = [100, 101, 53, 50, 50, 101, 101, 101, 101];
var loUrls = [];
var loCanvases = [];
var hiUrls = [];
var hiCanvases = [];
var loadTimer;
var velocity = Math.random() * 50 + 50;
var loading = false;
var muted = false;
function resize(){
var size = Math.min(window.innerWidth, window.innerHeight);
canvas.width = size * DPR;
canvas.height = size * DPR;
$canvas.width(size).height(size);
currFrameWrapped = false;
}
$window.resize(resize);
resize();
function loadImage(src, cb){
var img = new Image();
if(cb) img.onload = function(){
cb(img, src);
};
img.src = src;
return img;
}
function loadImages(srcs, cb){
var imgs = [];
var wrappedCb = _.after(srcs.length, function(){
cb(imgs);
});
_.each(srcs, function(src){
imgs.push(loadImage(src, wrappedCb));
});
}
function pad(number, length){
number = number.toString();
while(number.length < length) number = "0" + number;
return number;
}
function load(which){
loading = true;
$body.addClass('loading');
var frames = numFrames[which];
loUrls = [];
hiUrls = [];
loCanvases = [];
hiCanvases = [];
var filename;
for(var i = 0; i < frames; ++i){
filename = pad(i, 5);
loUrls.push('img/aub' + which + '/lo/img' + filename + '.jpg');
hiUrls.push('img/aub' + which + '/hi/img' + filename + '.jpg');
}
currAub = which;
loadImages(loUrls, function(imgs){
loCanvases = _.map(imgs, imgToCanvas);
loading = false;
$body.removeClass('loading');
});
}
function imgToCanvas(img){
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
return canvas;
}
var lastSound = 0;
function pop(){
if(muted) return;
var now = Date.now();
if(now - lastSound < 50) return;
lastSound = now;
var sound;
for(var i = 0; i < sounds.length; i++){
sound = sounds[i];
if( sound.isPaused() ){
sound.play();
return;
}
}
sound = new buzz.sound('pop.wav');
sounds.push(sound);
sound.play();
}
var sound = new buzz.sound('spook.mp3', {
autoplay: false,
loop: true
})
var sound2 = new buzz.sound('koops.mp3', {
autoplay: false,
loop: true
})
function playSound(speed){
var snd1 = speed < 0 ? sound2 : sound;
var snd2 = speed < 0 ? sound : sound2;
speed = Math.abs(speed);
if(muted || speed < 0.1) {
snd1.pause();
snd2.pause();
} else {
snd2.pause();
snd1.play()
snd1.setSpeed( Math.max(Math.min(speed, 2), 0.5) );
snd1.setVolume( Math.min( ((speed - 0.1) / 0.4) * 100, 100) );
}
}
function setFrame(i){
var maxFrame = numFrames[currAub] - 1;
while (i > maxFrame) i -= maxFrame;
while (i < 0) i += maxFrame;
var hiCanvas = hiCanvases[i];
if(hiCanvas){
draw(hiCanvas);
} else {
draw(loCanvases[i]);
console.log(i, currAub);
if(i !== currFrameWrapped) {
clearTimeout(loadTimer);
loadTimer = setTimeout(function(){
var hiUrl = hiUrls[i];
loadImage(hiUrl, function(img){
var canvas = imgToCanvas(img);
hiCanvases[i] = canvas;
})
}, 50)
}
}
//if(i !== currFrameWrapped) pop();
currFrameWrapped = i;
}
function draw(img){
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
function spin(d){
d /= window.innerWidth;
var offset = currOffset + d;
var frame = Math.round( offset * numFrames[currAub] / 4 );
setFrame(frame);
addSpinDistance( frame - currFrame );
currOffset = offset;
currFrame = frame;
}
function addSpinDistance(x){
x = Math.abs(x);
spinDistance += x/numFrames[currAub];
$counter.text('spins: ' + pad( Math.floor(spinDistance), 9 ));
}
var mousedown = false;
var lastX = 0;
var h1Off = false;
$body
.on('mousedown touchstart', function(e){
if(loading) return;
if(e.type === 'touchstart') {
lastX = e.originalEvent.pageX / 5;
} else {
lastX = e.pageX;
}
if(!h1Off){
$('h1').addClass('off');
h1Off = true;
}
velocity = 0;
mousedown = true;
$body.addClass('grab');
})
.on('mouseup touchend', function(e){
if(loading) return;
mousedown = false;
$body.removeClass('grab');
})
.on('mousemove touchmove', function(e){
if(loading) return;
if(mousedown){
var x;
if(e.type === 'touchmove') {
x = e.originalEvent.pageX / 5;
} else {
x = e.pageX;
}
velocity += x - lastX;
lastX = x;
}
})
$('#refresh').on('click', function(){
load( (currAub + 1) % numFrames.length );
});
$mute.on('click', function(){
if(muted){
$mute.attr('src', 'img/mute.svg');
muted = false;
} else {
$mute.attr('src', 'img/unmute.svg');
muted = true;
}
})
function tick(){
if(!loading){
velocity *= 0.98;
if(!mousedown && Math.abs(velocity) <= 5) velocity = 0;
spin(velocity);
playSound(velocity / 50);
}
requestAnimationFrame(tick);
}
load(0);
tick();
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment