import { getPentatonicScale, getFullScale, getChordTones, NOTES } from '../lib/theory' // Standard tuning: pitch classes of open strings, high-E first (top of diagram) const STRINGS = [ { label: 'e', root: 4 }, // high E { label: 'B', root: 11 }, { label: 'G', root: 7 }, { label: 'D', root: 2 }, { label: 'A', root: 9 }, { label: 'E', root: 4 }, // low E ] const NUM_FRETS = 13 // frets 0 (open) through 12 const FRET_MARKERS = [3, 5, 7, 9] const DOUBLE_MARKER = 12 // Layout constants const NUT_X = 40 // x of the nut line const OPEN_X = 18 // x of open-string dot centres const FRET_W = 52 // pixels per fret const STRING_H = 28 // pixels between strings const PAD_T = 28 // top padding (fret numbers) const PAD_B = 18 // bottom padding (fret marker dots) const BOARD_W = NUT_X + (NUM_FRETS - 1) * FRET_W + 10 const BOARD_H = PAD_T + 5 * STRING_H + PAD_B const DOT_R = 10 // x centre of a fretted note (fret >= 1) const fretX = f => NUT_X + (f - 0.5) * FRET_W // y centre of string si (0 = high e, 5 = low E) const stringY = si => PAD_T + si * STRING_H function noteColor(isChordTone, isPenta, isScale, mono = false) { if (isChordTone) return { fill: '#a855f7', text: '#fff' } if (isPenta) return mono ? { fill: '#c084fc', text: '#1e1b4b' } : { fill: '#f59e0b', text: '#000' } if (isScale) return mono ? { fill: '#e9d5ff', text: '#581c87' } : { fill: '#374151', text: '#d1d5db' } return null } export default function Fretboard({ keyInfo, currentChord, pentatonicOnly = false, monoColor = false }) { const { root, mode } = keyInfo ?? {} if (!root) return null const pentaSet = new Set(getPentatonicScale(root, mode).map(n => NOTES.indexOf(n))) const scaleSet = pentatonicOnly ? pentaSet : new Set(getFullScale(root, mode).map(n => NOTES.indexOf(n))) const chordSet = currentChord ? new Set(getChordTones(currentChord).map(n => NOTES.indexOf(n))) : new Set() return (
Fretboard — {root} {mode} {currentChord && / {currentChord}}