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
|
import { MajorScale, MinorScale, chromaticScale } from "./scale.mjs";
function scaleFrom(tonic, scale) {
switch (scale) {
case 'major':
return MajorScale(tonic);
case 'minor':
return MinorScale(tonic);
default:
throw new Error('how this happen')
}
}
function handleNoteEnter(e) {
const n = e.target.innerText;
// todo: this should be delegated. the key selector shouldn't know
// about the fretboard at all.
document.querySelectorAll(`#fretboard [x-data-note="${n}"]`).forEach(elt => {
console.debug('wow! found elt', elt);
elt.classList.add('hover');
})
}
function handleNoteLeave(e) {
const n = e.target.innerText;
// ibid.
document.querySelectorAll(`#fretboard [x-data-note="${n}"]`).forEach(elt => {
console.debug('wow! found elt', elt);
elt.classList.remove('hover');
})
}
function formChanged(form) {
const formData = new FormData(form);
const scale = scaleFrom(formData.get('tonic'), formData.get('scale'));
['tonic', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh'].forEach((c, i) => {
Array.from(form.getElementsByClassName(c)).forEach(elt => elt.innerText = scale[i]);
});
// todo: memoize this or put it in the scales module.
const allScales = chromaticScale.flatMap(tonic => {
return [MajorScale(tonic), MinorScale(tonic)];
})
const availableScales =
allScales.reduce((acc, s, i) => {
const suffix = i % 2 == 0 ? '' : 'm';
if (scale.includes(s.tonic) && scale.includes(s.third) && scale.includes(s.fifth)) {
return acc.concat(`${s.tonic}${suffix}`);
}
return acc;
}, []);
Array.from(form.getElementsByClassName('chords')).forEach(list => {
const items = availableScales.map(s => {
const elt = document.createElement('li');
elt.innerText = s;
return elt;
});
list.replaceChildren();
items.forEach(item => list.appendChild(item));
});
}
function handleFormChanged(e) {
formChanged(e.target.form);
}
export default function KeyPicker(form) {
console.debug('KeyPicker()', form);
form.onchange = handleFormChanged;
formChanged(form);
}
|