import { chromaticScale } from "./scale.mjs"; const strings = { string1: 'E', string2: 'A', string3: 'D', string4: 'G', string5: 'B', string6: 'E' }; function isAccidental(note) { return note[1] === '#' || note[1] === 'b'; } function alternateAccidental(note) { const root = chromaticScale.indexOf(note[0]); switch (note[1]) { case '#': return `${chromaticScale[root+2]}b`; case 'b': return `${chromaticScale[root-1]}#`; default: return note; } } function fretToNote(stringName, fretName) { console.debug('fretToNote', stringName, fretName); const string = strings[stringName]; if (!string) { return null; } if (!fretName?.startsWith('fret')) { return string; } const root = chromaticScale.indexOf(string) const fret = Number(fretName.substring(4)); console.debug('root', root, 'fret', fret); return chromaticScale[root+fret]; } function formChanged(form) { console.log('form changed', form); const formData = new FormData(form); console.log('form', formData); form.querySelectorAll('p').forEach(p => { const val = formData.get(p.className) console.debug('found sel', val, p.className, formData); const note = fretToNote(p.className, val); if (isAccidental(note)) { p.innerText = `${note} / ${alternateAccidental(note)}`; } else { p.innerText = note; } }); } function handleFormChanged(e) { console.log('handle form changed', e); formChanged(e.target.form); } let mousedownVal = undefined; function mousedown(e) { // at mousedown time, the form hasn't yet been changed. to support // deselecting elements, we need to know what the previous // selection was, so store it here. // // it'd be nice to be able to do this just in the click handler. mousedownVal = e.target.checked; } function click(e) { const elt = e.target; // if this element was selected at mousedown time, deselect it // now. if (mousedownVal) { elt.checked = false; } } export default function Fretboard(form) { console.debug('Fretboard()', form); form.onchange = handleFormChanged; form.querySelectorAll('input[type="radio"]').forEach(elt => { elt.onmousedown = mousedown; elt.onclick = click; }); formChanged(form); }