mirror of
https://github.com/9x/sheetmusictrainer.git
synced 2026-09-02 09:34:33 +02:00
Improve virtual guitar UX
This commit is contained in:
10
src/App.css
10
src/App.css
@@ -336,6 +336,16 @@ button {
|
|||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hint-button.active {
|
||||||
|
background-color: var(--color-primary);
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 4px 12px rgba(var(--hue-primary), 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint-button.active:hover {
|
||||||
|
background-color: var(--color-primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
.zen-button {
|
.zen-button {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: 2px solid var(--color-text-muted);
|
border: 2px solid var(--color-text-muted);
|
||||||
|
|||||||
32
src/App.tsx
32
src/App.tsx
@@ -57,6 +57,7 @@ function App() {
|
|||||||
const [matchStartTime, setMatchStartTime] = useState<number | null>(null);
|
const [matchStartTime, setMatchStartTime] = useState<number | null>(null);
|
||||||
const [feedbackMessage, setFeedbackMessage] = useState<string>("");
|
const [feedbackMessage, setFeedbackMessage] = useState<string>("");
|
||||||
const [revealed, setRevealed] = useState(false);
|
const [revealed, setRevealed] = useState(false);
|
||||||
|
const [virtualNote, setVirtualNote] = useState<number | null>(null);
|
||||||
|
|
||||||
const currentTuning = TUNINGS[settings.tuningId];
|
const currentTuning = TUNINGS[settings.tuningId];
|
||||||
const currentInstrumentDef = INSTRUMENT_DEFINITIONS[settings.instrument];
|
const currentInstrumentDef = INSTRUMENT_DEFINITIONS[settings.instrument];
|
||||||
@@ -233,6 +234,12 @@ function App() {
|
|||||||
// Virtual Guitar Handler
|
// Virtual Guitar Handler
|
||||||
const handleVirtualGuitarPlay = useCallback((playedMidi: number) => {
|
const handleVirtualGuitarPlay = useCallback((playedMidi: number) => {
|
||||||
playNote(playedMidi, 0.5); // Feedback sound
|
playNote(playedMidi, 0.5); // Feedback sound
|
||||||
|
setVirtualNote(playedMidi);
|
||||||
|
|
||||||
|
// Clear the note visualization after a short delay
|
||||||
|
setTimeout(() => {
|
||||||
|
setVirtualNote(null);
|
||||||
|
}, 500);
|
||||||
|
|
||||||
if (playedMidi === targetMidi) {
|
if (playedMidi === targetMidi) {
|
||||||
// Instant match
|
// Instant match
|
||||||
@@ -378,11 +385,11 @@ function App() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<main className="main-stage">
|
<main className="main-stage">
|
||||||
<div className={`card sheet-music-card ${settings.showHint ? 'has-hint' : ''} ${settings.zenMode ? 'zen-mode' : ''}`}>
|
<div className={`card sheet-music-card ${(settings.showHint || settings.showFretboard) ? 'has-hint' : ''} ${settings.zenMode ? 'zen-mode' : ''}`}>
|
||||||
<div className="sheet-music-container">
|
<div className="sheet-music-container">
|
||||||
<SheetMusic
|
<SheetMusic
|
||||||
targetMidi={targetMidi}
|
targetMidi={targetMidi}
|
||||||
playedMidi={pitchData?.midi}
|
playedMidi={virtualNote ?? pitchData?.midi}
|
||||||
keySignature={settings.keySignature}
|
keySignature={settings.keySignature}
|
||||||
clef={currentInstrumentDef.clefMode}
|
clef={currentInstrumentDef.clefMode}
|
||||||
transpose={currentInstrumentDef.transpose}
|
transpose={currentInstrumentDef.transpose}
|
||||||
@@ -420,6 +427,7 @@ function App() {
|
|||||||
interactive={settings.showFretboard}
|
interactive={settings.showFretboard}
|
||||||
onPlayNote={handleVirtualGuitarPlay}
|
onPlayNote={handleVirtualGuitarPlay}
|
||||||
showHints={settings.showHint}
|
showHints={settings.showHint}
|
||||||
|
maxFrets={15}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -429,15 +437,7 @@ function App() {
|
|||||||
|
|
||||||
{!settings.zenMode && (
|
{!settings.zenMode && (
|
||||||
<div className="action-row" style={{ marginTop: '24px', display: 'flex', justifyContent: 'center', gap: '16px' }}>
|
<div className="action-row" style={{ marginTop: '24px', display: 'flex', justifyContent: 'center', gap: '16px' }}>
|
||||||
<button
|
{currentInstrumentDef.showTuning && (
|
||||||
className={`hint-button ${settings.showHint ? 'active' : ''}`}
|
|
||||||
onClick={() => setSettings(s => ({ ...s, showHint: !s.showHint }))}
|
|
||||||
title="Keyboard Shortcut: H"
|
|
||||||
>
|
|
||||||
<HelpCircle size={18} />
|
|
||||||
{settings.showHint ? "Hide Hint" : "Show Hint"}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={`hint-button ${settings.showFretboard ? 'active' : ''}`}
|
className={`hint-button ${settings.showFretboard ? 'active' : ''}`}
|
||||||
onClick={() => setSettings(s => ({ ...s, showFretboard: !s.showFretboard }))}
|
onClick={() => setSettings(s => ({ ...s, showFretboard: !s.showFretboard }))}
|
||||||
@@ -446,6 +446,16 @@ function App() {
|
|||||||
<Guitar size={18} />
|
<Guitar size={18} />
|
||||||
Guitar
|
Guitar
|
||||||
</button>
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<button
|
||||||
|
className={`hint-button ${settings.showHint ? 'active' : ''}`}
|
||||||
|
onClick={() => setSettings(s => ({ ...s, showHint: !s.showHint }))}
|
||||||
|
title="Keyboard Shortcut: H"
|
||||||
|
>
|
||||||
|
<HelpCircle size={18} />
|
||||||
|
{settings.showHint ? "Hide Hint" : "Show Hint"}
|
||||||
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className="hint-button"
|
className="hint-button"
|
||||||
|
|||||||
Reference in New Issue
Block a user