diff --git a/index.html b/index.html index b154d32..e1c871d 100644 --- a/index.html +++ b/index.html @@ -382,77 +382,75 @@ function SongPlayer({ parts, detected, listening, onStartMic }) { useEffect(()=>()=>{ if(timerRef.current) clearTimeout(timerRef.current); },[]); - const NUM_FRETS=6, NS=6, W=320, H=260; - const TOP=44, BOT=H-24, LEFT=44, RIGHT=W-12; + const NS=6, H=260; + const TOP=44, BOT=H-24, LEFT=44; const strGap=(BOT-TOP)/(NS-1); - const fretGap=(RIGHT-LEFT)/NUM_FRETS; const renderFretboard = (pIdx) => { const pNotes = (allParts[pIdx]||{}).notes||[]; + const N = pNotes.length || 1; + const W = Math.max(320, LEFT + N*52 + 20); + const noteX = (ni) => LEFT + ni*52 + 26; + return ( - - - {Array.from({length:NUM_FRETS+1},(_,f)=>( - - ))} + + + {/* Strings */} {Array.from({length:NS},(_,s)=>( - + ))} + {/* String labels */} {STRING_NAMES.map((n,s)=>( - {n} ))} - {Array.from({length:NUM_FRETS},(_,f)=>( - {f+1} + {/* Vertical beat lines */} + {pNotes.map((_,ni)=>( + ))} + {/* Notes - left to right timeline */} {pNotes.map((note,ni)=>{ const p = NOTE_FRET_MAP[note]; if(!p) return null; const isOpen = p.fret===0; - const baseX = isOpen ? LEFT+0.5*fretGap : LEFT+(p.fret-0.5)*fretGap; - const baseY = TOP+p.str*strGap; - const sameSpot = pNotes.slice(0,ni).filter(n2=>{ - const q=NOTE_FRET_MAP[n2]; return q&&q.fret===p.fret&&q.str===p.str; - }).length; - const cx = baseX + sameSpot*32; - const cy = baseY; + const cx = noteX(ni); + const cy = TOP+p.str*strGap; const stateKey = pIdx+"-"+ni; const state = dotStates[stateKey]; const isCur = active && state==="cur"; const isHit = state==="hit"; const isMiss = state==="miss"; - const fill = isHit?C.sage:isMiss?C.coral:isCur?C.amber:C.amber; + const fill = isHit?C.sage:isMiss?C.coral:C.amber; const opacity = isHit||isCur||isMiss?1:0.7; return ( - + {!isOpen && ( - - {ni+1} - - )} - {isOpen && (isHit||isCur) && ( - - 0 + {p.fret} )} + {/* Fret label below dot */} + + {isOpen?"0":p.fret} + {isCur && ( - 🎸 + 🎸 )} ); })} + ); };