Implement random note display

This commit is contained in:
Kai Vogelgesang 2024-07-18 13:11:29 +02:00
parent 70923ccbe4
commit a43472f7f2
Signed by: kai
GPG Key ID: 3FC8578CC818A9EB
2 changed files with 72 additions and 3 deletions

View File

@ -1,4 +1,27 @@
<script lang="ts">
import { onMount } from "svelte";
import NoteDisplay from "./NoteDisplay.svelte";
const notes = [
"c/4", "d/4", "e/4", "f/4", "g/4", "a/4", "b/4",
"c/5", "d/5", "e/5", "f/5", "g/5", "a/5", "b/5",
"c/6"
];
let note: string;
const randomize = () => {
let newNote: string;
do {
newNote = notes[Math.floor(Math.random() * notes.length)];
} while (newNote === note);
note = newNote;
}
onMount(() => {
randomize();
});
</script>
<div id="root">
@ -10,9 +33,9 @@
</header>
<main class="container">
Hallo i bims the main content
<article>
card?
<NoteDisplay note={note} />
<button on:click={randomize}>Randomize</button>
</article>
</main>
@ -28,4 +51,8 @@
flex-direction: column;
justify-content: space-between;
}
</style>
main {
width: auto;
}
</style>

42
src/NoteDisplay.svelte Normal file
View File

@ -0,0 +1,42 @@
<script lang="ts">
// import { onMount } from "svelte";
import { Renderer, Stave, Voice, StaveNote, Formatter } from "vexflow";
export let note: string;
let container: HTMLDivElement;
const draw = (note: string) => {
if (!note) return;
if (!container) return;
console.log(`call draw("${note}");`);
for (let child of container.children) {
container.removeChild(child);
}
const renderer = new Renderer(container, Renderer.Backends.SVG);
renderer.resize(200, 200);
const ctx = renderer.getContext();
const stave = new Stave(10, 40, 180);
stave.addClef("treble");
stave.setContext(ctx).draw();
const voice = new Voice({ num_beats: 1, beat_value: 4 });
voice.addTickables([
new StaveNote({ keys: [note], duration: "q" })
]);
new Formatter().joinVoices([voice]).format([voice], 180);
voice.draw(ctx, stave);
}
$: draw(note);
</script>
<div bind:this={container}></div>