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);
+ }
}