summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@spork.org>2025-03-09 16:50:07 -0400
committerBrian Cully <bjc@spork.org>2025-03-09 16:50:07 -0400
commit53631ad1ef5497017f00f56608649e9bee90b264 (patch)
tree5099a928f2cbecc2c708bedc929042c60a4ad563
parent45c8b61f2c55a4534e7069c1febc36bf5709fccd (diff)
downloadchords-53631ad1ef5497017f00f56608649e9bee90b264.tar.gz
chords-53631ad1ef5497017f00f56608649e9bee90b264.zip
add display for available chords in the key
-rw-r--r--index.html18
-rw-r--r--key-picker.mjs25
-rw-r--r--main.css11
-rw-r--r--scale.mjs1
4 files changed, 52 insertions, 3 deletions
diff --git a/index.html b/index.html
index aa2c60a..055fdcb 100644
--- a/index.html
+++ b/index.html
@@ -101,12 +101,17 @@
<label for='tonic'>tonic:</label>
<select id='tonic' name='tonic'>
<option value='A'>A</option>
+ <option value='A#'>A#</option>
<option value='B'>B</option>
<option value='C' selected>C</option>
+ <option value='C#'>C#</option>
<option value='D'>D</option>
+ <option value='D#'>D#</option>
<option value='E'>E</option>
<option value='F'>F</option>
+ <option value='F#'>F#</option>
<option value='G'>G</option>
+ <option value='G#'>G#</option>
</select>
<label for='diatonic'>diatonic:</label>
<select id='diatonic' name='diatonic'>
@@ -117,7 +122,7 @@
<hr>
<ol class='notes'>
- <li class='first'>C</li>
+ <li class='tonic'>C</li>
<li class='second'>D</li>
<li class='third'>E</li>
<li class='fourth'>F</li>
@@ -125,6 +130,17 @@
<li class='sixth'>A</li>
<li class='seventh'>B</li>
</ol>
+ <hr>
+
+ <p>Available chords:</p>
+ <ul class='chords'>
+ <li>Amin</li>
+ <li>C</li>
+ <li>Dmin</li>
+ <li>Emin</li>
+ <li>F</li>
+ <li>G</li>
+ </ul>
</fieldset>
</form>
diff --git a/key-picker.mjs b/key-picker.mjs
index bd6482a..fc6b4ed 100644
--- a/key-picker.mjs
+++ b/key-picker.mjs
@@ -14,9 +14,32 @@ function scaleFrom(tonic, diatonic) {
function formChanged(form) {
const formData = new FormData(form);
const scale = scaleFrom(formData.get('tonic'), formData.get('diatonic'));
- ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh'].forEach((c, i) => {
+ ['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 ? '' : 'min';
+ 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) {
diff --git a/main.css b/main.css
index 77b282a..49f3ba3 100644
--- a/main.css
+++ b/main.css
@@ -67,3 +67,14 @@ body {
counter-increment: notes;
text-align: center;
}
+
+#key-picker .chords {
+ display: grid;
+ grid-template-rows: 1;
+ grid-template-columns: 4em 4em 4em 4em 4em 4em;
+ padding-left: 0;
+}
+
+#key-picker .chords li {
+ display: grid;
+}
diff --git a/scale.mjs b/scale.mjs
index 045265b..9e0e122 100644
--- a/scale.mjs
+++ b/scale.mjs
@@ -61,7 +61,6 @@ class Scale {
}
get length() {
- console.debug(`get length`, this.scale.length);
return this.scale.length;
}