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}