diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2018-03-03 05:38:35 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2018-03-03 05:38:35 +0100 |
| commit | 636b62aa6d0d77e19a4b7bb3c039924eeb217a71 (patch) | |
| tree | 042fa3404738e347f8d60f419fa600aa6030c61b /client/lib/util.js | |
hall demo
Diffstat (limited to 'client/lib/util.js')
| -rw-r--r-- | client/lib/util.js | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/client/lib/util.js b/client/lib/util.js new file mode 100644 index 0000000..fd48768 --- /dev/null +++ b/client/lib/util.js @@ -0,0 +1,111 @@ +import Tone from 'tone' +import StartAudioContext from './startAudioContext' + +const isIphone = (navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) +const isIpad = (navigator.userAgent.match(/iPad/i)) +const isAndroid = (navigator.userAgent.match(/Android/i)) +const isMobile = isIphone || isIpad || isAndroid +const isDesktop = ! isMobile + +document.body.classList.add(isMobile ? 'mobile' : 'desktop') + +const browser = { isIphone, isIpad, isAndroid, isMobile, isDesktop } + +function clamp(n,a,b){ return n<a?a:n<b?n:b } +function choice (a){ return a[ Math.floor(Math.random() * a.length) ] } +function mod(n,m){ return n-(m * Math.floor(n/m)) } +function randint(n){ return (Math.random()*n)|0 } +function randrange(a,b){ return a + Math.random() * (b-a) } +function randsign(){ return Math.random() >= 0.5 ? -1 : 1 } +function lerp(n,a,b){ return (b-a)*n+a } +function angle(x0,y0,x1,y1){ return Math.atan2(y1-y0,x1-x0) } +function dist(x0,y0,x1,y1){ return Math.sqrt(Math.pow(x1-x0,2)+Math.pow(y1-y0,2)) } +function xor(a,b){ a=!!a; b=!!b; return (a||b) && !(a&&b) } +function shuffle(a){ + for (var i = a.length; i > 0; i--){ + var r = randint(i) + var swap = a[i-1] + a[i-1] = a[r] + a[r] = swap + } + return a +} +// returns a gaussian random function with the given mean and stdev. +function gaussian(mean, stdev) { + let y2; + let use_last = false; + return () => { + let y1; + if (use_last) { + y1 = y2; + use_last = false; + } + else { + let x1, x2, w; + do { + x1 = 2.0 * Math.random() - 1.0; + x2 = 2.0 * Math.random() - 1.0; + w = x1 * x1 + x2 * x2; + } while( w >= 1.0); + w = Math.sqrt((-2.0 * Math.log(w))/w); + y1 = x1 * w; + y2 = x2 * w; + use_last = true; + } + + let retval = mean + stdev * y1; + if (retval > 0) + return retval; + return -retval; + } +} + +function requestAudioContext (fn) { + if (isMobile) { + const container = document.createElement('div') + const button = document.createElement('div') + button.innerHTML = 'Tap to start - please unmute your phone' + Object.assign(container.style, { + display: 'block', + position: 'absolute', + width: '100%', + height: '100%', + zIndex: '10000', + top: '0px', + left: '0px', + backgroundColor: 'rgba(0, 0, 0, 0.8)', + }) + Object.assign(button.style, { + display: 'block', + position: 'absolute', + left: '50%', + top: '50%', + padding: '20px', + backgroundColor: '#7F33ED', + color: 'white', + fontFamily: 'monospace', + borderRadius: '3px', + transform: 'translate3D(-50%,-50%,0)', + textAlign: 'center', + lineHeight: '1.5', + width: '150px', + }) + container.appendChild(button) + document.body.appendChild(container) + StartAudioContext.setContext(Tone.context) + StartAudioContext.on(button) + StartAudioContext.onStarted(_ => { + container.remove() + fn() + }) + } else { + fn() + } +} + +export { + clamp, choice, mod, lerp, angle, dist, xor, + randint, randrange, randsign, shuffle, gaussian, + browser, requestAudioContext, +} + |
