import Tone from 'tone' import keys from './lib/keys' import color from './lib/color' import { browser, requestAudioContext, clamp, 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 offsets = [] let player = new Tone.MultiPlayer({ applause: 'applause.mp3', }, () => { 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) console.log(inertialIntensity) let offsetIntensity = 0.98 * inertialIntensity 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) // console.log(offset, offsets[offsetIndex] * GRAIN_TIME, ( 0.25 * Math.cos(time*13/7))) player.start('applause', time, offset, GRAIN_TIME * 4, 0, inertialIntensity) } let mouse = { x: 0, y: 0 } 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) function down (e) { drawing = true 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) inertialIntensity = Math.min(0.999, intensity) if (intensity == 0.999) intensity -= (Math.random() * 0.45) if (inertialIntensity == 0.999) inertialIntensity -= (Math.random() * 0.35) const gray = Math.floor( clamp(1-(10*v),0,1)*255 ) ctx.fillStyle = 'rgb(' + [gray,gray,gray] + ')' ctx.beginPath() ctx.arc( x*window.innerWidth, y*window.innerHeight, v*500, 0, Math.PI*2 ) ctx.fill() } mouse.x = x mouse.y = y } function up (e) { drawing = false intensity = 0 } setInterval( () => { inertialIntensity += 0.001 }, 5000) 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) } function animate(){ requestAnimationFrame(animate) ctx.save() ctx.fillStyle='rgba(255,255,255,' + (1-(intensity || 0.01)) + ')' ctx.globalAlpha = 0.001 ctx.fillRect(0,0,window.innerWidth,window.innerHeight) ctx.restore() } animate()