changed indicators on the Playback/SpeedCalc modals

This commit is contained in:
2026-02-22 19:48:08 +02:00
parent 9437307e0f
commit 1fe8c542db
2 changed files with 23 additions and 5 deletions

View File

@@ -357,9 +357,9 @@ export default function PlaybackModal({ open, melody, builtMelody, files, archet
<p className="text-xs mb-2" style={mutedStyle}>Note Assigned Bell</p> <p className="text-xs mb-2" style={mutedStyle}>Note Assigned Bell</p>
<div className="flex flex-wrap gap-1.5"> <div className="flex flex-wrap gap-1.5">
{noteAssignments.map((assignedBell, noteIdx) => { {noteAssignments.map((assignedBell, noteIdx) => {
// A note is active if the current step has this note's bit set (raw archetype value) // A note is active (flashing) if its assigned bell is currently lit in activeBells
const isActive = currentStep >= 0 && Boolean(steps[currentStep] & (1 << noteIdx));
const firesABell = assignedBell && assignedBell > 0; const firesABell = assignedBell && assignedBell > 0;
const isActive = firesABell && activeBells.has(assignedBell);
return ( return (
<div <div
key={noteIdx} key={noteIdx}

View File

@@ -127,6 +127,7 @@ export default function SpeedCalculatorModal({ open, melody, builtMelody, archet
// Playback // Playback
const audioCtxRef = useRef(null); const audioCtxRef = useRef(null);
const playbackRef = useRef(null); // { timer, stepIndex } const playbackRef = useRef(null); // { timer, stepIndex }
const flashTimerRef = useRef(null);
const stepsRef = useRef([]); const stepsRef = useRef([]);
const stepDelayRef = useRef(500); const stepDelayRef = useRef(500);
const effectiveBeatRef = useRef(100); const effectiveBeatRef = useRef(100);
@@ -136,6 +137,7 @@ export default function SpeedCalculatorModal({ open, melody, builtMelody, archet
const [paused, setPaused] = useState(false); const [paused, setPaused] = useState(false);
const [loop, setLoop] = useState(true); const [loop, setLoop] = useState(true);
const [currentStep, setCurrentStep] = useState(-1); const [currentStep, setCurrentStep] = useState(-1);
const [activeBells, setActiveBells] = useState(new Set());
// Sliders // Sliders
const [stepDelay, setStepDelay] = useState(500); const [stepDelay, setStepDelay] = useState(500);
@@ -175,6 +177,7 @@ export default function SpeedCalculatorModal({ open, melody, builtMelody, archet
setCapturedNormal(normal); setCapturedNormal(normal);
setBinaryLoadError(""); setBinaryLoadError("");
setCurrentStep(-1); setCurrentStep(-1);
setActiveBells(new Set());
setPlaying(false); setPlaying(false);
setPaused(false); setPaused(false);
setSaveError(""); setSaveError("");
@@ -198,9 +201,14 @@ export default function SpeedCalculatorModal({ open, melody, builtMelody, archet
clearTimeout(playbackRef.current.timer); clearTimeout(playbackRef.current.timer);
playbackRef.current = null; playbackRef.current = null;
} }
if (flashTimerRef.current) {
clearTimeout(flashTimerRef.current);
flashTimerRef.current = null;
}
setPlaying(false); setPlaying(false);
setPaused(false); setPaused(false);
setCurrentStep(-1); setCurrentStep(-1);
setActiveBells(new Set());
}, []); }, []);
useEffect(() => { useEffect(() => {
@@ -237,6 +245,17 @@ export default function SpeedCalculatorModal({ open, melody, builtMelody, archet
const stepValue = currentSteps[playFrom]; const stepValue = currentSteps[playFrom];
setCurrentStep(playFrom); setCurrentStep(playFrom);
// Flash active bells for tone length, then clear
const bellsNow = new Set();
getActiveBells(stepValue).forEach((b) => bellsNow.add(b));
setActiveBells(bellsNow);
if (flashTimerRef.current) clearTimeout(flashTimerRef.current);
flashTimerRef.current = setTimeout(() => {
setActiveBells(new Set());
flashTimerRef.current = null;
}, effectiveBeatRef.current);
playStep(ctx, stepValue, effectiveBeatRef.current); playStep(ctx, stepValue, effectiveBeatRef.current);
const delay = stepDelayRef.current; const delay = stepDelayRef.current;
@@ -353,7 +372,6 @@ export default function SpeedCalculatorModal({ open, melody, builtMelody, archet
getActiveBells(v).forEach((b) => set.add(b)); getActiveBells(v).forEach((b) => set.add(b));
return set; return set;
}, new Set()); }, new Set());
const currentBells = currentStep >= 0 ? getActiveBells(steps[currentStep] || 0) : [];
const maxBell = allBellsUsed.size > 0 ? Math.max(...Array.from(allBellsUsed)) : 0; const maxBell = allBellsUsed.size > 0 ? Math.max(...Array.from(allBellsUsed)) : 0;
return ( return (
@@ -439,12 +457,12 @@ export default function SpeedCalculatorModal({ open, melody, builtMelody, archet
{totalSteps > 0 && ( {totalSteps > 0 && (
<div> <div>
<p className="text-xs mb-2" style={mutedStyle}> <p className="text-xs mb-2" style={mutedStyle}>
Bell indicator Notes Indicators
{currentStep >= 0 && <span> &nbsp;·&nbsp; Step {currentStep + 1} / {totalSteps}</span>} {currentStep >= 0 && <span> &nbsp;·&nbsp; Step {currentStep + 1} / {totalSteps}</span>}
</p> </p>
<div className="flex flex-wrap gap-1.5"> <div className="flex flex-wrap gap-1.5">
{Array.from({ length: maxBell }, (_, i) => i + 1).map((b) => { {Array.from({ length: maxBell }, (_, i) => i + 1).map((b) => {
const isActive = currentBells.includes(b); const isActive = activeBells.has(b);
const isUsed = allBellsUsed.has(b); const isUsed = allBellsUsed.has(b);
return ( return (
<div <div