diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2021-01-02 14:48:49 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2021-01-02 14:48:49 +0000 |
| commit | f3818e16d0318891a7af08699c99618ef3e753d2 (patch) | |
| tree | 8d86c2de993b76b1e9ec154f908ee31c117a1bf2 | |
| parent | initial commit (diff) | |
| download | isomorphic-kb-explorer-f3818e16d0318891a7af08699c99618ef3e753d2.tar.gz isomorphic-kb-explorer-f3818e16d0318891a7af08699c99618ef3e753d2.zip | |
more things?
| -rw-r--r-- | app/app.js | 103 |
1 files changed, 68 insertions, 35 deletions
@@ -2,17 +2,20 @@ import React from 'react'; import css from './css'; const statbyte = (stat, chan) => (stat << 4) | chan; -const noteon = (key, vel=127, chan=0) => [statbyte(0b1001, chan), key, vel]; -const noteoff = (key, vel=127, chan=0) => [statbyte(0b1000, chan), key, vel]; -const ccchange = (ctl, val, chan=0) => [statbyte(0b1011, chan), ctl, val]; +const NOTE_ON = 0b1001; +const NOTE_OFF = 0b1000; +const CCHANGE = 0b1011; + +/* + const noteon = (key, vel=127, chan=0) => [statbyte(0b1001, chan), key, vel]; + const noteoff = (key, vel=127, chan=0) => [statbyte(0b1000, chan), key, vel]; + const ccchange = (ctl, val, chan=0) => [statbyte(0b1011, chan), ctl, val]; +*/ const clamp = (val, min=0, max=1) => Math.max(min, Math.min(val, max)); const ramp = i => new Array(i).fill(true).map((_, i) => i); const mix = (i, a, b) => i * a + (1-i) * b; -window.ccchange = ccchange; -window.noteon = noteon; - const parse = message => ({ cmd: message.data[0] >> 4, chan: message.data[0] & 0xf, @@ -36,7 +39,7 @@ body { font-family: sans-serif; } -.app { +.app, .keyboard { position: relative; } @@ -71,7 +74,7 @@ body { } `); -const Hexagon = ({ x, y, children, state }) => { +const Hexagon = ({ x, y, children, state, note, send }) => { if (rowStaggered) { if (y % 2 == 0) x += 0.5; @@ -90,7 +93,8 @@ const Hexagon = ({ x, y, children, state }) => { > <div className="inner" - onClick={() => console.info(x,y)} + onMouseDown={() => send(NOTE_ON, note)} + onMouseUp ={() => send(NOTE_OFF, note)} > {children} </div> @@ -100,9 +104,50 @@ const Hexagon = ({ x, y, children, state }) => { const range = i => new Array(i).fill(true); +class Keyboard extends React.Component { + state = {}; + + onmessage = (message) => { + switch (message.cmd) { + case NOTE_ON: + this.setState(old => ({ ...old, [message.note]: true })); + break; + + case NOTE_OFF: + this.setState(old => ({ ...old, [message.note]: false })); + break; + } + } + + render() { + const { w, h, send } = this.props; + + return ( + <div className="keyboard"> + {range(w).map((_, x) => ( + range(h).map((_, y) => { + let note = 36 + 2 * x + 6 * (h - y); + if (y % 2 == 0) note += 1; + return ( + <Hexagon + key={x + ',' + y} + x={x} y={y} + note={note} + state={this.state[note]} + send={send} + > + {note} + </Hexagon> + ); + }) + ))} + </div> + ); + } +} export default class App extends React.Component { - state = {}; + keyboardRef = React.createRef(); componentDidUpdate(prevProps) { if (prevProps.midiin) @@ -115,40 +160,28 @@ export default class App extends React.Component { onmessage = (e) => { const message = parse(e); + if (this.keyboardRef.current) + this.keyboardRef.current.onmessage(message); + switch (message.cmd) { - case 9: - // NOTE_ON - this.setState(old => ({ ...old, [message.note]: true })); + case NOTE_ON: + console.info(message.note); break; + } + } - case 8: - // NOTE_OFF - this.setState(old => ({ ...old, [message.note]: false })); - break; + send = (command, note) => { + if (!this.props.midiout) + return; - case 11: - // CC - break; - } + const msg = [statbyte(command, 0), note, 127]; + this.props.midiout.send(msg); } render() { - const xs = 10; - const ys = 4; - return ( <div className="app"> - {range(xs).map((_, x) => ( - range(ys).map((_, y) => { - let note = 36 + 2 * x + 6 * (ys - y); - if (y % 2 == 0) note += 1; - return ( - <Hexagon key={x + ',' + y} x={x} y={y} note={note} state={this.state[note]}> - {note} - </Hexagon> - ); - }) - ))} + <Keyboard ref={this.keyboardRef} w={10} h={4} send={this.send} /> </div> ); } |
