fix: brush draw per-note duration with noteStartBeats tracking

This commit is contained in:
2026-07-26 10:50:45 +07:00
parent 8450bd6de4
commit 034455598d
3 changed files with 24 additions and 7 deletions
+17 -5
View File
@@ -5120,7 +5120,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
visitedPitches: snapToScaleRef.current ? [snapPitchToScale(pitch, selectedScaleRef.current)] : [pitch],
initialBeat: start,
initialPitch: snapToScaleRef.current ? snapPitchToScale(pitch, selectedScaleRef.current) : pitch,
lastDrawBeat: start
noteStartBeats: [start]
});
// Play the note with SoundFont
if (window.SonicSF) {
@@ -5206,18 +5206,27 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
return;
}
if (draggedNote.mode === 'draw') {
const rawDur = beat - draggedNote.startOffsetBeat;
const newDur = getSnapBeat(Math.max(0.125, rawDur), snapVal);
const visited = draggedNote.visitedPitches || [];
const snappedPitch = snapToScaleRef.current ? snapPitchToScale(pitch, selectedScaleRef.current) : pitch;
const pitchChanged = !visited.includes(snappedPitch);
const noteBeats = draggedNote.noteStartBeats || [];
const defaultDur = getSnapDuration(snapVal);
if (pitchChanged) {
const brushIds = draggedNote.brushIds || [];
if (brushIds.length > 0 && noteBeats.length > 0) {
const prevNoteId = brushIds[brushIds.length - 1];
const prevNoteBeat = noteBeats[noteBeats.length - 1];
const prevDur = Math.max(0.125, beat - prevNoteBeat);
setNotes(prev => prev.map(n => {
if (n.id !== prevNoteId) return n;
return { ...n, duration_beats: prevDur };
}));
}
const newNote = {
id: 'note_' + Date.now() + Math.random().toString(36).substr(2, 8) + '_' + (visited.length + 1),
pitch: snappedPitch,
start_beat: beat,
duration_beats: getSnapDuration(snapVal),
duration_beats: defaultDur,
velocity: brushVelocityRef.current,
pan: 0.0
};
@@ -5225,13 +5234,16 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
setSelectedNoteIds(prev => [...prev, newNote.id]);
draggedNote.brushIds = [...brushIds, newNote.id];
draggedNote.visitedPitches = [...visited, snappedPitch];
draggedNote.noteStartBeats = [...noteBeats, beat];
} else {
const brushIds = draggedNote.brushIds || [];
const lastBrushId = brushIds.length > 0 ? brushIds[brushIds.length - 1] : draggedNote.drawNoteId;
const lastNoteBeat = noteBeats.length > 0 ? noteBeats[noteBeats.length - 1] : draggedNote.startOffsetBeat;
if (lastBrushId) {
const extDur = Math.max(0.125, beat - lastNoteBeat);
setNotes(prev => prev.map(n => {
if (n.id !== lastBrushId) return n;
return { ...n, duration_beats: newDur };
return { ...n, duration_beats: extDur };
}));
}
}