diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2018-03-14 00:51:21 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2018-03-14 00:51:21 +0100 |
| commit | 331064358df418c9846a94ed190548492c9e61f6 (patch) | |
| tree | e1ce4847561bf68dc01feb180ab7d1d43e172b1c /client | |
| parent | f60aeec9f3d1fefa8ea873cd2ecba5b75c13da86 (diff) | |
hidpi canvas stuff
Diffstat (limited to 'client')
| -rw-r--r-- | client/draw.js | 52 | ||||
| -rw-r--r-- | client/index.js | 42 | ||||
| -rw-r--r-- | client/lib/vendor/hidpi-canvas.js | 170 |
3 files changed, 228 insertions, 36 deletions
diff --git a/client/draw.js b/client/draw.js index ef66e22..3aff6a4 100644 --- a/client/draw.js +++ b/client/draw.js @@ -3,46 +3,58 @@ import { randint, randrange, clamp, mod, } from './lib/util' +import './lib/vendor/hidpi-canvas' + import mouse from './lib/mouse' import color from './lib/color' let w, h let rx, ry -const pixels_per_second = 1024 +const pixels_per_second = 512 // 1024 const canvas = document.createElement('canvas') -const ctx = canvas.getContext('2d') - -const scratch = document.createElement('canvas') -const scratchCtx = scratch.getContext('2d') - document.body.appendChild(canvas) document.body.addEventListener('resize', resize) resize() recenter() requestAnimationFrame(animate) +// must request context after resizing +const ctx = canvas.getContext('2d') + +const scratch = document.createElement('canvas') +const scratchCtx = scratch.getContext('2d-lodpi') + function resize(){ w = canvas.width = window.innerWidth h = canvas.height = window.innerHeight - clear() + canvas.style.width = window.innerWidth + 'px' + canvas.style.height = window.innerHeight + 'px' } function recenter(){ rx = randint(w), ry = randint(h) } +let frame = null +function onFrame(fn){ + frame = fn +} function animate(t){ requestAnimationFrame(animate) - ctx.save() - ctx.globalAlpha = 0.0001 - ctx.translate(w/2, h/2) - ctx.rotate(0.1) - ctx.translate(-rx, -ry) - ctx.drawImage(canvas, 0, 0) - ctx.restore() + if (frame) { + frame(t) + frame = null + } + // ctx.save() + // ctx.globalAlpha = 0.0001 + // ctx.translate(w/2, h/2) + // ctx.rotate(0.1) + // ctx.translate(-rx, -ry) + // ctx.drawImage(canvas, 0, 0) + // ctx.restore() } function clear(n, x, y, ww, hh){ - ctx.fillStyle = 'rgba(255,255,255,' + (n || 0.5) + ')' + ctx.fillStyle = 'rgba(255,255,255,' + (n || 0.9) + ')' ctx.fillRect(x || 0, y || 0, ww || w, hh || h) recenter() } @@ -161,10 +173,10 @@ function spectrum(spec, x0, y0, ww, hh){ var pcm_length = spec.fft_overlap * spec_len - x0 = x0 || 0 - y0 = y0 || Math.floor(h/4) - ww = ww || window.innerWidth - hh = hh || h/4 + x0 = x0 * devicePixelRatio || 0 + y0 = y0 * devicePixelRatio || Math.floor(h/4) + ww = ww * devicePixelRatio || w + hh = hh * devicePixelRatio || h/4 const width = Math.round(pcm_length / spec.sr * pixels_per_second) const height = Math.floor(hh) @@ -176,7 +188,7 @@ function spectrum(spec, x0, y0, ww, hh){ } export default { - canvas, ctx, + canvas, ctx, onFrame, triangle, clear, line, dot, waveform, spectrum }
\ No newline at end of file diff --git a/client/index.js b/client/index.js index 809220d..e08aab0 100644 --- a/client/index.js +++ b/client/index.js @@ -27,11 +27,13 @@ let samplers = {} let sampler requestAudioContext( () => { + // sampler = samplers.misc = new Sampler('samples/misc/glass.mp3', 2) // sampler = samplers.smash = new Sampler('samples/smash/g{}.mp3', 12) sampler = samplers.earth = new Sampler('samples/earth/earth{}.mp3', 20) // sampler = samplers.glass = new Sampler('samples/glass/0{}Particle.mp3', 20) - // sampler = samplers.bong = new Sampler('samples/bong/bong{}.mp3', 10) + // sampler = samplers.bubbles = new Sampler('samples/bubbles/bubbles{}.mp3', 10) // sampler = samplers.kalimba = new Sampler('samples/kalimba/380731__cabled-mess__sansula-08-c-raw.wav', 10) + samplers.choice = (m,n) => { const r = Math.random() if (r < m) return samplers.smash @@ -82,7 +84,7 @@ function manipulate(x, y, pcm, spec){ // let new_spec = spectrum.cloneSpectrum(spec) // new_spec = spectrum.rotatePhase(new_spec, x * Math.PI) - let new_spec = spectrum.rotateSpectrum(spec, x) + let new_spec = spectrum.rotateSpectrum(spec, (y + 0.5)%1) return new_spec } @@ -122,31 +124,39 @@ function trigger(x, y, t, source){ // const freq = notes[Math.floor(x * notes.length)] // const { speaker, player } = hall.play(source, y, freq, x, t) - const { pcm, spec } = source.getWaveAndSpectrum(y) + const { pcm, spec } = source.getWaveAndSpectrum(x) if (! pcm) return const new_spec = manipulate(x, y, pcm, spec) if (! new_spec) return - draw.clear() - // draw.waveform(pcm) - draw.spectrum(spec, 0, window.innerHeight/4 + 20) - const audioBuffer = spectrum.fromSpectrum(new_spec) - draw.waveform(audioBuffer.getChannelData(0)) - const player = new Tone.Player(audioBuffer) player.connect(output) player.start(Tone.now()) - // const new_spec = spectrum.toSpectrum(audioBuffer.getChannelData(0), sr) - draw.spectrum(new_spec, 0, window.innerHeight * 1/2 + 40) + draw.onFrame(() => { + // INIT DRAWING PHASE + draw.clear() - draw.triangle( - lerp(x, 0, 1) * window.innerWidth, - lerp(y, 0, 1) * window.innerHeight - 20, - 40 - ) + // DRAW INDIVIDUAL UI ELEMENTS + // draw.waveform(pcm) + // draw.spectrum(spec, 0, window.innerHeight/4 + 20) + + draw.waveform(audioBuffer.getChannelData(0)) + + // DRAW SPECTRUM + // const new_spec = spectrum.toSpectrum(audioBuffer.getChannelData(0), sr) + // draw.spectrum(new_spec, 0, window.innerHeight * 1/2 + 40) + draw.spectrum(new_spec, 0, window.innerHeight * 1/4 + 20, 0, window.innerHeight * 1/2) + + // DRAW FLAIR + draw.triangle( + lerp(x, 0, 1) * window.innerWidth, + lerp(y, 0, 1) * window.innerHeight - 20, + 40 + ) + }) } diff --git a/client/lib/vendor/hidpi-canvas.js b/client/lib/vendor/hidpi-canvas.js new file mode 100644 index 0000000..d5323b9 --- /dev/null +++ b/client/lib/vendor/hidpi-canvas.js @@ -0,0 +1,170 @@ +/** + * HiDPI Canvas Polyfill (1.0.10) + * + * Author: Jonathan D. Johnson (http://jondavidjohn.com) + * Homepage: https://github.com/jondavidjohn/hidpi-canvas-polyfill + * Issue Tracker: https://github.com/jondavidjohn/hidpi-canvas-polyfill/issues + * License: Apache-2.0 +*/ +(function(prototype) { + + var pixelRatio = (function() { + var canvas = window.document.createElement('canvas'), + context = canvas.getContext('2d'), + backingStore = context.backingStorePixelRatio || + context.webkitBackingStorePixelRatio || + context.mozBackingStorePixelRatio || + context.msBackingStorePixelRatio || + context.oBackingStorePixelRatio || + context.backingStorePixelRatio || 1; + + return (window.devicePixelRatio || 1) / backingStore; + })(), + + forEach = function(obj, func) { + for (var p in obj) { + if (obj.hasOwnProperty(p)) { + func(obj[p], p); + } + } + }, + + ratioArgs = { + 'fillRect': 'all', + 'clearRect': 'all', + 'strokeRect': 'all', + 'moveTo': 'all', + 'lineTo': 'all', + 'arc': [0,1,2], + 'arcTo': 'all', + 'bezierCurveTo': 'all', + 'isPointinPath': 'all', + 'isPointinStroke': 'all', + 'quadraticCurveTo': 'all', + 'rect': 'all', + 'translate': 'all', + 'createRadialGradient': 'all', + 'createLinearGradient': 'all' + }; + + if (pixelRatio === 1) return; + + forEach(ratioArgs, function(value, key) { + prototype[key] = (function(_super) { + return function() { + var i, len, + args = Array.prototype.slice.call(arguments); + + if (value === 'all') { + args = args.map(function(a) { + return a * pixelRatio; + }); + } + else if (Array.isArray(value)) { + for (i = 0, len = value.length; i < len; i++) { + args[value[i]] *= pixelRatio; + } + } + + return _super.apply(this, args); + }; + })(prototype[key]); + }); + + // Stroke lineWidth adjustment + prototype.stroke = (function(_super) { + return function() { + this.lineWidth *= pixelRatio; + _super.apply(this, arguments); + this.lineWidth /= pixelRatio; + }; + })(prototype.stroke); + + // Text + // + prototype.fillText = (function(_super) { + return function() { + var args = Array.prototype.slice.call(arguments); + + args[1] *= pixelRatio; // x + args[2] *= pixelRatio; // y + + this.font = this.font.replace( + /(\d+)(px|em|rem|pt)/g, + function(w, m, u) { + return (m * pixelRatio) + u; + } + ); + + _super.apply(this, args); + + this.font = this.font.replace( + /(\d+)(px|em|rem|pt)/g, + function(w, m, u) { + return (m / pixelRatio) + u; + } + ); + }; + })(prototype.fillText); + + prototype.strokeText = (function(_super) { + return function() { + var args = Array.prototype.slice.call(arguments); + + args[1] *= pixelRatio; // x + args[2] *= pixelRatio; // y + + this.font = this.font.replace( + /(\d+)(px|em|rem|pt)/g, + function(w, m, u) { + return (m * pixelRatio) + u; + } + ); + + _super.apply(this, args); + + this.font = this.font.replace( + /(\d+)(px|em|rem|pt)/g, + function(w, m, u) { + return (m / pixelRatio) + u; + } + ); + }; + })(prototype.strokeText); +})(window.CanvasRenderingContext2D.prototype); +;(function(prototype) { + prototype.getContext = (function(_super) { + return function(type) { + var backingStore, ratio, context; + + + if (type == '2d-lodpi') { + context = _super.call(this, '2d'); + } + else if (type === '2d') { + context = _super.call(this, '2d'); + + backingStore = context.backingStorePixelRatio || + context.webkitBackingStorePixelRatio || + context.mozBackingStorePixelRatio || + context.msBackingStorePixelRatio || + context.oBackingStorePixelRatio || + context.backingStorePixelRatio || 1; + + ratio = (window.devicePixelRatio || 1) / backingStore; + + if (ratio > 1) { + this.style.height = this.height + 'px'; + this.style.width = this.width + 'px'; + this.width *= ratio; + this.height *= ratio; + } + } + else { + context = _super.call(this, type); + } + + return context; + }; + })(prototype.getContext); +})(window.HTMLCanvasElement.prototype); |
