diff options
Diffstat (limited to 'client/index.js')
| -rw-r--r-- | client/index.js | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/client/index.js b/client/index.js new file mode 100644 index 0000000..12d466e --- /dev/null +++ b/client/index.js @@ -0,0 +1,115 @@ +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/20 +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 = 16 + +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 offsetIndex = Math.floor(inertialIntensity * 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) +} + +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.01) + if (inertialIntensity == 0.999) inertialIntensity -= (Math.random() * 0.01) + 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.1 +}, 2000) + +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,0.11)' + ctx.globalAlpha = 0.1 + ctx.fillRect(0,0,window.innerWidth,window.innerHeight) + ctx.restore() +} +animate() |
