From b411b7a822dafe4b6442717327c2953e22965609 Mon Sep 17 00:00:00 2001 From: jermspeaks Date: Mon, 4 Mar 2024 10:57:08 -0800 Subject: [PATCH 1/4] Add fretboard --- src/components/lib/GuitarFingering.svelte | 202 +++++++++++++++++++--- 1 file changed, 177 insertions(+), 25 deletions(-) diff --git a/src/components/lib/GuitarFingering.svelte b/src/components/lib/GuitarFingering.svelte index 3c76dd1f..dbdad156 100644 --- a/src/components/lib/GuitarFingering.svelte +++ b/src/components/lib/GuitarFingering.svelte @@ -67,37 +67,84 @@ "sus4", ]; - // let chords = Object.keys(chordData); - // let search = ""; - // let suggestions = []; - let selectedNote = ""; let selectedOption = ""; - // let selectedChord = null; - let fingerings = []; - - // function onChange(event) { - // selectedNote = event.currentTarget.value; - // console.log("selectedNote", selectedNote); + let selectedVariation = 0; - // const chord = `${selectedNote}`; - // selectedChord = chordData?.[chord]; - // // fingerings = selectedChord.map((fingering) => fingering.p); - // } + function onNoteChange(event) { + // const nextNote = event.currentTarget.value; + if (selectedVariation !== 0) { + selectedVariation = 0; + } - // const selectChord = (chordName) => { - // search = chordName; - // selectedChord = chordData[chordName]; - // }; + return event; + } $: selectedPositionsAndFingerings = chordData?.[`${selectedNote}${selectedOption}`]; - // $: fingerings = Array.isArray(selectedPositionsAndFingerings) - // ? selectedPositionsAndFingerings.map((fingering) => fingering?.f) - // : []; - // $: frets = Array.isArray(selectedPositionsAndFingerings) - // ? selectedPositionsAndFingerings.map((fingering) => fingering?.p) - // : []; + + // Constants for the SVG rendering + const numberOfStrings = 6; + const numberOfFrets = 21; + const stringSpacing = 20; // Vertical space between strings + const fretSpacing = 40; // Horizontal space between frets + const fretboardWidth = (numberOfFrets + 1) * fretSpacing + 2 * stringSpacing; + const fretboardHeight = (numberOfStrings - 1) * stringSpacing; + + const getFingerPosition = (string, fret) => { + return { + cx: fret * fretSpacing - fretSpacing / 2, // x position + cy: (numberOfStrings - string) * stringSpacing, // y position + r: 8, // radius of the circle + }; + }; + + const getTextPosition = (string, fret) => { + return { + x: fret * fretSpacing - fretSpacing / 2, // x position - text width + y: (numberOfStrings - string) * stringSpacing + 5, // y position + 1/2 text size + }; + }; + + const parseFretPositions = (fretAndPosition = {}) => { + const { f: fingerPosition, p: fretPosition } = fretAndPosition; + + // Edge Case: if the fingering includes a semicolon, there are alternative fingerings. + // We need to account for that + + // Positions are delimited by commas like this "4,6,6,5,4,4" + // Fingering is delimited by single numbers, like "134211" + // For each string, determine the fingering and the fret position + // Some fingering omits the finger positions where position === x since + // there is no fingering there, so you can't rely on index + const fingerPositions = fingerPosition.split(""); + const fretPositions = fretPosition.split(","); + + let stringIndex = 0; + const map = fretPositions.map((fret, i) => { + let finalFingerAndPosition = {}; + if (fret === "x") { + finalFingerAndPosition = { + text: "", + fret: "x", + }; + } else if (fret === "0") { + finalFingerAndPosition = { + text: "", + fret: 0, + }; + } else { + finalFingerAndPosition = { + text: fingerPositions[stringIndex], + fret: parseInt(fret, 10), + }; + stringIndex++; + } + + return finalFingerAndPosition; + }); + return map; + }; onMount(() => { searchChords(); @@ -116,6 +163,7 @@ name="note" bind:group={selectedNote} value={note} + on:change={onNoteChange} />