add mono color
This commit is contained in:
+13
-2
@@ -45,6 +45,7 @@ export default function App() {
|
||||
const [instrument, setInstrument] = useState('guitar') // 'guitar' | 'piano'
|
||||
const [showTuner, setShowTuner] = useState(false)
|
||||
const [showDebug, setShowDebug] = useState(false)
|
||||
const [monoColor, setMonoColor] = useState(false)
|
||||
|
||||
// ── Mic permission error ──────────────────────────────────────────────────────
|
||||
const [micError, setMicError] = useState(null)
|
||||
@@ -306,6 +307,16 @@ export default function App() {
|
||||
<p className="text-xs text-gray-600">Real-time key detection for live jams</p>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center">
|
||||
<button
|
||||
onClick={() => setMonoColor(v => !v)}
|
||||
className={`p-2 rounded-full border transition-all ${monoColor ? 'border-accent bg-accent/10' : 'border-border hover:border-gray-400'}`}
|
||||
title="Mono color mode"
|
||||
>
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" style={{ opacity: 0.75 }}>
|
||||
<circle cx="6" cy="10" r="4" fill={monoColor ? '#a855f7' : '#a855f7'} />
|
||||
<circle cx="13" cy="10" r="4" fill={monoColor ? '#c084fc' : '#f59e0b'} />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setShowDebug(v => !v)}
|
||||
className={`p-2 rounded-full border transition-all ${showDebug ? 'border-accent bg-accent/10' : 'border-border hover:border-gray-400'}`}
|
||||
@@ -474,8 +485,8 @@ export default function App() {
|
||||
<div className="flex gap-3 mb-3 items-stretch">
|
||||
<div className="w-full lg:w-[70%] min-w-0">
|
||||
{instrument === 'guitar'
|
||||
? <Fretboard keyInfo={effectiveKey} currentChord={currentChord} pentatonicOnly={false} />
|
||||
: <Piano keyInfo={effectiveKey} currentChord={currentChord} />
|
||||
? <Fretboard keyInfo={effectiveKey} currentChord={currentChord} pentatonicOnly={false} monoColor={monoColor} />
|
||||
: <Piano keyInfo={effectiveKey} currentChord={currentChord} monoColor={monoColor} />
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -30,14 +30,14 @@ 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) {
|
||||
if (isChordTone) return { fill: '#a855f7', text: '#fff' } // purple
|
||||
if (isPenta) return { fill: '#f59e0b', text: '#000' } // amber
|
||||
if (isScale) return { fill: '#374151', text: '#d1d5db' } // grey
|
||||
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 }) {
|
||||
export default function Fretboard({ keyInfo, currentChord, pentatonicOnly = false, monoColor = false }) {
|
||||
const { root, mode } = keyInfo ?? {}
|
||||
|
||||
if (!root) return null
|
||||
@@ -120,7 +120,7 @@ export default function Fretboard({ keyInfo, currentChord, pentatonicOnly = fals
|
||||
{STRINGS.flatMap((str, si) =>
|
||||
Array.from({ length: NUM_FRETS }, (_, fi) => {
|
||||
const pc = (str.root + fi) % 12
|
||||
const color = noteColor(chordSet.has(pc), pentaSet.has(pc), scaleSet.has(pc))
|
||||
const color = noteColor(chordSet.has(pc), pentaSet.has(pc), scaleSet.has(pc), monoColor)
|
||||
if (!color) return null
|
||||
|
||||
const cx = fi === 0 ? OPEN_X : fretX(fi)
|
||||
@@ -147,8 +147,8 @@ export default function Fretboard({ keyInfo, currentChord, pentatonicOnly = fals
|
||||
|
||||
<div className="mt-3 flex gap-5 text-xs text-gray-500">
|
||||
<span><span className="text-accent">●</span> Chord tone</span>
|
||||
<span><span className="text-amber-400">●</span> Pentatonic</span>
|
||||
<span><span className="text-gray-500">●</span> Scale</span>
|
||||
<span style={{ color: monoColor ? '#c084fc' : '#f59e0b' }}>●</span><span> Pentatonic</span>
|
||||
<span style={{ color: monoColor ? '#e9d5ff' : '#6b7280' }}>●</span><span> Scale</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -28,16 +28,16 @@ const BLACK_H = 82 // black key height
|
||||
const LABEL_Y = KEY_H - 10 // y of note label on white key
|
||||
const BLACK_LABEL_Y = BLACK_H - 8
|
||||
|
||||
function keyColor(isChordTone, isPenta, isScale, isBlack) {
|
||||
function keyColor(isChordTone, isPenta, isScale, isBlack, mono = false) {
|
||||
if (isChordTone) return { fill: '#a855f7', text: '#fff' }
|
||||
if (isPenta) return { fill: '#f59e0b', text: '#000' }
|
||||
if (isScale) return { fill: '#374151', text: '#d1d5db' }
|
||||
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 isBlack
|
||||
? { fill: '#1f1f1f', text: '#6b7280' }
|
||||
: { fill: '#f5f5f5', text: '#6b7280' }
|
||||
}
|
||||
|
||||
export default function Piano({ keyInfo, currentChord }) {
|
||||
export default function Piano({ keyInfo, currentChord, monoColor = false }) {
|
||||
const { root, mode } = keyInfo ?? {}
|
||||
if (!root) return null
|
||||
|
||||
@@ -68,7 +68,7 @@ export default function Piano({ keyInfo, currentChord }) {
|
||||
const isChordTone = chordSet.has(k.pc)
|
||||
const isPenta = pentaSet.has(k.pc)
|
||||
const isScale = scaleSet.has(k.pc)
|
||||
const { fill, text } = keyColor(isChordTone, isPenta, isScale, false)
|
||||
const { fill, text } = keyColor(isChordTone, isPenta, isScale, false, monoColor)
|
||||
return (
|
||||
<g key={`w-${oct}-${wi}`}>
|
||||
<rect
|
||||
@@ -102,7 +102,7 @@ export default function Piano({ keyInfo, currentChord }) {
|
||||
const isChordTone = chordSet.has(k.pc)
|
||||
const isPenta = pentaSet.has(k.pc)
|
||||
const isScale = scaleSet.has(k.pc)
|
||||
const { fill, text } = keyColor(isChordTone, isPenta, isScale, true)
|
||||
const { fill, text } = keyColor(isChordTone, isPenta, isScale, true, monoColor)
|
||||
return (
|
||||
<g key={`b-${oct}-${bi}`}>
|
||||
<rect
|
||||
@@ -134,8 +134,8 @@ export default function Piano({ keyInfo, currentChord }) {
|
||||
|
||||
<div className="mt-3 flex gap-5 text-xs text-gray-500">
|
||||
<span><span className="text-accent">●</span> Chord tone</span>
|
||||
<span><span className="text-amber-400">●</span> Pentatonic</span>
|
||||
<span><span className="text-gray-500">●</span> Scale</span>
|
||||
<span><span style={{ color: monoColor ? '#c084fc' : '#f59e0b' }}>●</span> Pentatonic</span>
|
||||
<span><span style={{ color: monoColor ? '#e9d5ff' : '#6b7280' }}>●</span> Scale</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user