diff options
| author | s-ol <s+removethis@s-ol.nu> | 2021-01-20 23:15:14 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2021-01-22 13:45:11 +0000 |
| commit | 61a9215b410686ed587c6681fe86d181d895beac (patch) | |
| tree | 5118631f517c909480b7bd4217c77fd877c7f8ff /app/app.js | |
| parent | add shell.nix (diff) | |
| download | isomorphic-kb-explorer-61a9215b410686ed587c6681fe86d181d895beac.tar.gz isomorphic-kb-explorer-61a9215b410686ed587c6681fe86d181d895beac.zip | |
add different layouts
Diffstat (limited to 'app/app.js')
| -rw-r--r-- | app/app.js | 135 |
1 files changed, 71 insertions, 64 deletions
@@ -1,5 +1,6 @@ import React from 'react'; -import css from './css'; +import { pos, height } from './style'; +import notes from './notes'; const statbyte = (stat, chan) => (stat << 4) | chan; const NOTE_ON = 0b1001; @@ -23,59 +24,8 @@ const parse = message => ({ val: message.data[2] / 127, }); -const longSize = 3; -const rowStaggered = true; -const w = longSize * (rowStaggered ? Math.sqrt(3) : 2 ); -const h = longSize * (rowStaggered ? 2 : Math.sqrt(3)); -const sx = longSize * (rowStaggered ? Math.sqrt(3) : 1.5 ); -const sy = longSize * (rowStaggered ? 1.5 : Math.sqrt(3)); -const rem = (n) => `${n}rem`; - -css(` -body { - background: #212121; - margin: 2rem; - - font-family: sans-serif; -} - -.app, .keyboard { - position: relative; -} - -.hexagon { - position: absolute; - width: ${rem(w)}; - height: ${rem(h)}; -} - -.hexagon > .inner { - margin: auto; - width: ${rem(Math.min(w, h) * 0.8)}; - height: ${rem(Math.min(w, h) * 0.8)}; - padding: ${rem(longSize * 0.4)}; - border-radius: ${rem(longSize)}; - box-sizing: border-box; - font-size: ${rem(longSize * 0.5)}; - text-align: center; - background: #696969; - color: #eeeeee; - cursor: pointer; - - transition: background 300ms; -} -.hexagon > .inner:hover { - background: #848484; -} -.hexagon > .inner:active, -.hexagon.active > .inner { - background: #eeeeee; - color: #696969; -} -`); - -const Hexagon = ({ x, y, children, state, note, send }) => { - if (rowStaggered) { +const Hexagon = ({ x, y, children, state, note, send, major }) => { + if (major == 'row') { if (y % 2 == 0) x += 0.5; } else { @@ -86,10 +36,7 @@ const Hexagon = ({ x, y, children, state, note, send }) => { return ( <div className={'hexagon' + (state ? ' active' : '')} - style={{ - top: rem(y * sy), - left: rem(x * sx), - }} + style={pos([x, y], major)} > <div className="inner" @@ -102,6 +49,33 @@ const Hexagon = ({ x, y, children, state, note, send }) => { ); }; +const layouts = { + wicki_hayden: { + major: 'row', + map: ([x, y], [w, h]) => { + let note = 48 + 2 * x + 6 * y; + if (y % 2 == 0) note += 1; + return note; + }, + }, + harmonic: { + major: 'col', + map: ([x, y], [w, h]) => { + let note = 48 + x * 0.5 + y * 7; + if (x % 2 === 1) note += 3.5; + return note; + }, + }, + gerhard: { + major: 'col', + map: ([x, y], [w, h]) => { + let note = 48 + x * 3.5 + y; + if (x % 2 === 1) note -= 0.5; + return note; + }, + }, +}; + const range = i => new Array(i).fill(true); class Keyboard extends React.Component { @@ -120,14 +94,19 @@ class Keyboard extends React.Component { } render() { - const { w, h, send } = this.props; + const { w, h, send, layout, showMidi } = this.props; + const { major, map } = layouts[layout]; return ( - <div className="keyboard"> + <div + className={`keyboard ${major}-major`} + style={{ + height: height(h, major), + }} + > {range(w).map((_, x) => ( range(h).map((_, y) => { - let note = 48 + 2 * x + 6 * (h - y); - if (y % 2 == 0) note += 1; + const note = map([x, y], [w, h]); return ( <Hexagon key={x + ',' + y} @@ -135,8 +114,9 @@ class Keyboard extends React.Component { note={note} state={this.state[note]} send={send} + major={major} > - {note} + {showMidi ? notes[note % 12] : note} </Hexagon> ); }) @@ -149,6 +129,10 @@ class Keyboard extends React.Component { export default class App extends React.Component { keyboardRef = React.createRef(); + state = { + layout: 'wicki_hayden', + }; + componentDidUpdate(prevProps) { if (prevProps.midiin) prevProps.midiin.onmidimessage = null; @@ -178,10 +162,33 @@ export default class App extends React.Component { this.props.midiout.send(msg); } + onlayout = (e) => { + this.setState({ layout: e.target.value }); + } + render() { + const { configure, showMidi } = this.props; + const { layout } = this.state; + return ( <div className="app"> - <Keyboard ref={this.keyboardRef} w={10} h={4} send={this.send} /> + <button onClick={configure}>settings</button> + <label>layout: + <select name="layout" onChange={this.onlayout} value={layout}> + <option value="wicki_hayden">Wicki-Hayden</option> + <option value="harmonic">Harmonic Table</option> + <option value="gerhard">Gerhard</option> + </select> + </label> + + <Keyboard + ref={this.keyboardRef} + w={10} + h={4} + send={this.send} + layout={layout} + showMidi={showMidi} + /> </div> ); } |
