summaryrefslogtreecommitdiff
path: root/app/client
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2018-06-06 00:59:39 +0200
committerJules Laplace <julescarbon@gmail.com>2018-06-06 00:59:39 +0200
commitd3fcd1212f7214b12b04a83d03dfb129c5fbb0a4 (patch)
treeb9cede8c8b245d5dc5d3ed23d8879e603af82809 /app/client
parent8c8e2e08d2ae89ba18ca05bab446e4642798dce2 (diff)
pix2wav paths
Diffstat (limited to 'app/client')
-rw-r--r--app/client/api/index.js2
-rw-r--r--app/client/audio/index.js2
-rw-r--r--app/client/audio/lib/_draw.js139
-rw-r--r--app/client/audio/lib/draw.js (renamed from app/client/audio/draw.js)138
-rw-r--r--app/client/audio/lib/index.js47
-rw-r--r--app/client/audio/lib/output.js (renamed from app/client/audio/output.js)0
-rw-r--r--app/client/audio/lib/spectrum.js (renamed from app/client/audio/spectrum.js)0
-rw-r--r--app/client/audio/lib/startAudioContext.js (renamed from app/client/audio/startAudioContext.js)0
-rw-r--r--app/client/audio/pix2wav.js35
-rw-r--r--app/client/audio/ui.js12
-rw-r--r--app/client/audio/wav2pix.js149
-rw-r--r--app/client/common/fileList.component.js2
-rw-r--r--app/client/dashboard/dashboardHeader.component.js2
-rw-r--r--app/client/dashboard/tasklist.component.js2
-rw-r--r--app/client/dataset/dataset.component.js2
-rw-r--r--app/client/index.jsx2
-rw-r--r--app/client/modules/pix2pix/index.js3
-rw-r--r--app/client/modules/pix2pix/pix2pix.actions.js4
-rw-r--r--app/client/modules/pix2pix/views/pix2pix.new.js3
-rw-r--r--app/client/modules/pix2pix/views/pix2pix.show.js2
-rw-r--r--app/client/modules/pix2wav/index.js13
-rw-r--r--app/client/modules/pix2wav/pix2wav.actions.js57
-rw-r--r--app/client/modules/pix2wav/pix2wav.tasks.js7
-rw-r--r--app/client/modules/pix2wav/views/pix2wav.new.js13
-rw-r--r--app/client/modules/pix2wav/views/pix2wav.show.js116
-rw-r--r--app/client/modules/samplernn/index.js2
-rw-r--r--app/client/modules/samplernn/samplernn.actions.js4
-rw-r--r--app/client/modules/samplernn/views/samplernn.graph.js6
-rw-r--r--app/client/modules/samplernn/views/samplernn.import.js2
-rw-r--r--app/client/modules/samplernn/views/samplernn.new.js2
-rw-r--r--app/client/modules/samplernn/views/samplernn.results.js2
-rw-r--r--app/client/modules/samplernn/views/samplernn.show.js2
-rw-r--r--app/client/queue/queue.reducer.js2
-rw-r--r--app/client/util/hidpi-canvas.js170
-rw-r--r--app/client/util/index.js30
-rw-r--r--app/client/util/math.js13
36 files changed, 692 insertions, 295 deletions
diff --git a/app/client/api/index.js b/app/client/api/index.js
index c19b78d..7551fb2 100644
--- a/app/client/api/index.js
+++ b/app/client/api/index.js
@@ -1,5 +1,5 @@
import { crud_actions } from './crud.actions'
-import * as util from '../util'
+import util from '../util'
import * as parser from './parser'
/*
diff --git a/app/client/audio/index.js b/app/client/audio/index.js
deleted file mode 100644
index 8b3da74..0000000
--- a/app/client/audio/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import Tone from 'tone'
-import StartAudioContext from './startAudioContext'
diff --git a/app/client/audio/lib/_draw.js b/app/client/audio/lib/_draw.js
new file mode 100644
index 0000000..974fa62
--- /dev/null
+++ b/app/client/audio/lib/_draw.js
@@ -0,0 +1,139 @@
+import {
+ browser, requestAudioContext,
+ 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 = 512 // 1024
+
+const canvas = document.createElement('canvas')
+// 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(ww, hh){
+ w = canvas.width = ww || window.innerWidth
+ h = canvas.height = hh || window.innerHeight
+ canvas.style.width = w + 'px'
+ canvas.style.height = h + 'px'
+}
+function recenter(){
+ rx = randint(w), ry = randint(h)
+}
+let frame = null
+function onFrame(fn){
+ frame = fn
+}
+function animate(t){
+ requestAnimationFrame(animate)
+ 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.9) + ')'
+ ctx.fillRect(x || 0, y || 0, ww || w, hh || h)
+ recenter()
+}
+function triangle(px,py,r){
+ setTimeout( () => tri(px,py,r), Math.random()*10)
+ // setTimeout( () => tri(px,py,r), Math.random()*200)
+ // setTimeout( () => tri(px,py,r), Math.random()*300)
+}
+function tri(px, py, r) {
+ ctx.save()
+ ctx.globalCompositeOperation = 'multiply'
+ ctx.fillStyle = color.color((px+py)/(w+h), 0, 1, 0.2)
+ function p(){
+ let theta = randrange(0, Math.PI*2)
+ let x = px + Math.cos(theta) * r
+ let y = py + Math.sin(theta) * r
+ return { x, y }
+ }
+ ctx.beginPath()
+ const p0 = p(), p1 = p(), p2 = p()
+ ctx.moveTo(p0.x, p0.y)
+ ctx.lineTo(p1.x, p1.y)
+ ctx.lineTo(p2.x, p2.y)
+ ctx.lineTo(p0.x, p0.y)
+ ctx.fill()
+ ctx.restore()
+}
+function line(y){
+ ctx.beginPath()
+ ctx.moveTo(0, y)
+ ctx.lineTo(w, y)
+ ctx.strokeStyle = "#888"
+ ctx.strokeWidth = 1
+ ctx.stroke()
+}
+function dot(x, y, r){
+ ctx.fillStyle = "#f00"
+ ctx.beginPath()
+ ctx.moveTo(x, y)
+ ctx.arc(x, y, r, 0, 2*Math.PI)
+ ctx.fill()
+}
+function waveform(pcm, sr, pos, zoom){
+ sr = sr || 44100
+ pos = pos || 0
+
+ var width = w
+ var height = Math.floor(h/4)
+ var half_height = Math.floor(height/2)
+ var x0 = 0
+ var y0 = 20
+ var ymid = y0 + half_height
+ var max_width_in_seconds = width / pixels_per_second
+ var max_width_in_samples = max_width_in_seconds * sr
+ var pcm_length = pcm.length
+ var len = Math.min(pcm_length, max_width_in_samples)
+ var pcm_step = sr / pixels_per_second
+ var i
+ ctx.save()
+
+ clear(1, x0, y0, width, height)
+
+ line(ymid)
+ ctx.beginPath()
+ for (i = 0; i < width; i += 0.5) {
+ var si = Math.floor(pcm_step * i + pos)
+ if (si > pcm_length) break
+ var val = pcm[si] // -1, 1
+ // ctx.moveTo(x0 + i, ymid)
+ ctx.lineTo(x0 + i, ymid + val * half_height)
+ }
+ ctx.strokeStyle = "rgba(250,20,0,0.9)"
+ ctx.strokeWidth = 1
+ ctx.stroke()
+ ctx.restore()
+}
+
+export default {
+ canvas, ctx, onFrame, resize,
+ triangle, clear, line, dot,
+ waveform, spectrum, raw_spectrum,
+} \ No newline at end of file
diff --git a/app/client/audio/draw.js b/app/client/audio/lib/draw.js
index 8caf8d8..f5ba3ac 100644
--- a/app/client/audio/draw.js
+++ b/app/client/audio/lib/draw.js
@@ -1,137 +1,6 @@
-import {
- browser, requestAudioContext,
- 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 = 512 // 1024
-
-const canvas = document.createElement('canvas')
-// 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(ww, hh){
- w = canvas.width = ww || window.innerWidth
- h = canvas.height = hh || window.innerHeight
- canvas.style.width = w + 'px'
- canvas.style.height = h + 'px'
-}
-function recenter(){
- rx = randint(w), ry = randint(h)
-}
-let frame = null
-function onFrame(fn){
- frame = fn
-}
-function animate(t){
- requestAnimationFrame(animate)
- 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.9) + ')'
- ctx.fillRect(x || 0, y || 0, ww || w, hh || h)
- recenter()
-}
-function triangle(px,py,r){
- setTimeout( () => tri(px,py,r), Math.random()*10)
- // setTimeout( () => tri(px,py,r), Math.random()*200)
- // setTimeout( () => tri(px,py,r), Math.random()*300)
-}
-function tri(px, py, r) {
- ctx.save()
- ctx.globalCompositeOperation = 'multiply'
- ctx.fillStyle = color.color((px+py)/(w+h), 0, 1, 0.2)
- function p(){
- let theta = randrange(0, Math.PI*2)
- let x = px + Math.cos(theta) * r
- let y = py + Math.sin(theta) * r
- return { x, y }
- }
- ctx.beginPath()
- const p0 = p(), p1 = p(), p2 = p()
- ctx.moveTo(p0.x, p0.y)
- ctx.lineTo(p1.x, p1.y)
- ctx.lineTo(p2.x, p2.y)
- ctx.lineTo(p0.x, p0.y)
- ctx.fill()
- ctx.restore()
-}
-function line(y){
- ctx.beginPath()
- ctx.moveTo(0, y)
- ctx.lineTo(w, y)
- ctx.strokeStyle = "#888"
- ctx.strokeWidth = 1
- ctx.stroke()
-}
-function dot(x, y, r){
- ctx.fillStyle = "#f00"
- ctx.beginPath()
- ctx.moveTo(x, y)
- ctx.arc(x, y, r, 0, 2*Math.PI)
- ctx.fill()
-}
-function waveform(pcm, sr, pos, zoom){
- sr = sr || 44100
- pos = pos || 0
-
- var width = w
- var height = Math.floor(h/4)
- var half_height = Math.floor(height/2)
- var x0 = 0
- var y0 = 20
- var ymid = y0 + half_height
- var max_width_in_seconds = width / pixels_per_second
- var max_width_in_samples = max_width_in_seconds * sr
- var pcm_length = pcm.length
- var len = Math.min(pcm_length, max_width_in_samples)
- var pcm_step = sr / pixels_per_second
- var i
- ctx.save()
-
- clear(1, x0, y0, width, height)
-
- line(ymid)
- ctx.beginPath()
- for (i = 0; i < width; i += 0.5) {
- var si = Math.floor(pcm_step * i + pos)
- if (si > pcm_length) break
- var val = pcm[si] // -1, 1
- // ctx.moveTo(x0 + i, ymid)
- ctx.lineTo(x0 + i, ymid + val * half_height)
- }
- ctx.strokeStyle = "rgba(250,20,0,0.9)"
- ctx.strokeWidth = 1
- ctx.stroke()
- ctx.restore()
-}
-
function spectrum(spec, x0, y0, ww, hh){
const data = spec.data
const fft_size = spec.fft_size
@@ -186,6 +55,7 @@ function spectrum(spec, x0, y0, ww, hh){
ctx.drawImage(scratch, x0, y0, width, height)
ctx.restore()
}
+
function raw_spectrum(spec, x0, y0, ww, hh, def_min_r, def_min_i){
const data = spec.data
const fft_size = spec.fft_size
@@ -262,9 +132,3 @@ function raw_spectrum(spec, x0, y0, ww, hh, def_min_r, def_min_i){
return { canvas: _scratch, imageData }
}
-
-export default {
- canvas, ctx, onFrame, resize,
- triangle, clear, line, dot,
- waveform, spectrum, raw_spectrum,
-} \ No newline at end of file
diff --git a/app/client/audio/lib/index.js b/app/client/audio/lib/index.js
new file mode 100644
index 0000000..ba96112
--- /dev/null
+++ b/app/client/audio/lib/index.js
@@ -0,0 +1,47 @@
+import Tone from 'tone'
+import StartAudioContext from './startAudioContext'
+
+import { is_mobile } from '../util'
+
+export function requestAudioContext (fn) {
+ if (is_mobile) {
+ 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()
+ }
+} \ No newline at end of file
diff --git a/app/client/audio/output.js b/app/client/audio/lib/output.js
index 53901b3..53901b3 100644
--- a/app/client/audio/output.js
+++ b/app/client/audio/lib/output.js
diff --git a/app/client/audio/spectrum.js b/app/client/audio/lib/spectrum.js
index f4a5444..f4a5444 100644
--- a/app/client/audio/spectrum.js
+++ b/app/client/audio/lib/spectrum.js
diff --git a/app/client/audio/startAudioContext.js b/app/client/audio/lib/startAudioContext.js
index 0e257be..0e257be 100644
--- a/app/client/audio/startAudioContext.js
+++ b/app/client/audio/lib/startAudioContext.js
diff --git a/app/client/audio/pix2wav.js b/app/client/audio/pix2wav.js
new file mode 100644
index 0000000..ccd36be
--- /dev/null
+++ b/app/client/audio/pix2wav.js
@@ -0,0 +1,35 @@
+function render(pcm, count, zip){
+ const fft = spectrum.toSpectrum(pcm, sr)
+ // console.log('render', fft)
+ // const pcm_rev = pcm.slice().reverse()
+ // const spec_rev = spectrum.toSpectrum(pcm_rev, spec.sr)
+ draw.clear()
+ const { canvas, imageData } = draw.raw_spectrum(fft, 0, 256, 0, 256, _r, _i)
+ const dataURL = canvas.toDataURL("image/png")
+ if (zip) {
+ const fn = sprintf('frame_%05d.png', count)
+ zip.file(fn, dataURL.split(',')[1], {base64: true})
+ }
+ return { fft, canvas, imageData }
+}
+function play(i) {
+ // console.log('play', i)
+ last_i = i
+ let player = players[clamp(i, 0, players.length)]
+ // const { canvas, imageData } = draw.raw_spectrum(fft, 0, 256, 0, 256, 1, 1)
+ // console.log(_r, _i)
+ // const { canvas, imageData } = draw.raw_spectrum(player.fft, 0, 256, 0, 256, _r, _i)
+ const new_fft = spectrum.fromImageData(player.imageData, 44100, _r, _i)
+ // gallery.innerHTML = ''
+
+ // console.log(player.fft.data, new_fft.data)
+ const buf = spectrum.fromSpectrum(new_fft)
+ const _p = new Tone.Player(buf)
+ _p.connect(output)
+ _p.start(Tone.now())
+ redraw(new_fft)
+}
+function redraw(new_fft){
+ const { canvas, imageData } = draw.raw_spectrum(new_fft, 0, 256, 0, 256, _r, _i)
+}
+
diff --git a/app/client/audio/ui.js b/app/client/audio/ui.js
new file mode 100644
index 0000000..76ffb09
--- /dev/null
+++ b/app/client/audio/ui.js
@@ -0,0 +1,12 @@
+/*
+
+mouse.register({
+ move: (x, y) => {
+ }
+})
+keys.listen((z) => {
+ // console.log(z)
+ play(mod(z, players.length))
+})
+
+*/
diff --git a/app/client/audio/wav2pix.js b/app/client/audio/wav2pix.js
index 3e86c40..089816d 100644
--- a/app/client/audio/wav2pix.js
+++ b/app/client/audio/wav2pix.js
@@ -1,153 +1,78 @@
import Tone from 'tone'
import JSZip from 'jszip'
-import { sprintf } from 'sprintf-js'
import FileSaver from 'file-saver'
-import draw from './draw'
-import keys from './lib/keys'
-import mouse from './lib/mouse'
+import draw from './lib/draw'
import output from './lib/output'
import spectrum from './lib/spectrum'
import {
- requestAudioContext,
lerp, clamp, mod,
-} from './lib/util'
+} from '../util'
+
+import { requestAudioContext } from './lib'
-let selfDrag = false
let buffer
-let players = []
-let gallery
let sr = 44100
let last_i = 0
let _r = 8, _i = 8
-function init(){
- requestAudioContext(ready)
- document.body.addEventListener('dragover', dragover)
- document.body.addEventListener('dragstart', dragstart)
- document.body.addEventListener('drop', drop)
- document.querySelector("#upload").addEventListener('change', handleFileSelect)
- // draw.onFrame(() => {})
- draw.resize(256, 256)
- gallery = document.querySelector('#gallery')
- mouse.register({
- move: (x, y) => {
- }
- })
- keys.listen((z) => {
- // console.log(z)
- play(mod(z, players.length))
- })
-}
-function ready(){
-}
-function dragover (e) {
- e.preventDefault()
-}
-function dragstart (e) {
- selfDrag = true
-}
-function drop (e) {
- e.stopPropagation()
- e.preventDefault()
+let files, file_index = 0;
- if (e.dataTransfer && ! selfDrag) {
- if (e.dataTransfer.files.length) {
- handleFileSelect(e)
- }
- }
- else {
- handleFileSelect(e)
- }
- selfDrag = false
+const FRAME_LENGTH = 126 * 255
+const FRAME_OFFSET = FRAME_LENGTH / 4
+
+function init() {
+ requestAudioContext(ready)
+ draw.resize(256, 256)
}
-let files, file_index = 0;
-function handleFileSelect(e){
+function handleFileSelect(e) {
files = e.dataTransfer ? e.dataTransfer.files : e.target.files
loadNext()
}
-function loadNext(){
+function loadNext() {
var file = files[file_index++]
if (! file) return
load(file)
}
-function load(file){
- players = []
- buffer = new Tone.Buffer(URL.createObjectURL(file), loadBuffer, (err) => console.error('err', err))
+function load(file) {
+ buffer = new Tone.Buffer(
+ URL.createObjectURL(file),
+ loadBuffer,
+ (err) => console.error('err', err)
+ )
}
-function loadBuffer(){
+function loadBuffer() {
+ // dispatch
console.log('loaded buffer', buffer)
const pcm = buffer._buffer.getChannelData(0)
- sr = buffer._buffer.sampleRate
+ const sr = buffer._buffer.sampleRate
if (! pcm) return
- const FRAME_LENGTH = 126 * 255
- const FRAME_OFFSET = FRAME_LENGTH / 4
+ const zip = new JSZip()
+ const zip_folder = zip.folder("wav2pix_" + name);
- var zip = new JSZip()
-
- var zip_folder = zip.folder("images");
-
- for (var offset = 0, count = 0, _len = pcm.length - FRAME_LENGTH; offset < _len; offset += FRAME_OFFSET, count += 1) {
- if ((count % 100) === 0) console.log(count)
- // console.log('generating', count, offset)
- // let player = render(pcm.slice(offset, offset+FRAME_LENGTH), count, zip_folder)
+ const offset = 0
+ for (offset = 0, count = 0, _len = pcm.length - FRAME_LENGTH;
+ offset < _len;
+ offset += FRAME_OFFSET, count += 1
+ ) {
+ if ((count % 100) === 0) {
+ // dispatch event instead..
+ console.log(count)
+ }
render(pcm.slice(offset, offset+FRAME_LENGTH), count, zip_folder)
- // register(player, count)
- // if (count > 20) break
}
+ // dispatch event
console.log('done exporting')
- zip.generateAsync({type:"blob"}).then(function(content) {
+ zip.generateAsync({ type: "blob" }).then(content => {
+ // dispatch
console.log('saving zip')
- FileSaver.saveAs(content, "img2pix.zip")
+ // FileSaver.saveAs(content, "wav2pix_" + name + ".zip")
setTimeout(loadNext, 1000)
})
// play(0)
}
-function render(pcm, count, zip){
- const fft = spectrum.toSpectrum(pcm, sr)
- // console.log('render', fft)
- // const pcm_rev = pcm.slice().reverse()
- // const spec_rev = spectrum.toSpectrum(pcm_rev, spec.sr)
- draw.clear()
- const { canvas, imageData } = draw.raw_spectrum(fft, 0, 256, 0, 256, _r, _i)
- const dataURL = canvas.toDataURL("image/png")
- if (zip) {
- const fn = sprintf('frame_%05d.png', count)
- zip.file(fn, dataURL.split(',')[1], {base64: true})
- }
- return { fft, canvas, imageData }
-}
-function play(i) {
- // console.log('play', i)
- last_i = i
- let player = players[clamp(i, 0, players.length)]
- // const { canvas, imageData } = draw.raw_spectrum(fft, 0, 256, 0, 256, 1, 1)
- // console.log(_r, _i)
- // const { canvas, imageData } = draw.raw_spectrum(player.fft, 0, 256, 0, 256, _r, _i)
- const new_fft = spectrum.fromImageData(player.imageData, 44100, _r, _i)
- // gallery.innerHTML = ''
- // console.log(player.fft.data, new_fft.data)
- const buf = spectrum.fromSpectrum(new_fft)
- const _p = new Tone.Player(buf)
- _p.connect(output)
- _p.start(Tone.now())
- redraw(new_fft)
-}
-function redraw(new_fft){
- const { canvas, imageData } = draw.raw_spectrum(new_fft, 0, 256, 0, 256, _r, _i)
-}
-function register(player, i){
- // console.log('register', player)
- players.push(player)
- player.canvas.addEventListener('click', () => {
- play(i)
- })
- if (i < 20) {
- gallery.appendChild(player.canvas)
- }
-}
init()
diff --git a/app/client/common/fileList.component.js b/app/client/common/fileList.component.js
index b70ce55..70ee5b6 100644
--- a/app/client/common/fileList.component.js
+++ b/app/client/common/fileList.component.js
@@ -3,7 +3,7 @@ import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom';
import moment from 'moment'
-import * as util from '../util'
+import util from '../util'
const defaultFields = new Set(['name', 'date', 'size'])
diff --git a/app/client/dashboard/dashboardHeader.component.js b/app/client/dashboard/dashboardHeader.component.js
index 62586b8..d27a324 100644
--- a/app/client/dashboard/dashboardHeader.component.js
+++ b/app/client/dashboard/dashboardHeader.component.js
@@ -2,7 +2,7 @@ import { h, Component } from 'preact'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
-import * as util from '../util'
+import util from '../util'
class DashboardHeader extends Component {
constructor(props){
diff --git a/app/client/dashboard/tasklist.component.js b/app/client/dashboard/tasklist.component.js
index b43481f..56bb50b 100644
--- a/app/client/dashboard/tasklist.component.js
+++ b/app/client/dashboard/tasklist.component.js
@@ -1,7 +1,7 @@
import { h, Component } from 'preact'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
-import * as util from '../util'
+import util from '../util'
import actions from '../actions'
diff --git a/app/client/dataset/dataset.component.js b/app/client/dataset/dataset.component.js
index 14ad852..af734ad 100644
--- a/app/client/dataset/dataset.component.js
+++ b/app/client/dataset/dataset.component.js
@@ -1,7 +1,7 @@
import { h, Component } from 'preact'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
-import * as util from '../util'
+import util from '../util'
import actions from '../actions'
diff --git a/app/client/index.jsx b/app/client/index.jsx
index 51e92df..8a13687 100644
--- a/app/client/index.jsx
+++ b/app/client/index.jsx
@@ -5,7 +5,7 @@ import { BrowserRouter, Route } from 'react-router-dom'
import { store, history } from './store'
import * as socket from './socket'
-import * as util from './util'
+import util from './util'
import Header from './common/header.component'
import AudioPlayer from './common/audioPlayer/audioPlayer.component'
diff --git a/app/client/modules/pix2pix/index.js b/app/client/modules/pix2pix/index.js
index ffe5f6b..9e3d466 100644
--- a/app/client/modules/pix2pix/index.js
+++ b/app/client/modules/pix2pix/index.js
@@ -1,11 +1,14 @@
import { h, Component } from 'preact'
import { Route, Link } from 'react-router-dom'
+import util from '../../util'
+
import Pix2PixNew from './views/pix2pix.new'
import Pix2PixShow from './views/pix2pix.show'
import Pix2PixLive from './views/pix2pix.live'
function router () {
+ document.body.style.backgroundImage = 'linear-gradient(' + (util.randint(40)+40) + 'deg, #fde, #ffe)'
return (
<section>
<Route exact path='/pix2pix/new/' component={Pix2PixNew} />
diff --git a/app/client/modules/pix2pix/pix2pix.actions.js b/app/client/modules/pix2pix/pix2pix.actions.js
index 82311ad..8633c0a 100644
--- a/app/client/modules/pix2pix/pix2pix.actions.js
+++ b/app/client/modules/pix2pix/pix2pix.actions.js
@@ -7,13 +7,13 @@ import * as datasetLoader from '../../dataset/dataset.loader'
import actions from '../../actions'
-import { allProgress } from '../../util'
+import util from '../../util'
import pix2pixModule from './pix2pix.module'
export const load_directories = (id) => (dispatch) => {
const module = pix2pixModule.name
- allProgress([
+ util.allProgress([
datasetLoader.load(module),
// actions.socket.list_directory({ module, dir: 'datasets' }),
// actions.socket.list_directory({ module, dir: 'results' }),
diff --git a/app/client/modules/pix2pix/views/pix2pix.new.js b/app/client/modules/pix2pix/views/pix2pix.new.js
index 173777c..203a606 100644
--- a/app/client/modules/pix2pix/views/pix2pix.new.js
+++ b/app/client/modules/pix2pix/views/pix2pix.new.js
@@ -1,7 +1,4 @@
import { h, Component } from 'preact'
-import { bindActionCreators } from 'redux'
-import { connect } from 'react-redux'
-import * as util from '../../../util'
import NewDatasetForm from '../../../dataset/dataset.new'
diff --git a/app/client/modules/pix2pix/views/pix2pix.show.js b/app/client/modules/pix2pix/views/pix2pix.show.js
index ef4b906..2139c6c 100644
--- a/app/client/modules/pix2pix/views/pix2pix.show.js
+++ b/app/client/modules/pix2pix/views/pix2pix.show.js
@@ -1,7 +1,7 @@
import { h, Component } from 'preact'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
-import * as util from '../../../util'
+import util from '../../../util'
import * as pix2pixActions from '../pix2pix.actions'
import * as pix2pixTasks from '../pix2pix.tasks'
diff --git a/app/client/modules/pix2wav/index.js b/app/client/modules/pix2wav/index.js
index 602d54e..9071d04 100644
--- a/app/client/modules/pix2wav/index.js
+++ b/app/client/modules/pix2wav/index.js
@@ -1,10 +1,18 @@
import { h, Component } from 'preact'
import { Route, Link } from 'react-router-dom'
+import util from '../../util'
+
+import Pix2WavNew from './views/pix2wav.new'
+import Pix2WavShow from './views/pix2wav.show'
+// import Pix2WavLive from './views/pix2wav.live'
function router () {
- // <Route exact path='/pix2pix/live/' component={Pix2PixLive} />
+ document.body.style.backgroundImage = 'linear-gradient(' + (util.randint(40)+40) + 'deg, #fde, #ffe)'
return (
<section>
+ <Route exact path='/pix2wav/new/' component={Pix2WavNew} />
+ <Route exact path='/pix2wav/datasets/' component={Pix2WavShow} />
+ <Route exact path='/pix2wav/datasets/:id/' component={Pix2WavShow} />
</section>
)
}
@@ -13,12 +21,11 @@ function links(){
return (
<span>
<span>datasets</span>
- <span><Link to="/pix2wav/live/">live</Link></span>
</span>
)
}
export default {
- name: 'pix2pix',
+ name: 'pix2wav',
router, links,
}
diff --git a/app/client/modules/pix2wav/pix2wav.actions.js b/app/client/modules/pix2wav/pix2wav.actions.js
new file mode 100644
index 0000000..08f1a97
--- /dev/null
+++ b/app/client/modules/pix2wav/pix2wav.actions.js
@@ -0,0 +1,57 @@
+import uuidv1 from 'uuid/v1'
+
+import socket from '../../socket'
+import types from '../../types'
+
+import * as datasetLoader from '../../dataset/dataset.loader'
+
+import actions from '../../actions'
+
+import util from '../../util'
+
+import pix2wavModule from './pix2wav.module'
+
+export const load_directories = (id) => (dispatch) => {
+ const module = pix2wavModule.name
+ util.allProgress([
+ datasetLoader.load(module),
+ // actions.socket.list_directory({ module, dir: 'datasets' }),
+ // actions.socket.list_directory({ module, dir: 'results' }),
+ // actions.socket.list_directory({ module, dir: 'output' }),
+ // actions.socket.disk_usage({ module, dir: 'datasets' }),
+ ], (percent, i, n) => {
+ dispatch({ type: types.app.load_progress, progress: { i, n }})
+ }).then(res => {
+ const [datasetApiReport] = res //, datasets, results, output, datasetUsage, lossReport] = res
+ const {
+ folderLookup,
+ fileLookup,
+ datasetLookup,
+ folders,
+ files,
+ unsortedFolder,
+ } = datasetApiReport
+ dispatch({
+ type: types.dataset.load,
+ data: {
+ module,
+ folderLookup,
+ fileLookup,
+ datasetLookup,
+ folders, files,
+ },
+ })
+ if (id) {
+ console.log('folder id', id)
+ dispatch({
+ type: types.dataset.set_folder,
+ data: {
+ folder_id: id,
+ module
+ },
+ })
+ }
+ }).catch(e => {
+ console.error(e)
+ })
+}
diff --git a/app/client/modules/pix2wav/pix2wav.tasks.js b/app/client/modules/pix2wav/pix2wav.tasks.js
new file mode 100644
index 0000000..646e28c
--- /dev/null
+++ b/app/client/modules/pix2wav/pix2wav.tasks.js
@@ -0,0 +1,7 @@
+import uuidv1 from 'uuid/v1'
+
+import socket from '../../socket'
+import types from '../../types'
+
+import actions from '../../actions'
+
diff --git a/app/client/modules/pix2wav/views/pix2wav.new.js b/app/client/modules/pix2wav/views/pix2wav.new.js
new file mode 100644
index 0000000..aff00aa
--- /dev/null
+++ b/app/client/modules/pix2wav/views/pix2wav.new.js
@@ -0,0 +1,13 @@
+import { h, Component } from 'preact'
+
+import NewDatasetForm from '../../../dataset/dataset.new'
+
+import pix2wavModule from '../pix2wav.module'
+
+export default function Pix2WavNew ({ history }) {
+ return (
+ <div class='app pix2wav'>
+ <NewDatasetForm module={pix2wavModule} history={history} />
+ </div>
+ )
+}
diff --git a/app/client/modules/pix2wav/views/pix2wav.show.js b/app/client/modules/pix2wav/views/pix2wav.show.js
new file mode 100644
index 0000000..46a2436
--- /dev/null
+++ b/app/client/modules/pix2wav/views/pix2wav.show.js
@@ -0,0 +1,116 @@
+import { h, Component } from 'preact'
+import { bindActionCreators } from 'redux'
+import { connect } from 'react-redux'
+import util from '../../../util'
+
+import * as pix2wavActions from '../pix2wav.actions'
+import * as pix2wavTasks from '../pix2wav.tasks'
+
+import Loading from '../../../common/loading.component'
+import DatasetForm from '../../../dataset/dataset.form'
+import NewDatasetForm from '../../../dataset/dataset.new'
+import UploadStatus from '../../../dataset/upload.status'
+import { FileList, FileRow } from '../../../common/fileList.component'
+
+import DatasetComponent from '../../../dataset/dataset.component'
+
+import pix2wavModule from '../pix2wav.module'
+
+class Pix2wavShow extends Component {
+ constructor(props){
+ super(props)
+ this.datasetActions = this.datasetActions.bind(this)
+ }
+ componentWillMount(){
+ const id = this.props.match.params.id || localStorage.getItem('pix2wav.last_id')
+ console.log('load dataset:', id)
+ const { match, pix2wav, actions } = this.props
+ if (id === 'new') return
+ if (id) {
+ if (parseInt(id)) localStorage.setItem('pix2wav.last_id', id)
+ if (! pix2wav.folder || pix2wav.folder.id !== id) {
+ actions.load_directories(id)
+ }
+ }
+ }
+ render(){
+ const { pix2wav, match, history } = this.props
+ const { folderLookup } = (pix2wav.data || {})
+ const folder = (folderLookup || {})[pix2wav.folder_id] || {}
+
+ return (
+ <div className='app pix2wav'>
+ <div class='heading'>
+ <div class='spaced'>
+ <h1>{folder ? folder.name : <Loading />}</h1>
+ <UploadStatus />
+ </div>
+ </div>
+ {folder && folder.name && folder.name !== 'unsorted' &&
+ <DatasetForm
+ title='Add Files'
+ module={pix2wavModule}
+ folder={folder}
+ canUpload canAddURL
+ />
+ }
+ <DatasetComponent
+ loading={pix2wav.loading}
+ progress={pix2wav.progress}
+ id={pix2wav.folder_id}
+ module={pix2wavModule}
+ data={pix2wav.data}
+ folder={folder}
+ history={history}
+ onPickFile={(file, e) => {
+ e.preventDefault()
+ e.stopPropagation()
+ console.log('picked a file', file)
+ }}
+ datasetActions={this.datasetActions}
+ />
+ </div>
+ )
+ }
+ datasetActions(dataset, isFetching=false, isProcessing=false){
+ const { pix2wav, remote } = this.props
+ const input = pix2wav.data.fileLookup[dataset.input[0]]
+ if (! input) return null
+ if (input.name && input.name.match(/(gif|jpe?g|png)$/i)) return null
+ return (
+ <div>
+ <div class={'actions'}>
+ <span class='link' onClick={() => remote.train_task(dataset, pix2wav.folder_id, 1)}>train</span>
+ <span class='link' onClick={() => remote.train_task(dataset, pix2wav.folder_id, 2)}>2x</span>
+ <span class='link' onClick={() => remote.train_task(dataset, pix2wav.folder_id, 4)}>4x</span>
+ <span class='link' onClick={() => remote.train_task(dataset, pix2wav.folder_id, 6)}>6x</span>
+ <span class='link' onClick={() => remote.train_task(dataset, pix2wav.folder_id, 18)}>18x</span>
+ </div>
+ {dataset.isBuilt
+ ? <div class='subtext'>
+ {'fetched '}
+ <span class='link' onClick={() => remote.clear_cache_task(dataset)}>rm</span>
+ </div>
+ : isFetching
+ ? <div class='subtext'>
+ {'fetching'}
+ </div>
+ : <div class='subtext'>
+ <span class='link' onClick={() => remote.fetch_task(input.url, input.id, dataset.name)}>fetch</span>
+ </div>
+ }
+ </div>
+ )
+ }
+}
+
+const mapStateToProps = state => ({
+ pix2wav: state.module.pix2wav,
+})
+
+const mapDispatchToProps = (dispatch, ownProps) => ({
+ actions: bindActionCreators(pix2wavActions, dispatch),
+ remote: bindActionCreators(pix2wavTasks, dispatch),
+})
+
+export default connect(mapStateToProps, mapDispatchToProps)(Pix2wavShow)
diff --git a/app/client/modules/samplernn/index.js b/app/client/modules/samplernn/index.js
index 7d5e36e..485a9a4 100644
--- a/app/client/modules/samplernn/index.js
+++ b/app/client/modules/samplernn/index.js
@@ -1,5 +1,6 @@
import { h, Component } from 'preact'
import { Route, Link } from 'react-router-dom'
+import util from '../../util'
import SampleRNNNew from './views/samplernn.new'
import SampleRNNShow from './views/samplernn.show'
@@ -8,6 +9,7 @@ import SampleRNNResults from './views/samplernn.results'
import SampleRNNGraph from './views/samplernn.graph'
function router () {
+ document.body.style.backgroundImage = 'linear-gradient(' + (util.randint(40)+40) + 'deg, #eef, #fef)'
return (
<section>
<Route exact path='/samplernn/new/' component={SampleRNNNew} />
diff --git a/app/client/modules/samplernn/samplernn.actions.js b/app/client/modules/samplernn/samplernn.actions.js
index d0fda31..a957e25 100644
--- a/app/client/modules/samplernn/samplernn.actions.js
+++ b/app/client/modules/samplernn/samplernn.actions.js
@@ -7,13 +7,13 @@ import * as datasetLoader from '../../dataset/dataset.loader'
import actions from '../../actions'
-import { allProgress } from '../../util'
+import util from '../../util'
import samplernnModule from './samplernn.module'
export const load_directories = (id) => (dispatch) => {
const module = samplernnModule.name
- allProgress([
+ util.allProgress([
datasetLoader.load(module),
actions.socket.list_directory({ module, dir: 'datasets' }),
actions.socket.list_directory({ module, dir: 'results' }),
diff --git a/app/client/modules/samplernn/views/samplernn.graph.js b/app/client/modules/samplernn/views/samplernn.graph.js
index 821f1cb..9685802 100644
--- a/app/client/modules/samplernn/views/samplernn.graph.js
+++ b/app/client/modules/samplernn/views/samplernn.graph.js
@@ -2,7 +2,9 @@ import { h, Component } from 'preact'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
-import { lerp, norm, randint, randrange } from '../../../util'
+import util from '../../../util'
+
+const { lerp, norm, randint, randrange } = util
import * as samplernnActions from '../samplernn.actions'
@@ -38,7 +40,7 @@ class SampleRNNGraph extends Component {
canvas.style.width = canvas.width + 'px'
canvas.style.height = canvas.height + 'px'
- const ctx = canvas.getContext('2d')
+ const ctx = canvas.getContext('2d-lodpi')
const w = canvas.width = canvas.width * devicePixelRatio
const h = canvas.height = canvas.height * devicePixelRatio
ctx.clearRect(0,0,w,h)
diff --git a/app/client/modules/samplernn/views/samplernn.import.js b/app/client/modules/samplernn/views/samplernn.import.js
index cce4aea..61df4da 100644
--- a/app/client/modules/samplernn/views/samplernn.import.js
+++ b/app/client/modules/samplernn/views/samplernn.import.js
@@ -1,7 +1,7 @@
import { h, Component } from 'preact'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
-import * as util from '../../../util'
+import util from '../../../util'
import * as samplernnActions from '../samplernn.actions'
diff --git a/app/client/modules/samplernn/views/samplernn.new.js b/app/client/modules/samplernn/views/samplernn.new.js
index 5f657c0..5640afc 100644
--- a/app/client/modules/samplernn/views/samplernn.new.js
+++ b/app/client/modules/samplernn/views/samplernn.new.js
@@ -1,7 +1,7 @@
import { h, Component } from 'preact'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
-import * as util from '../../../util'
+import util from '../../../util'
import NewDatasetForm from '../../../dataset/dataset.new'
diff --git a/app/client/modules/samplernn/views/samplernn.results.js b/app/client/modules/samplernn/views/samplernn.results.js
index 12367a3..3d448fc 100644
--- a/app/client/modules/samplernn/views/samplernn.results.js
+++ b/app/client/modules/samplernn/views/samplernn.results.js
@@ -2,8 +2,8 @@ import { h, Component } from 'preact'
import { bindActionCreators } from 'redux'
import { Link } from 'react-router-dom';
import { connect } from 'react-redux'
+import util from '../../../util'
-import * as util from '../../../util'
import * as samplernnActions from '../samplernn.actions'
import * as audioPlayerActions from '../../../common/audioPlayer/audioPlayer.actions'
diff --git a/app/client/modules/samplernn/views/samplernn.show.js b/app/client/modules/samplernn/views/samplernn.show.js
index f44deda..b7e0740 100644
--- a/app/client/modules/samplernn/views/samplernn.show.js
+++ b/app/client/modules/samplernn/views/samplernn.show.js
@@ -1,7 +1,7 @@
import { h, Component } from 'preact'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
-import * as util from '../../../util'
+import util from '../../../util'
import * as samplernnActions from '../samplernn.actions'
import * as samplernnTasks from '../samplernn.tasks'
diff --git a/app/client/queue/queue.reducer.js b/app/client/queue/queue.reducer.js
index b9ed194..033acba 100644
--- a/app/client/queue/queue.reducer.js
+++ b/app/client/queue/queue.reducer.js
@@ -1,5 +1,5 @@
import types from '../types'
-import * as util from '../util'
+import util from '../util'
import moment from 'moment'
const queueInitialState = {
diff --git a/app/client/util/hidpi-canvas.js b/app/client/util/hidpi-canvas.js
new file mode 100644
index 0000000..f0a7a0d
--- /dev/null
+++ b/app/client/util/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);
diff --git a/app/client/util/index.js b/app/client/util/index.js
index a811dcf..4ce1245 100644
--- a/app/client/util/index.js
+++ b/app/client/util/index.js
@@ -2,17 +2,13 @@ import * as sort from './sort'
import * as format from './format'
import * as maths from './math'
-export {
- sort,
- ...maths,
- ...format,
-}
+import './hidpi-canvas'
-export const is_iphone = !!((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)))
-export const is_ipad = !!(navigator.userAgent.match(/iPad/i))
-export const is_android = !!(navigator.userAgent.match(/Android/i))
-export const is_mobile = is_iphone || is_ipad || is_android
-export const is_desktop = ! is_mobile;
+const is_iphone = !!((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)))
+const is_ipad = !!(navigator.userAgent.match(/iPad/i))
+const is_android = !!(navigator.userAgent.match(/Android/i))
+const is_mobile = is_iphone || is_ipad || is_android
+const is_desktop = ! is_mobile;
const htmlClassList = document.body.parentNode.classList
htmlClassList.add(is_desktop ? 'desktop' : 'mobile')
@@ -20,9 +16,7 @@ htmlClassList.remove('loading')
// window.debug = false
-document.body.style.backgroundImage = 'linear-gradient(' + (randint(40)+40) + 'deg, #fde, #ffe)'
-
-export const allProgress = (promises, progress_cb) => {
+const allProgress = (promises, progress_cb) => {
let d = 0
progress_cb(0, 0, promises.length)
promises.forEach((p) => {
@@ -34,3 +28,13 @@ export const allProgress = (promises, progress_cb) => {
})
return Promise.all(promises)
}
+
+document.body.style.backgroundImage = 'linear-gradient(' + (maths.randint(40)+40) + 'deg, #fde, #ffe)'
+
+export default {
+ ...maths,
+ ...format,
+ sort,
+ allProgress,
+ is_iphone, is_ipad, is_android, is_mobile, is_desktop,
+}
diff --git a/app/client/util/math.js b/app/client/util/math.js
index 253bacd..c301ffd 100644
--- a/app/client/util/math.js
+++ b/app/client/util/math.js
@@ -1,13 +1,12 @@
-export function mod(n,m){ return n-(m * Math.floor(n/m)) }
-export function clamp(n,a,b) { return n<a?a:n<b?n:b }
-export function norm(n,a,b) { return (n-a) / (b-a) }
-export function lerp(n,a,b) { return (b-a)*n+a }
-export function mix(n,a,b) { return a*(1-n)+b*n }
-export function randint(n) { return Math.floor(Math.random()*n) }
+export const mod = (n,m) => n-(m * Math.floor(n/m))
+export const clamp = (n,a,b) => n<a?a:n<b?n:b
+export const norm = (n,a,b) => (n-a) / (b-a)
+export const lerp = (n,a,b) => (b-a)*n+a
+export const mix = (n,a,b) => a*(1-n)+b*n
+export const randint = (n) => Math.floor(Math.random()*n)
export function randrange(a,b){ return Math.random() * (b-a) + a }
export function randsign(){ return Math.random() >= 0.5 ? -1 : 1 }
export function choice (a){ return a[ Math.floor(Math.random() * a.length) ] }
-export function lerp(n,a,b){ return (b-a)*n+a }
export function angle(x0,y0,x1,y1){ return Math.atan2(y1-y0,x1-x0) }
export function dist(x0,y0,x1,y1){ return Math.sqrt(Math.pow(x1-x0,2)+Math.pow(y1-y0,2)) }
export function xor(a,b){ a=!!a; b=!!b; return (a||b) && !(a&&b) }