(() => { const updateRate = 1000 / 10; const sWidth = 224; const sHeight = 208; const colours = ['#0f9', '#ff9', '#f09', '#0ff', '#f0f']; const gfx = document.querySelector('.sprite').getContext('2d'); const play = document.querySelector('.play'); const bars = Array.from(document.querySelectorAll('.bar')); let audioBuffer; const knowsWhatAnOpusIs = document.createElement('audio').canPlayType('audio/ogg;codecs=opus') !== ''; const displayPlayButton = () => { play.onclick = () => { attemptPlay(); }; play.classList.remove('hidden'); }; const startAnimation = () => { play.classList.add('hidden'); requestAnimationFrame(update); }; const aud = (() => { const audObj = window.AudioContext || window.webkitAudioContext; try { return new audObj({ latencyHint: 'playback' }); } catch(ex) { return new audObj; } })(); const attemptPlay = () => { play.onclick = null; aud.resume().then(() => { if(aud.state !== 'running') { displayPlayButton(); return; } aud.decodeAudioData(audioBuffer) .then(buffer => { const source = aud.createBufferSource(); source.connect(aud.destination); source.buffer = buffer; source.loop = true; source.start(); startAnimation(); }) .catch(ex => { console.error(ex); alert('Failed to decode audio, oops!'); startAnimation(); }); }); }; let sFrames; const sprite = new Image; sprite.onload = () => { sFrames = sprite.height / sHeight; const xhr = new XMLHttpRequest; xhr.responseType = 'arraybuffer'; xhr.onload = () => { audioBuffer = xhr.response; if(aud.state === 'running') attemptPlay(); else displayPlayButton(); }; xhr.onerror = ex => { console.error(ex); alert('Failed to load audio, oops!'); startAnimation(); }; xhr.open('GET', `admin.${knowsWhatAnOpusIs ? 'opus' : 'caf'}`); xhr.send(); }; sprite.src = 'lurkmoar.png'; let lastUpdate, updates = 0; const update = t => { try { if(lastUpdate !== undefined && t - updateRate < lastUpdate) return; ++updates; lastUpdate = t; gfx.canvas.width = gfx.canvas.clientWidth; gfx.clearRect(0, 0, gfx.canvas.width, gfx.canvas.height); const saWidth = sWidth * (gfx.canvas.clientHeight / sHeight); gfx.drawImage( sprite, 0, sHeight * (updates % sFrames), sWidth, sHeight, (gfx.canvas.width / 2) - (saWidth / 2), 0, saWidth, gfx.canvas.height ); for(let i = 0; i < bars.length; ++i) bars[i].style.background = colours[(i + updates) % colours.length]; } finally { requestAnimationFrame(update); } }; })();