diff --git a/packages/client/src/components/MidiInfo.svelte b/packages/client/src/components/MidiInfo.svelte index fa4ab7a4..0334773d 100644 --- a/packages/client/src/components/MidiInfo.svelte +++ b/packages/client/src/components/MidiInfo.svelte @@ -1,5 +1,5 @@
@@ -77,6 +84,18 @@
+
+ +
+ +
+
@@ -85,7 +104,7 @@ .midi-body { display: grid; gap: 0.5rem; - grid-template-columns: 25% 25% 25%; + grid-template-columns: 25% 25% 25% 25%; grid-template-rows: auto; align-items: center; @media (width <= 475px) { diff --git a/packages/client/src/components/Score.svelte b/packages/client/src/components/Score.svelte index 83e458a1..ab119d09 100644 --- a/packages/client/src/components/Score.svelte +++ b/packages/client/src/components/Score.svelte @@ -115,7 +115,7 @@ } .g-clef { font-size: 3.6rem; - bottom: 4.2rem; + bottom: 4.12rem; left: 1rem; pointer-events: none; position: absolute; diff --git a/packages/client/src/routes/(site)/+page.svelte b/packages/client/src/routes/(site)/+page.svelte index dbf3d38a..cfb53b23 100644 --- a/packages/client/src/routes/(site)/+page.svelte +++ b/packages/client/src/routes/(site)/+page.svelte @@ -5,8 +5,8 @@ import Score from '$components/Score.svelte' import { currentGame, gameActions } from '$stores/game' - import { midiActions, midiInput } from '$stores/midi' - import { getNote } from '$utils/midi' + import { useKeyboard, midiActions, midiInput } from '$stores/midi' + import { getNote, parseNote } from '$utils/midi' import type { NoteMessageEvent } from 'webmidi' import type { Note } from '@/types' @@ -18,6 +18,10 @@ let timeout: ReturnType | undefined let guessState: 'waiting' | 'correct' | 'wrong' | 'ended' + const regexNote = /^[A-G]$/ + const regexPosInt = /^[0-9]$/ + let keyboardInput = '' + onMount(() => { handlePromptMIDI() }) @@ -33,8 +37,9 @@ console.log('noteon', e) // @ts-ignore const data = e.rawData as [number, number, number] - const value = data[1] - + handlePlayedNote(data[1]) + } + function handlePlayedNote(value: number) { if (!$currentGame) { played = { ...getNote(value), value, correct: false } } else { @@ -55,7 +60,31 @@ }, 2000) } } - + function handleKeyDown(e: KeyboardEvent) { + if ($useKeyboard) { + const pressed = e.key.toUpperCase() + const zeroPressed = keyboardInput.length === 0 + const onePressed = keyboardInput.length === 1 + const twoPressed = keyboardInput.length === 2 + if (zeroPressed && regexNote.test(pressed)) { + keyboardInput += pressed + } else if (onePressed && pressed === 'B') { + keyboardInput += '♭' + } else if (onePressed && pressed === 'S') { + keyboardInput += '♯' + } else if ( + (onePressed && regexPosInt.test(pressed)) || + (twoPressed && regexPosInt.test(pressed)) + ) { + // Octave pressed + const note = parseNote(keyboardInput + pressed) + if ('data' in note) { + handlePlayedNote(note.data) + } + keyboardInput = '' + } + } + } async function handlePromptMIDI() { status = 'Finding device...' const res = await midiActions.openMidi() @@ -77,6 +106,8 @@ } + +

Practise Music Reading

@@ -115,6 +146,9 @@ {/if} {/if} + {#if $useKeyboard && keyboardInput} +
Input: {keyboardInput}
+ {/if}