aboutsummaryrefslogtreecommitdiffstats
path: root/app/app.js
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2021-01-20 23:15:14 +0000
committers-ol <s+removethis@s-ol.nu>2021-01-22 13:45:11 +0000
commit61a9215b410686ed587c6681fe86d181d895beac (patch)
tree5118631f517c909480b7bd4217c77fd877c7f8ff /app/app.js
parentadd shell.nix (diff)
downloadisomorphic-kb-explorer-61a9215b410686ed587c6681fe86d181d895beac.tar.gz
isomorphic-kb-explorer-61a9215b410686ed587c6681fe86d181d895beac.zip
add different layouts
Diffstat (limited to 'app/app.js')
-rw-r--r--app/app.js135
1 files changed, 71 insertions, 64 deletions
diff --git a/app/app.js b/app/app.js
index 8679784..5f78b4a 100644
--- a/app/app.js
+++ b/app/app.js
@@ -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>
);
}