From 1226a1f3cbf9ca88ce6004af409bd22b43d4afe6 Mon Sep 17 00:00:00 2001 From: Greg Jopa <534034+gregjopa@users.noreply.github.com> Date: Fri, 31 Mar 2023 22:24:10 -0500 Subject: [PATCH] feat: use vexflow to render note name (#8) --- src/App.tsx | 20 ++++---- src/components/StaveNote.tsx | 90 +++++++++++++++++++++++++++--------- 2 files changed, 78 insertions(+), 32 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index f7af209..00b3a7d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -174,6 +174,10 @@ function App() { playNote(noteValue, octave); } + const waitingForGuess = + gameState === GameState.WaitingForGuess || + gameState === GameState.NotStarted; + return ( <>
@@ -186,16 +190,14 @@ function App() { + -
Score: {countOfCorrectGuesses}
void; + shouldDisplayNoteName: boolean; }; -export const StaveNote: React.FC = ({ note, onClick }) => { +export const StaveNote: React.FC = ({ + note, + onClick, + shouldDisplayNoteName, +}) => { const vexflowRef = useCallback( (node: HTMLDivElement) => { if (node !== null) { const nodeWidth = node.getBoundingClientRect().width; const width = nodeWidth > 300 ? nodeWidth : 300; - draw(node, { note, width, height: 250 }); + draw({ + container: node, + note, + width, + height: 250, + shouldDisplayNoteName, + }); } }, - [note] + [note, shouldDisplayNoteName] ); return ( @@ -27,11 +38,23 @@ export const StaveNote: React.FC = ({ note, onClick }) => { ); }; -function draw( - container: HTMLDivElement, - { note, width, height }: { note: Note; width: number; height: number } -) { - const { Renderer, Stave, StaveNote, Voice, Accidental, Formatter } = Vex.Flow; +type DrawParams = { + container: HTMLDivElement; + note: Note; + width: number; + height: number; + shouldDisplayNoteName: boolean; +}; + +function draw({ + container, + note, + width, + height, + shouldDisplayNoteName, +}: DrawParams) { + const { Renderer, Stave, StaveNote, TextNote, Voice, Accidental, Formatter } = + Vex.Flow; container.innerHTML = ""; const renderer = new Renderer(container, Renderer.Backends.SVG); @@ -48,23 +71,44 @@ function draw( stave.addKeySignature(keySignature); stave.setContext(context).draw(); - const notes = [ - new StaveNote({ - clef, - keys: [`${noteName}/${octave}`], - duration: "4", - auto_stem: true, - align_center: true, - }), - ]; - - const voice = new Voice({ num_beats: 1, beat_value: 4 }) + const staveNote = new StaveNote({ + clef, + keys: [`${noteName}/${octave}`], + duration: "4", + auto_stem: true, + align_center: true, + }); + + const textNote = new TextNote({ + text: noteName + octave, + duration: "4", + align_center: true, + }) + .setContext(context) + .setJustification(TextNote.Justification.CENTER) + .setLine(11) + .setFont( + '-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif', + 10, + 400 + ); + + const staveNoteVoice = new Voice({ num_beats: 1, beat_value: 4 }) + .setStrict(false) + .addTickables([staveNote]); + + const textNoteVoice = new Voice({ num_beats: 1, beat_value: 4 }) .setStrict(false) - .addTickables(notes); + .addTickables([textNote]); - Accidental.applyAccidentals([voice], keySignature); + Accidental.applyAccidentals([staveNoteVoice], keySignature); - new Formatter().joinVoices([voice]).format([voice], scaledWidth / 2); + new Formatter() + .joinVoices([staveNoteVoice, textNoteVoice]) + .format([staveNoteVoice, textNoteVoice], scaledWidth / 2); - voice.draw(context, stave); + staveNoteVoice.draw(context, stave); + if (shouldDisplayNoteName) { + textNoteVoice.draw(context, stave); + } }