fix: range loop selection maintains bar count on BPM change

- Add prevBpmRef to track previous BPM
- BPM effect recalculates selectionStart/End using bar count
- startBar = oldStart / oldSecondsPerBar
- newStart = startBar * newSecondsPerBar (same for end)
This commit is contained in:
2026-07-27 08:31:12 +07:00
parent e739eb54bf
commit 3c12ce2a22
2 changed files with 19 additions and 5 deletions
+15 -2
View File
@@ -6402,12 +6402,25 @@ const App = () => {
}]);
const [appWarningModal, setAppWarningModal] = useState(null);
const [bpm, setBpm] = useState(localStorage.getItem('studio_bpm') || '120');
const [draggedClip, setDraggedClip] = useState(null); // { trackId, clickOffset, buffer, name, volume, color }
const prevBpmRef = useRef(bpm);
const [draggedClip, setDraggedClip] = useState(null);
const [hoveredTrackId, setHoveredTrackId] = useState(null);
// Recalculate item/section durations when BPM changes (maintain bar count)
// Recalculate item/section/selection durations when BPM changes
useEffect(() => {
const oldSpb = prevBpmRef.current ? (60.0 / parseFloat(prevBpmRef.current)) * 4 : null;
const bpmVal = parseFloat(bpm) || 120;
const secondsPerBar = (60.0 / bpmVal) * 4;
// Recalculate range loop selection to maintain bar count
if (oldSpb && selectionStart !== null && selectionEnd !== null && selectionEnd > selectionStart) {
const startBar = selectionStart / oldSpb;
const endBar = selectionEnd / oldSpb;
if (endBar - startBar > 0.01) {
setSelectionStart(startBar * secondsPerBar);
setSelectionEnd(endBar * secondsPerBar);
}
}
prevBpmRef.current = bpm;
// Recalculate item/section durations
updateActiveTracks(prev => prev.map(t => ({
...t,
midiItems: (t.midiItems || []).map(m => {