diff options
Diffstat (limited to 'client/index.js')
| -rw-r--r-- | client/index.js | 162 |
1 files changed, 124 insertions, 38 deletions
diff --git a/client/index.js b/client/index.js index e44508d..6a32627 100644 --- a/client/index.js +++ b/client/index.js @@ -5,53 +5,139 @@ import colundi from './lib/colundi' import { mod, browser, requestAudioContext } from './lib/util' import { Grid, Views, HexFactory } from 'honeycomb-grid' +const gridSize = browser.isMobile ? 25 : 50 +const hexagon = polygon(6, gridSize) + +const grid = Grid({ + size: gridSize, +}) + const Hex = HexFactory({ - size: 50, - template: function(hex) { - return ` - <svg class='hex'> - <polygon points="43.30127019 0 86.60254039 25 86.60254039 75 43.30127019 100 0 75 0 25"/> - </svg> - ` - } + size: gridSize, + template: function(hex) { + return ` + <svg class='hex'> + <polygon points="${hexagon.pointString}" /> + </svg> + ` + } }) const container = document.querySelector("#container") +const origin = { + x: container.offsetWidth / 2 - hexagon.width / 2, + y: container.offsetHeight / 2 - hexagon.height / 2, +} const view = Views.DOM({ - container: container, - origin: { - x: container.offsetWidth / 2, - y: container.offsetHeight / 2, - } + container: container, + origin: origin, }) -const origin = Hex(0,0,0) -const seen = {} -let perimeter = [ origin ] +let last = null, dragging = false +let hexes -for (let i = 0, len = colundi.list.length; i < len;) { - const hex = perimeter.shift() - const id = hexToString(hex) - if (seen[id]) continue - seen[id] = true - let pair = colundi.list[i] - const neighbors = [0,1,2,3,4,5].map((i) => Hex.neighbor(hex, i)) - perimeter = perimeter.concat(neighbors) - view.renderHexes([ hex ]) - const el = container.lastChild - el.querySelector('polygon').setAttribute('fill', pair.color) - i++ -} - -requestAudioContext(() => { -}) - -keys.listen(function(index){ - index += 20 - const freq = colundi.index(index) - kalimba.play(freq) -}) +requestAudioContext(init) +function init () { + if (browser.isMobile) { + document.addEventListener('touchstart', touch(down)) + document.addEventListener('touchmove', touch(move)) + document.addEventListener('touchend', touch(up)) + } + else { + document.addEventListener('mousedown', down) + document.addEventListener('mousemove', move) + document.addEventListener('mouseup', up) + } + build(colundi.list) + keys.listen(function(index){ + index += 20 + const freq = colundi.index(index) + kalimba.play(freq) + }) +} +function build (list) { + container.innerHTML = "" + let perimeter = [ Hex(0, 0, 0) ] + hexes = {} + for (let i = 0, len = list.length; i < len;) { + const hex = perimeter.shift() + const id = hexToString(hex) + if (hexes[id]) continue + let pair = list[len - i - 1] + const neighbors = [0,1,2,3,4,5].map((j) => Hex.neighbor(hex, j)) + perimeter = perimeter.concat(neighbors) + view.renderHexes([ hex ]) + const el = container.lastChild + el.querySelector('polygon').setAttribute('fill', pair.color) + hexes[id] = { el: el, freq: pair.freq } + i++ + } +} +function down (e){ + dragging = true + const hex = grid.pointToHex({ + x: e.pageX - origin.x - hexagon.width/2, + y: e.pageY - origin.y - hexagon.height/2 + }) + const pair = find(hex) + if (! pair) return + pair.el.style.opacity = 0.5 + kalimba.play( pair.freq ) +} +function move (e){ + if (! dragging) return + const hex = grid.pointToHex({ + x: e.pageX - origin.x - hexagon.width/2, + y: e.pageY - origin.y - hexagon.height/2 + }) + const pair = find(hex) + if (last === pair) return + if (last) last.el.style.opacity = 1 + if (! pair) return + pair.el.style.opacity = 0.5 + kalimba.play( pair.freq ) + last = pair +} +function up (e){ + if (last) last.el.style.opacity = 1 + last = null + dragging = false +} +function find(hex){ + const id = hexToString(hex) + if (id in hexes) return hexes[id] + return null +} +function touch(fn){ + return (e) => fn(e.touches[0]) +} +function polygon(n, side){ + const points = [] + const xs = [], ys = [] + let min_x = Infinity, max_x = -Infinity + let min_y = Infinity, max_y = -Infinity + let x, y + for (let i = 0; i < n; i++) { + x = side * Math.cos(Math.PI/n * (1 + 2*i)) + y = side * Math.sin(Math.PI/n * (1 + 2*i)) + min_x = Math.min(min_x, x) + max_x = Math.max(max_x, x) + min_y = Math.min(min_y, y) + max_y = Math.max(max_y, y) + xs.push(x) + ys.push(y) + } + for (let i = 0; i < n; i++) { + points.push(xs[i] - min_x, ys[i] - min_y) + } + return { + points: points, + pointString: points.map(p => p.toFixed(3)).join(" "), + width: max_x - min_x, + height: max_y - min_y + } +} function hexToString(hex) { return [hex.x, hex.y, hex.z].join("_") } |
