Skip to content

Commit

Permalink
Refactor DegreeTrainerSettings component for ear trainer page
Browse files Browse the repository at this point in the history
  • Loading branch information
Zilong-L committed Aug 27, 2024
1 parent 150ed6d commit 46033c2
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 60 deletions.
8 changes: 3 additions & 5 deletions src/Components/EarTrainers/DegreeTrainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ const EarTrainer = () => {
const newNote = generateRandomNoteBasedOnRoot();
setCurrentNote(newNote);

if(gameStarted){
playNote(newNote,1)
}
},[possibleMidiList])
useEffect(() => {
console.log(range)
Expand Down Expand Up @@ -225,19 +222,20 @@ const EarTrainer = () => {
setRange={setRange}
currentNotes={currentNotes}
setCurrentNotes={setCurrentNotes}
playNote={playNote}
/>
{!gameStarted ? (
<Button
variant="contained"
color="primary"
onClick={startGame}
sx={{ height: '30vh', marginTop: 'auto', marginBottom: '1rem' }}
sx={{ height: '30vh', marginTop: 'auto', marginBottom: '2rem' }}
fullWidth
>
<Typography variant='h2'>开始</Typography>
</Button>
) : (
<Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', height: '100%' }}>
<Box sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', height: '100%',marginBottom:'2rem' }}>
<Box sx={{ flexGrow: 1 }} /> {/* 这个空的 Box 会推动下面的内容到底部 */}
<Grid container spacing={2} sx={{ marginBottom: '1rem' }}>
{filteredNotes.map((note) => (
Expand Down
140 changes: 85 additions & 55 deletions src/Components/EarTrainers/DegreeTrainerSettings.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { Modal, Box, Button, Slider, Checkbox, Typography, Grid } from '@mui/material';
import { getPianoInstance, getDroneInstance } from '@components/ToneInstance';
import HomeIcon from '@mui/icons-material/Home';
import * as Tone from 'tone';

function DegreeTrainerSettings({
Expand All @@ -17,9 +18,11 @@ function DegreeTrainerSettings({
range,
setRange,
currentNotes,
setCurrentNotes
setCurrentNotes,
playNote
}) {
const [showDegreeSettings, setShowDegreeSettings] = useState(false);
const [showVolumeSettings, setShowVolumeSettings] = useState(false);
const drone = getDroneInstance();
const piano = getPianoInstance();
let midiMin = drone.rootMin;
Expand All @@ -30,7 +33,13 @@ function DegreeTrainerSettings({
newNotes[index].enable = !newNotes[index].enable;
setCurrentNotes(newNotes);
};
const closeSettings = () => { setIsSettingsOpen(false); setShowDegreeSettings(false) }

const closeSettings = () => {
setIsSettingsOpen(false);
setShowDegreeSettings(false);
setShowVolumeSettings(false);
playNote();
};

return (
<Modal open={isSettingsOpen} onClose={closeSettings}>
Expand All @@ -40,7 +49,8 @@ function DegreeTrainerSettings({
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 300,
width: '80%',
maxWidth: 500,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
Expand All @@ -50,25 +60,33 @@ function DegreeTrainerSettings({
overflowY: 'auto',
}}
>
<h2>设置</h2>
<h2 style={{ fontSize: '2rem', textAlign: 'center' }}>设置</h2>

{!showDegreeSettings ? (
{!showDegreeSettings && !showVolumeSettings ? (
<>
<Button sx={{display:'block'}} color='secondary' onClick={() => setShowDegreeSettings(true)}>选择练习级数</Button>
<div style={{ padding: '6px 8px' }}>
<label>BPM: </label>
<Slider color='secondary' value={bpm} onChange={(e, value) => setBpm(value)} min={40} max={200} valueLabelDisplay="auto" />
</div>
<div style={{ padding: '6px 8px' }}>
<label id="note-range-slider" >
<Button sx={{ display: 'block', fontSize: '1.5rem', width: '100%', textAlign: 'left', marginBottom: '1rem' }} color='secondary' onClick={() => setShowDegreeSettings(true)}>
练习设置
</Button>
<Button sx={{ display: 'block', fontSize: '1.5rem', width: '100%', textAlign: 'left' }} color='secondary' onClick={() => setShowVolumeSettings(true)}>
音量设置
</Button>
</>
) : showDegreeSettings ? (
<>




<div style={{ padding: '6px 8px', fontSize: '1.1rem' }}>
<label id="note-range-slider" style={{ fontSize: '1.1rem' }}>
Note Range
</label>
<Slider
color='secondary'
value={range}
valueLabelFormat={(value) => Tone.Frequency(value, 'midi').toNote()}
onChange={(_, newValue) => {
if (Math.abs(newValue[1] - newValue[0]) >= 12) { // 确保范围至少有12个MIDI值
if (Math.abs(newValue[1] - newValue[0]) >= 12) {
console.log(newValue);
setRange(newValue);
}
Expand All @@ -77,64 +95,76 @@ function DegreeTrainerSettings({
min={Tone.Frequency('C3').toMidi()}
max={Tone.Frequency('C6').toMidi()}
valueLabelDisplay="auto"
sx={{ '.MuiSlider-valueLabel': { fontSize: '1rem' } }}
/>
</div>
<div style={{ padding: '6px 8px' }}>
<label>Drone Volume</label>
<Slider color='secondary' value={droneVolume} valueLabelFormat={(value) => Math.round(value * 100)} onChange={(e, value) => setDroneVolume(value)} min={0} max={1} step={0.01} valueLabelDisplay="auto" />
<div style={{ padding: '6px 8px', fontSize: '1.1rem' }}>
<label style={{ fontSize: '1.1rem' }}>Root Note</label>
<Slider color='secondary' valueLabelFormat={(value) => Tone.Frequency(value, 'midi').toNote()} value={rootNote} onChange={(e, value) => setRootNote(value)} min={midiMin} max={midiMax} valueLabelDisplay="auto" sx={{ '.MuiSlider-valueLabel': { fontSize: '1rem' } }} />
</div>
<div style={{ padding: '6px 8px' }}>
<label>Piano Volume </label>
<Slider color='secondary' valueLabelFormat={(value) => Math.round(value * 100)} value={pianoVolume} onChange={(e, value) => setPianoVolume(value)} min={0} max={1} step={0.01} valueLabelDisplay="auto" />
<div style={{ padding: '6px 8px', }}>
<label style={{ fontSize: '1.1rem' }}>BPM: </label>
<Slider color='secondary' value={bpm} onChange={(e, value) => setBpm(value)} min={40} max={200} valueLabelDisplay="auto" sx={{ '.MuiSlider-valueLabel': { fontSize: '1rem' } }} />
</div>
<div style={{ padding: '6px 8px' }}>
<label>Root Note</label>
<Slider color='secondary' valueLabelFormat={(value) => Tone.Frequency(value, 'midi').toNote()} value={rootNote} onChange={(e, value) => setRootNote(value)} min={midiMin} max={midiMax} valueLabelDisplay="auto" />
<div style={{ padding: '6px 8px',fontSize: '1.1rem' }}>
<label style={{ fontSize: '1.1rem' }}>选择练习级数</label>
<Grid container spacing={1}sx={{marginTop:'4px',paddingLeft:0}}>
{currentNotes.map((note, index) => (
<Grid item xs={4} key={note.name} sx={{padding:0}}>
<Box
onClick={() => handleDegreeToggle(index)}
sx={{
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
padding: '4px',
'&:hover': { bgcolor: 'action.hover' },
}}
>
<Checkbox
color='secondary'
checked={note.enable}
tabIndex={-1}
size="small"
sx={{ padding: '2px' }}
/>
<Typography variant="body2" sx={{ marginLeft: '4px', fontSize: '1.1rem' }}>
{note.name}
</Typography>
</Box>
</Grid>
))}
</Grid>
</div>

<Button
color='secondary'
onClick={() => setShowDegreeSettings(false)}
sx={{ display: 'flex', justifyContent: 'flex-center', fontSize: '1.2rem', marginLeft: 'auto' }}
>
<HomeIcon/>
</Button>
</>
) : (
<>
<Typography variant="h6" sx={{ paddingBottom: '1rem', paddingLeft: '6px' }}>选择要练习的级数</Typography>

<Grid container spacing={1}>
{currentNotes.map((note, index) => (
<Grid item xs={4} key={note.name}>
<Box
onClick={() => handleDegreeToggle(index)}
sx={{
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
padding: '4px',
'&:hover': { bgcolor: 'action.hover' },
}}
>
<Checkbox
color='secondary'
checked={note.enable}
tabIndex={-1}
size="small"
sx={{ padding: '2px' }}
/>
<Typography variant="body2" sx={{ marginLeft: '4px' }}>
{note.name}
</Typography>
</Box>
</Grid>
))}
</Grid>
<div style={{ padding: '6px 8px', fontSize: '1.1rem' }}>
<label style={{ fontSize: '1.1rem' }}>Drone Volume</label>
<Slider color='secondary' value={droneVolume} valueLabelFormat={(value) => Math.round(value * 100)} onChange={(e, value) => setDroneVolume(value)} min={0} max={1} step={0.01} valueLabelDisplay="auto" sx={{ '.MuiSlider-valueLabel': { fontSize: '1rem' } }} />
</div>
<div style={{ padding: '6px 8px', fontSize: '1.1rem' }}>
<label style={{ fontSize: '1.1rem' }}>Piano Volume </label>
<Slider color='secondary' valueLabelFormat={(value) => Math.round(value * 100)} value={pianoVolume} onChange={(e, value) => setPianoVolume(value)} min={0} max={1} step={0.01} valueLabelDisplay="auto" sx={{ '.MuiSlider-valueLabel': { fontSize: '1rem' } }} />
</div>

<Button
color='secondary'
onClick={() => setShowDegreeSettings(false)}
sx={{ marginLeft: 'auto' }}
sx={{ display: 'flex', justifyContent: 'flex-center', fontSize: '1.2rem', marginLeft: 'auto' }}
>
返回
<HomeIcon/>
</Button>

</>
)}

</Box>
</Modal>
);
Expand Down

0 comments on commit 46033c2

Please sign in to comment.