diff options
| -rw-r--r-- | client/index.js | 80 | ||||
| -rw-r--r-- | index.html | 34 |
2 files changed, 105 insertions, 9 deletions
diff --git a/client/index.js b/client/index.js index 6a32627..eef40db 100644 --- a/client/index.js +++ b/client/index.js @@ -8,6 +8,8 @@ import { Grid, Views, HexFactory } from 'honeycomb-grid' const gridSize = browser.isMobile ? 25 : 50 const hexagon = polygon(6, gridSize) +const hertz_el = document.querySelector('#hertz') + const grid = Grid({ size: gridSize, }) @@ -17,13 +19,13 @@ const Hex = HexFactory({ template: function(hex) { return ` <svg class='hex'> - <polygon points="${hexagon.pointString}" /> + <polygon points='${hexagon.pointString}' /> </svg> ` } }) -const container = document.querySelector("#container") +const container = document.querySelector('#container') const origin = { x: container.offsetWidth / 2 - hexagon.width / 2, y: container.offsetHeight / 2 - hexagon.height / 2, @@ -34,7 +36,7 @@ const view = Views.DOM({ }) let last = null, dragging = false -let hexes +let hexes, els = [], order = [] requestAudioContext(init) @@ -49,6 +51,9 @@ function init () { document.addEventListener('mousemove', move) document.addEventListener('mouseup', up) } + document.querySelector('#frequency').addEventListener('click', sortByFrequency) + document.querySelector('#color').addEventListener('click', sortByColor) + document.querySelector('#brightness').addEventListener('click', sortByBrightness) build(colundi.list) keys.listen(function(index){ index += 20 @@ -56,8 +61,23 @@ function init () { kalimba.play(freq) }) } +function sortByBrightness () { + els.sort((a,b) => a.lum>b.lum?-1:a.lum==b.lum?0:1).map(resort) +} +function sortByColor () { + els.sort((a,b) => a.hue<b.hue?-1:a.hue==b.hue?0:1).map(resort) +} +function sortByFrequency () { + els.sort((a,b) => a.freq<b.freq?-1:a.freq==b.freq?0:1).map(resort) +} +function resort (tuple,i) { + const position = order[i] + hexes[position.id] = tuple + tuple.el.style.top = position.top + tuple.el.style.left = position.left +} function build (list) { - container.innerHTML = "" + container.innerHTML = '' let perimeter = [ Hex(0, 0, 0) ] hexes = {} for (let i = 0, len = list.length; i < len;) { @@ -70,7 +90,11 @@ function build (list) { view.renderHexes([ hex ]) const el = container.lastChild el.querySelector('polygon').setAttribute('fill', pair.color) - hexes[id] = { el: el, freq: pair.freq } + const hsl = rgbStringToHSL(pair.color) + const tuple = { el: el, freq: pair.freq, hue: (hsl[0]+0.2) % 1, lum: hsl[2] } + hexes[id] = tuple + els.push(tuple) + order.push({ id: id, top: el.style.top, left: el.style.left }) i++ } } @@ -83,6 +107,7 @@ function down (e){ const pair = find(hex) if (! pair) return pair.el.style.opacity = 0.5 + hertz_el.innerHTML = pair.freq kalimba.play( pair.freq ) } function move (e){ @@ -96,12 +121,14 @@ function move (e){ if (last) last.el.style.opacity = 1 if (! pair) return pair.el.style.opacity = 0.5 + hertz_el.innerHTML = pair.freq kalimba.play( pair.freq ) last = pair } function up (e){ if (last) last.el.style.opacity = 1 last = null + hertz_el.innerHTML = '' dragging = false } function find(hex){ @@ -133,12 +160,51 @@ function polygon(n, side){ } return { points: points, - pointString: points.map(p => p.toFixed(3)).join(" "), + 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("_") + return [hex.x, hex.y, hex.z].join('_') +} +function rgbStringToHSL(s) { + const RGB = s.replace('rgb(','').replace(')','').split(', ').map((a) => parseInt(a)) + var R = RGB[0] + var G = RGB[1] + var B = RGB[2] + var var_R = ( R / 255 ) //RGB from 0 to 255 + var var_G = ( G / 255 ) + var var_B = ( B / 255 ) + + var var_Min = Math.min( var_R, var_G, var_B ) //Min. value of RGB + var var_Max = Math.max( var_R, var_G, var_B ) //Max. value of RGB + var del_Max = var_Max - var_Min //Delta RGB value + + var H, S + var L = ( var_Max + var_Min ) / 2 + + if ( del_Max == 0 ) //This is a gray, no chroma... + { + H = 0 //HSL results from 0 to 1 + S = 0 + } + else //Chromatic data... + { + if ( L < 0.5 ) S = del_Max / ( var_Max + var_Min ) + else S = del_Max / ( 2 - var_Max - var_Min ) + + var del_R = ( ( ( var_Max - var_R ) / 6 ) + ( del_Max / 2 ) ) / del_Max + var del_G = ( ( ( var_Max - var_G ) / 6 ) + ( del_Max / 2 ) ) / del_Max + var del_B = ( ( ( var_Max - var_B ) / 6 ) + ( del_Max / 2 ) ) / del_Max + + if ( var_R == var_Max ) H = del_B - del_G + else if ( var_G == var_Max ) H = ( 1 / 3 ) + del_R - del_B + else if ( var_B == var_Max ) H = ( 2 / 3 ) + del_G - del_R + + if ( H < 0 ) H += 1 + if ( H > 1 ) H -= 1 + } + return [H,S,L] } @@ -1,8 +1,7 @@ <html> <head> <title>honeycomb</title> -<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> -<style> +<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <style> html,body { margin: 0; padding: 0; width: 100%; height: 100%; } body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; @@ -16,6 +15,31 @@ body { .desktop body { user-select: none; } +svg { + transition: all 0.5s ease; + cursor: pointer; +} +#buttons { + position: absolute; + bottom: 0; left: 0; + width: 100%; + text-align: center; +} +#buttons button { + margin: 10px; + font-size: 18px; + border: 2px solid; + background: #000; + color: #bbb; + font-weight: bold; + padding: 5px; +} +#hertz { + font-size: 36px; + padding: 10px; + color: #fff; + font-weight: bold; +} @media only screen and (max-device-width: 800px) { html,body { margin: 0; @@ -26,6 +50,12 @@ body { </head> <body> <div id="container"></div> +<div id="buttons"> + <div id="hertz"></div> + <button id="frequency">frequency</button> + <button id="color">color</button> + <button id="brightness">brightness</button> +</div> </body> <script> var s = document.createElement('script'); |
