-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path+page.svelte
More file actions
133 lines (119 loc) · 3.98 KB
/
Copy path+page.svelte
File metadata and controls
133 lines (119 loc) · 3.98 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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<script>
import { tunings } from "../lib";
import frets from "../frets";
import { Scale, Mode } from "tonal";
import TuningSelector from "../lib/TuningSelector.svelte";
import FretBoard from "../lib/FretBoard.svelte";
import KeySelector from "../lib/KeySelector.svelte";
import ScaleSelector from "../lib/ScaleSelector.svelte";
import ScaleChords from "../lib/ScaleChords.svelte";
import ScaleInfo from "../lib/ScaleInfo.svelte";
import SystemSelector from "../lib/SystemSelector.svelte";
import { page } from "$app/stores";
import { goto } from "$app/navigation";
// Read state from URL params with defaults
let tuning = $state($page.url.searchParams.get("tuning") || "Standard");
let key = $state($page.url.searchParams.get("key") || "C");
let scale = $state($page.url.searchParams.get("scale") || "minor pentatonic");
let system = $state($page.url.searchParams.get("system") || "CAGED");
let positionParam = $page.url.searchParams.get("position");
let position = $state(positionParam ? parseInt(positionParam) : null);
let scaleObj = $derived(Scale.get(`${key} ${scale}`));
let fretData = $derived(frets(tunings.get(tuning), 16, scaleObj));
let triads = $derived(Mode.triads(scaleObj.type, scaleObj.tonic));
// Update URL when state changes
function updateURL() {
const params = new URLSearchParams();
params.set("tuning", tuning);
params.set("key", key);
params.set("scale", scale);
params.set("system", system);
if (position) {
params.set("position", position);
}
goto(`?${params.toString()}`, { replaceState: true, noScroll: true });
}
// Watch for state changes and update URL
$effect(() => {
if (scaleObj.intervals?.length === 7) {
system = "CAGED";
}
// Access all reactive values
tuning;
key;
scale;
system;
position;
// Update URL after state changes
updateURL();
});
// Filter fretData based on selected system and position
let filteredFretData = $derived.by(() => {
if (!position || !system) return fretData;
// Check if the current scale has positions for this system
const hasSystemPositions = fretData.strings.some((string) =>
string.some(
(note) => note.positions[system] && note.positions[system].length > 0,
),
);
if (!hasSystemPositions) return fretData;
// Create filtered strings with only notes in the selected position
const filteredStrings = fretData.strings.map((notes) =>
notes.map((note) => {
// Keep the note but mark if it should be in the selected position
// Only show notes that are in the scale AND in the selected position
const isInPosition = note.positions[system]?.includes(position);
return {
...note,
inPosition: isInPosition && !!note.interval, // Only scale notes in this position
};
}),
);
return {
...fretData,
strings: filteredStrings,
};
});
$effect(() => {
console.log("Page state:", {
fretData,
filteredFretData,
tuning,
key,
scale,
system,
position,
scaleIntervals: scaleObj.intervals?.length,
});
});
</script>
<svelte:head>
<title>{key} {scale} Scale</title>
<meta name="Description" content="{key} {scale} scale for guitar" />
</svelte:head>
<div
class="flex bg-gray-50 *:p-5 *:border-r *:border-gray-200 border-b border-gray-300 dark:bg-blue-950 dark:*:border-blue-900 dark:border-blue-900">
<div>
<TuningSelector bind:value={tuning} />
</div>
<div>
<KeySelector bind:value={key} />
</div>
<div>
<ScaleSelector bind:value={scale} />
</div>
<div class="">
<SystemSelector bind:system bind:position />
</div>
<div class="border-r-0">
<ScaleInfo scale={scaleObj} />
</div>
</div>
<div class="p-5 h-72">
<FretBoard fretData={filteredFretData} />
</div>
{#if triads.length > 0}
<div class="relative bg-gray-50 p-5 dark:bg-transparent dark:border-blue-900">
<ScaleChords scale={scaleObj} />
</div>
{/if}