import Tone from 'tone' import keys from './lib/keys' import color from './lib/color' import { browser, requestAudioContext, randrange, clamp, choice, firstTouch } from './lib/util' const compressor = new Tone.Compressor(-30, 3).toMaster() const GRAIN_TIME = 1/2 const SAMPLE_RATE = 44100 const GRAIN_SIZE = GRAIN_TIME * SAMPLE_RATE requestAudioContext( () => { const clock = new Tone.Clock(tick, 1/GRAIN_TIME) clock.start() console.log('ready') }) let images = [] let img; for (var i = 745; i <= 750; i++) { img = new Image img.src = 'img/' + i + '.png' images.push(img) } let offsets = [] let loading = true let player = new Tone.MultiPlayer({ applause: 'applause.mp3', // applause: '0bB7tTknkDw.mp3', }, () => { loading = false let data = player.buffers.get('applause').get().getChannelData(0) let intensities = [] for (let i = 0, len = Math.floor(data.length / GRAIN_SIZE); i < len; i++) { let z = 0 for (let j = i * GRAIN_SIZE, max = (i+1) * GRAIN_SIZE; j < max; j++) { z += Math.abs(data[j]) } intensities[i] = [z / GRAIN_SIZE, i] } offsets = intensities.sort( (a,b) => a[0] < b[0] ? -1 : a[0] == b[0] ? 0 : 1 ) .map( (a,i) => { return a[1] }) }) player.fadeIn = 0.25 player.fadeOut = 0.25 player.connect(compressor) let intensity = 0, inertialIntensity = 0, inertia = 5 function tick (time) { if (! offsets.length) return // let offsetIndex = clamp( Math.floor(mouse.y * offsets.length + Math.cos(time/20)), 0, offsets.length-1 ) inertialIntensity = Math.max(intensity, (intensity + inertialIntensity*(inertia-1))/inertia) let offsetIntensity = 0.94 * inertialIntensity + 0.02 let offsetIndex = Math.floor(offsetIntensity * offsets.length + Math.cos(time)) let offset = Math.max((offsets[offsetIndex] || 0) * GRAIN_TIME + ( 0.25 * Math.sin(time*17/7) ), 0) player.start('applause', time, offset, GRAIN_TIME * 4, 0, (inertialIntensity * 0.95) + 0.05) } let mouse = { x: window.innerWidth/2, y: window.innerHeight/2 } let drawing = false let canvas = document.createElement('canvas') canvas.width = window.innerWidth canvas.height = window.innerHeight let ctx = canvas.getContext('2d') document.body.appendChild(canvas) let count = 0 function down (e) { drawing = true intensity = Math.min(0.999, intensity + 0.08) mouse.x = e.pageX / window.innerWidth mouse.y = e.pageY / window.innerHeight } function move (e){ const x = e.pageX / window.innerWidth const y = e.pageY / window.innerHeight const dx = (mouse.x - x) const dy = (mouse.y - y) const v = Math.sqrt(dx*dx+dy*dy) if (drawing) { intensity = Math.min(0.999, intensity + v*0.1 + 0.02) inertialIntensity = Math.min(0.999, intensity) if (intensity == 0.999) intensity -= (Math.random() * 0.4) if (inertialIntensity == 0.999) inertialIntensity -= (Math.random() * 0.3) // ctx.fillStyle = color(intensity) // ctx.beginPath() // ctx.arc( x*window.innerWidth, y*window.innerHeight, v*500, 0, Math.PI*2 ) // ctx.fill() if ((count++ % 10) == 0) { ctx.save() ctx.translate(x*window.innerWidth, y*window.innerHeight) ctx.rotate(Math.random() - 0.5) ctx.drawImage(choice(images), 0, 0) ctx.restore() } } mouse.x = x mouse.y = y } function up (e) { drawing = false intensity = 0 } setInterval( () => { inertialIntensity += 0.001 }, 5000) setInterval( () => { if (! drawing) inertialIntensity += 0.01 * Math.random() }, 15000) if (browser.isMobile) { document.body.addEventListener('touchstart', firstTouch(down)) document.body.addEventListener('touchmove', firstTouch(move)) window.addEventListener('touchend', firstTouch(up)) } else { document.body.addEventListener('mousedown', down) document.body.addEventListener('mousemove', move) window.addEventListener('mouseup', up) } const fonts = ['Arial','Helvetica','Comic Sans MS','Chalkboard','Georgia'] function animate(t){ requestAnimationFrame(animate) ctx.save() // ctx.fillStyle=color(inertialIntensity/2) const n = Math.floor( (0.5 + randrange(0, 1 - inertialIntensity/2) ) * 255 ) // ctx.fillStyle = 'rgba(255,255,255,0.2)' // + [n,n,n] + ')' if (! drawing) { ctx.globalAlpha = 0.05 + Math.random()/10 if ((count % 3) == 0) { ctx.clearRect(0, 0, w, h) } } const w = canvas.width const h = canvas.height ctx.save() ctx.translate(w/2,h/2) ctx.rotate(mouse.x) ctx.translate(-w/2,-h/2) ctx.globalAlpha = 0.01 ctx.drawImage(canvas, -2, -2, w+10, h+10) ctx.restore() ctx.globalAlpha = drawing ? (0.05 + Math.random()*0.05) : 0.1 ctx.fillStyle='rgb(255,255,255)' ctx.fillRect(0, 0, w, h) ctx.restore() } animate() load() function load() { if (loading) setTimeout(load, 10) ctx.font = "100px " + choice(fonts) ctx.fillStyle=color(Math.random()) ctx.fillText("LOADING!",window.innerWidth/2-250,window.innerHeight/2) }