summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/index.js162
-rw-r--r--index.html7
2 files changed, 124 insertions, 45 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("_")
}
diff --git a/index.html b/index.html
index 2175fbf..5288f88 100644
--- a/index.html
+++ b/index.html
@@ -13,16 +13,9 @@ body {
position: absolute; top: 0; left: 0;
width: 100%; height: 100%;
}
-.mobile #container {
- transform-origin: 50% 50%;
- transform: scale(0.6);
-}
.desktop body {
user-select: none;
}
-.hex {
- transform: translate(-40px, -50px);
-}
@media only screen and (max-device-width: 800px) {
html,body {
margin: 0;