fix: piano roll bars extend to fill viewport on zoom out

This commit is contained in:
2026-07-25 07:50:53 +07:00
parent a90a3cfad1
commit eb805c04a4
2 changed files with 21 additions and 18 deletions
+15 -12
View File
@@ -4434,6 +4434,9 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
rollBeatsRef.current = rollBeats;
const totalBeats = Math.max(rollBeats, noteMaxBeat + 16, 64); // at least 64 beats (16 bars) for scrolling
const drawWidth = totalBeats * pixelsPerBeat;
const [rollViewWidth, setRollViewWidth] = React.useState(800);
const viewWidth = Math.max(drawWidth, rollViewWidth);
const viewBeats = Math.ceil(viewWidth / pixelsPerBeat) + 4;
const [notes, setNotes] = React.useState(st.notes || []);
const [selectedNoteIds, setSelectedNoteIds] = React.useState([]);
@@ -4577,7 +4580,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
const ctx = canvas.getContext('2d');
const dpr = window.devicePixelRatio || 1;
const h = 128 * NoteHeight;
canvas.width = drawWidth * dpr;
canvas.width = viewWidth * dpr;
canvas.height = h * dpr;
ctx.scale(dpr, dpr);
@@ -4586,13 +4589,13 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
const y = (127 - pitch) * NoteHeight;
const isBlack = [1, 3, 6, 8, 10].includes(pitch % 12);
ctx.fillStyle = isBlack ? '#1a1a1e' : '#25252a';
ctx.fillRect(0, y, drawWidth, NoteHeight);
ctx.fillRect(0, y, viewWidth, NoteHeight);
ctx.strokeStyle = '#2d2d35';
ctx.lineWidth = 0.5;
ctx.beginPath();
ctx.moveTo(0, y + NoteHeight);
ctx.lineTo(drawWidth, y + NoteHeight);
ctx.lineTo(viewWidth, y + NoteHeight);
ctx.stroke();
}
@@ -4605,7 +4608,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
else if (snapVal === '1/16') snapBeats = 0.25;
else if (snapVal === '1/32') snapBeats = 0.125;
for (let beat = 0; beat <= totalBeats; beat += snapBeats) {
for (let beat = 0; beat <= viewBeats; beat += snapBeats) {
const x = beat * pixelsPerBeat;
if (x > drawWidth) break;
const isBar = beat % timeSigNum === 0;
@@ -4663,7 +4666,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
if (st.currentTime !== undefined && st.currentTime !== null && st.currentTime >= 0) {
const phBeat = st.currentTime / (60.0 / (parseInt(bpm) || 120));
const phX = phBeat * pixelsPerBeat;
if (phX >= 0 && phX <= drawWidth) {
if (phX >= 0 && phX <= viewWidth) {
ctx.strokeStyle = '#f59e0b';
ctx.lineWidth = 1.5;
ctx.beginPath();
@@ -4680,18 +4683,18 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
const ctx = canvas.getContext('2d');
const dpr = window.devicePixelRatio || 1;
const h = 80;
canvas.width = drawWidth * dpr;
canvas.width = viewWidth * dpr;
canvas.height = h * dpr;
ctx.scale(dpr, dpr);
ctx.fillStyle = '#161616';
ctx.fillRect(0, 0, drawWidth, h);
ctx.fillRect(0, 0, viewWidth, h);
ctx.strokeStyle = '#252525';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(0, h / 2);
ctx.lineTo(drawWidth, h / 2);
ctx.lineTo(viewWidth, h / 2);
ctx.stroke();
notes.forEach((note) => {
@@ -5331,7 +5334,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
const renderBarLabels = () => {
const labels = [];
const barsCount = Math.ceil(totalBeats / 4);
const barsCount = Math.ceil(viewBeats / 4);
for (let bar = 0; bar < barsCount; bar++) {
const x = bar * 4 * pixelsPerBeat;
labels.push(
@@ -5436,7 +5439,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
}
}, /*#__PURE__*/React.createElement("div", {
style: {
width: `${drawWidth}px`,
width: `${viewWidth}px`,
height: '100%'
},
className: "relative h-full font-mono text-[9px] text-zinc-500 font-bold"
@@ -5456,7 +5459,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
className: "flex-1 overflow-auto bg-[#141414] min-w-0"
}, /*#__PURE__*/React.createElement("div", {
style: {
width: `${drawWidth}px`,
width: `${viewWidth}px`,
height: `${(128 - PITCH_START) * NoteHeight}px`
},
className: "relative"
@@ -5476,7 +5479,7 @@ const PianoRollTabEditor = ({ st, zoom, bpm, viewportWidth, onClose, onUpdateNot
className: "flex-1 overflow-x-hidden min-w-0"
}, /*#__PURE__*/React.createElement("div", {
style: {
width: `${drawWidth}px`,
width: `${viewWidth}px`,
height: '100%'
},
className: "relative"
File diff suppressed because one or more lines are too long