summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@spork.org>2025-07-28 09:48:56 -0400
committerBrian Cully <bjc@spork.org>2025-07-28 09:48:56 -0400
commit636c18b9640733ffab9d9bb35fa7753a7d1903a3 (patch)
tree41ff4e9ae046bb39b7f8dabb061fe54f5cc2c08a
parent77f5e81d0a1adc497040eaa89095635f3de3924e (diff)
downloadchords-636c18b9640733ffab9d9bb35fa7753a7d1903a3.tar.gz
chords-636c18b9640733ffab9d9bb35fa7753a7d1903a3.zip
put key picker note hover back
-rw-r--r--key-picker.mjs54
-rw-r--r--main.mjs38
2 files changed, 60 insertions, 32 deletions
diff --git a/key-picker.mjs b/key-picker.mjs
index b3f871c..53c089f 100644
--- a/key-picker.mjs
+++ b/key-picker.mjs
@@ -15,27 +15,6 @@ function scaleFrom(tonic, scale) {
}
}
-function handleNoteEnter(e) {
- const elt = e.target;
- const n = Note.fromString(elt.textContent).toString();
- // todo: this should be delegated. the key selector shouldn't know
- // about the fretboard at all.
- elt.classList.add('hover');
- document.querySelectorAll(`#fretboard [x-data-note="${n}"]`).forEach(elt => {
- elt.classList.add('hover');
- })
-}
-
-function handleNoteLeave(e) {
- const elt = e.target;
- const n = Note.fromString(elt.textContent).toString();
- // ibid.
- elt.classList.remove('hover');
- document.querySelectorAll(`#fretboard [x-data-note="${n}"]`).forEach(elt => {
- elt.classList.remove('hover');
- })
-}
-
function noteClicked(elt, justClear=false) {
const n = Note.fromString(elt.textContent).toString();
const count = Number(elt.getAttribute('x-data-clicked')) || 0;
@@ -114,6 +93,9 @@ export default class extends HTMLElement {
customElements.define(this.name, this);
}
+ noteEnterEvent = 'x-key-picker-note-enter'
+ noteLeaveEvent = 'x-key-picker-note-leave'
+
constructor() {
super();
@@ -128,12 +110,38 @@ export default class extends HTMLElement {
const form = this.querySelector('form');
form.onchange = handleFormChanged;
form.querySelectorAll('.notes li').forEach(elt => {
- elt.onmouseenter = handleNoteEnter;
- elt.onmouseleave = handleNoteLeave;
+ elt.onmouseenter = this.handleNoteEnter.bind(this);
+ elt.onmouseleave = this.handleNoteLeave.bind(this);
elt.onclick = handleNoteClick;
});
formChanged(form);
console.log('bjc', 'Cdim', DiminishedScale('C').toString());
}
+
+ handleNoteEnter(e) {
+ const elt = e.target;
+ const note = Note.fromString(elt.textContent)
+ elt.classList.add('hover');
+
+ const event = new CustomEvent(this.noteEnterEvent, {
+ bubbles: true,
+ cancelable: true,
+ detail: note
+ });
+ this.dispatchEvent(event);
+ }
+
+ handleNoteLeave(e) {
+ const elt = e.target;
+ const note = Note.fromString(elt.textContent)
+ elt.classList.remove('hover');
+
+ const event = new CustomEvent(this.noteLeaveEvent, {
+ bubbles: true,
+ cancelable: true,
+ detail: note
+ });
+ this.dispatchEvent(event);
+ }
}
diff --git a/main.mjs b/main.mjs
index 6c71e9c..9aa4dd2 100644
--- a/main.mjs
+++ b/main.mjs
@@ -5,30 +5,31 @@ import String from './string.mjs';
import Player from './player.mjs';
import { Note, toCents } from './scale.mjs';
+// assume A440 tuning
+const noteA = Note.fromString('A');
let player = undefined;
-function save(e) {
+function save({ detail }) {
document.querySelectorAll(History.name).forEach(h => {
- console.debug('h is', h, 'e is', e.detail);
- h.add(e.detail);
+ console.debug('h is', h, 'e is', detail);
+ h.add(detail);
});
}
-function play(e) {
- console.debug('got playEvent', e, e.detail.notes);
+function play({ detail }) {
+ console.debug('got playEvent', detail.notes);
if (player) {
player.stop();
}
- const played = e.detail.notes.map((n, i) => {
+ const played = detail.notes.map((n, i) => {
if (n !== 'x') {
- return [Note.fromString(n), e.detail.octaves[i]];
+ return [Note.fromString(n), detail.octaves[i]];
}
}).filter(n => n);
- const a = Note.fromString('A');
player = new Player(played.map(([n, o]) => {
- return toCents([a, 4], [n, o]);
+ return toCents([noteA, 4], [n, o]);
}));
player.start();
}
@@ -40,6 +41,20 @@ function stop(e) {
}
}
+function noteEnter({ detail }) {
+ console.debug('got noteEnter', detail);
+ Array.from(document.querySelectorAll(`.fret [value='${detail.toString()}']`))
+ .map(f => f.parentNode)
+ .forEach(f => f.classList.add('hover'));
+}
+
+function noteLeave({ detail }) {
+ console.debug('got noteLeave', detail);
+ Array.from(document.querySelectorAll(`.fret [value='${detail.toString()}']`))
+ .map(f => f.parentNode)
+ .forEach(f => f.classList.remove('hover'));
+}
+
function init() {
console.debug('init()', this);
@@ -54,5 +69,10 @@ function init() {
f.addEventListener(f.playEvent, play);
f.addEventListener(f.stopEvent, stop);
});
+
+ document.querySelectorAll(KeyPicker.name).forEach(kp => {
+ kp.addEventListener(kp.noteEnterEvent, noteEnter);
+ kp.addEventListener(kp.noteLeaveEvent, noteLeave);
+ })
}
document.addEventListener('DOMContentLoaded', init);