fix: WaveformLane grid now matches TempoTrackLane bar:beat structure, bar:beat always shown on tempo lane
This commit is contained in:
+24
-29
@@ -443,26 +443,28 @@ const WaveformLane = ({
|
|||||||
const PADDING_LEFT = barDuration; // 1-bar margin on left
|
const PADDING_LEFT = barDuration; // 1-bar margin on left
|
||||||
const tStart = scrollLeftVal / zoom - PADDING_LEFT;
|
const tStart = scrollLeftVal / zoom - PADDING_LEFT;
|
||||||
const tEnd = (scrollLeftVal + drawWidth) / zoom + PADDING_LEFT;
|
const tEnd = (scrollLeftVal + drawWidth) / zoom + PADDING_LEFT;
|
||||||
let gridSpacing = 1.0;
|
const firstBeat = Math.floor(tStart / beatDuration) * beatDuration;
|
||||||
|
let snapDivisor = 1;
|
||||||
if (snapValue && snapValue !== 'free') {
|
if (snapValue && snapValue !== 'free') {
|
||||||
const beatDuration = 60 / parseFloat(bpm || 120);
|
if (snapValue === '4') snapDivisor = 4; else if (snapValue === '1') snapDivisor = 1; else if (snapValue === '1/2') snapDivisor = 0.5; else if (snapValue === '1/4') snapDivisor = 0.25; else if (snapValue === '1/8') snapDivisor = 0.125; else if (snapValue === '1/16') snapDivisor = 0.0625; else if (snapValue === '1/32') snapDivisor = 0.03125;
|
||||||
let divisor = 1;
|
|
||||||
if (snapValue === '4') divisor = 4; else if (snapValue === '1') divisor = 1; else if (snapValue === '1/2') divisor = 0.5; else if (snapValue === '1/4') divisor = 0.25; else if (snapValue === '1/8') divisor = 0.125; else if (snapValue === '1/16') divisor = 0.0625; else if (snapValue === '1/32') divisor = 0.03125;
|
|
||||||
gridSpacing = beatDuration * divisor;
|
|
||||||
} else {
|
|
||||||
gridSpacing = 60 / parseFloat(bpm || 120);
|
|
||||||
}
|
}
|
||||||
let drawSpacing = gridSpacing;
|
for (let t = firstBeat; t <= tEnd; t += beatDuration) {
|
||||||
while (drawSpacing * zoom < 10) {
|
const beatNum = Math.floor(t / beatDuration) + 1;
|
||||||
drawSpacing *= 2;
|
const isBar = beatNum % 4 === 1;
|
||||||
}
|
const localX = (t - tStart) * zoom;
|
||||||
const firstGridStep = Math.floor(tStart / drawSpacing) * drawSpacing;
|
if (localX < -200 || localX > drawWidth + 200) continue;
|
||||||
for (let s = firstGridStep; s <= tEnd; s += drawSpacing) {
|
ctx.strokeStyle = isBar ? 'rgba(255, 255, 255, 0.12)' : 'rgba(255, 255, 255, 0.04)';
|
||||||
const localX = (s - tStart) * zoom;
|
ctx.lineWidth = isBar ? 1.2 : 0.5;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(localX, 0);
|
ctx.moveTo(localX, 0);
|
||||||
ctx.lineTo(localX, height);
|
ctx.lineTo(localX, height);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
if (isBar && zoom >= 2) {
|
||||||
|
ctx.fillStyle = 'rgba(255, 255, 255, 0.15)';
|
||||||
|
ctx.font = 'bold 7px Inter, sans-serif';
|
||||||
|
ctx.textAlign = 'left';
|
||||||
|
ctx.fillText(`${Math.ceil(beatNum / 4)}`, localX + 2, 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw waveform lane
|
// Draw waveform lane
|
||||||
@@ -1237,22 +1239,10 @@ const TempoTrackLane = ({
|
|||||||
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
|
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
|
||||||
ctx.font = 'bold 9px Inter, sans-serif';
|
ctx.font = 'bold 9px Inter, sans-serif';
|
||||||
ctx.textAlign = 'left';
|
ctx.textAlign = 'left';
|
||||||
|
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
|
||||||
|
ctx.font = 'bold 9px Inter, sans-serif';
|
||||||
|
ctx.textAlign = 'left';
|
||||||
ctx.fillText(`${Math.ceil(beatNum / 4)}`, localX + 3, 11);
|
ctx.fillText(`${Math.ceil(beatNum / 4)}`, localX + 3, 11);
|
||||||
} else if (zoom >= 2) {
|
|
||||||
ctx.strokeStyle = 'rgba(255, 255, 255, 0.08)';
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(localX, 0);
|
|
||||||
ctx.lineTo(localX, height);
|
|
||||||
ctx.stroke();
|
|
||||||
if (zoom >= 5) {
|
|
||||||
ctx.fillStyle = 'rgba(255, 255, 255, 0.4)';
|
|
||||||
ctx.font = '8px Inter, sans-serif';
|
|
||||||
ctx.textAlign = 'left';
|
|
||||||
const bar = Math.ceil(beatNum / 4);
|
|
||||||
const beat = ((beatNum - 1) % 4) + 1;
|
|
||||||
ctx.fillText(`${bar}:${beat}`, localX + 2, 9);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ctx.strokeStyle = 'rgba(255, 255, 255, 0.08)';
|
ctx.strokeStyle = 'rgba(255, 255, 255, 0.08)';
|
||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
@@ -1261,6 +1251,11 @@ const TempoTrackLane = ({
|
|||||||
ctx.lineTo(localX, height);
|
ctx.lineTo(localX, height);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
|
ctx.fillStyle = 'rgba(255, 255, 255, 0.35)';
|
||||||
|
ctx.font = '7px Inter, sans-serif';
|
||||||
|
const bar = Math.ceil(beatNum / 4);
|
||||||
|
const beat = ((beatNum - 1) % 4) + 1;
|
||||||
|
ctx.fillText(`${bar}:${beat}`, localX + 2, height - 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw snap sub-ticks at the bottom
|
// Draw snap sub-ticks at the bottom
|
||||||
|
|||||||
Reference in New Issue
Block a user