-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathScaleInfo.svelte
More file actions
51 lines (45 loc) · 1.24 KB
/
Copy pathScaleInfo.svelte
File metadata and controls
51 lines (45 loc) · 1.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<script>
import { onMount } from "svelte";
import { scalePoint, range } from "d3";
import { Note } from "tonal";
import FretNote from "./FretNote.svelte";
let { scale } = $props();
let notes = $derived(
scale.notes.map((note, index) => {
const noteObj = Note.get(note);
return {
...noteObj,
label: noteObj.name.replace("b", "♭").replace("#", "♯"),
interval: scale.intervals[index],
};
}),
);
let container = $state(null);
let width = $state(0);
let height = $state(45);
const margin = { top: 0, right: 20, bottom: 20, left: 20 };
const dotX = $derived(
scalePoint()
.domain(range(scale.notes.length))
.range([margin.left, width - margin.right]),
);
onMount(() => {
width = container.clientWidth;
height = 45;
});
</script>
<div class="w-full h-full" bind:this={container}>
<svg class="h-12" viewBox="0 0 {width} {height}">
{#each notes as note, i}
<g transform="translate({dotX(i)}, {20})">
<FretNote {note} />
<text
text-anchor="middle"
dy="25"
font-size="10"
class="text-black dark:text-gray-200"
fill="currentColor">{note.interval}</text>
</g>
{/each}
</svg>
</div>