fix: canvas audioclip hiển thị theo tỉ lệ tempo, không giãn khung

This commit is contained in:
2026-08-02 18:20:48 +07:00
parent 0853a13f62
commit 9be6991222
4 changed files with 22 additions and 9 deletions
+11 -6
View File
@@ -9759,8 +9759,11 @@ const MediaExplorerPanel = ({ height }) => {
} else {
const pk = curPeaks && curPeaks.length > 0 ? curPeaks : null;
if (pk) {
const pxPerSec = 50;
const contentW = Math.max(w, dur * pxPerSec);
// Audio hin th theo t l tempo (pxPerSec), không giãn đy khung preview
const audioBpm = curTempo || 120;
const pxPerBeat = 42;
const pxPerSec = pxPerBeat * audioBpm / 60;
const contentW = Math.max(1, dur * pxPerSec);
let offset = 0;
if (playing && contentW > w && dur > 0) {
offset = Math.max(0, Math.min(contentW - w, t * pxPerSec - w / 2));
@@ -9774,7 +9777,8 @@ const MediaExplorerPanel = ({ height }) => {
const ph = Math.max(2, pk[i] * (h / 2 - 4));
ctx.fillRect(x, mid - ph, barW, ph * 2);
}
const audioPlayheadX = contentW > w ? Math.min(w / 2, t * pxPerSec) : Math.min(w, t * pxPerSec);
// Playhead theo t l tempo; khi content rng hơn frame thì khóa gia + scroll
const audioPlayheadX = contentW > w ? Math.min(w / 2, t * pxPerSec) : (t * pxPerSec);
if (playing && dur > 0) {
ctx.fillStyle = '#ef4444';
ctx.fillRect(audioPlayheadX - 1, 0, 2, h - 14);
@@ -9788,10 +9792,11 @@ const MediaExplorerPanel = ({ height }) => {
ctx.fillStyle = '#111'; ctx.fillRect(0, h - 14, w, 14);
ctx.fillStyle = '#888'; ctx.font = '9px JetBrains Mono, monospace';
const rulerBpm = curTempo || 120;
const rulerPxPerBeat = isMidiFile(f) ? 42 : (50 * 60 / rulerBpm);
const rulerPxPerBeat = 42;
const isRealMidi = isMidiFile(f) && curMidiNotes && curMidiNotes.length && curMidiTotalBeats > 0;
const rulerTotalBeats = isRealMidi ? Math.max(curMidiTotalBeats, 4) : Math.max(4, Math.ceil(dur * rulerBpm / 60) || 16);
const rulerContentW = isRealMidi ? Math.max(w, rulerTotalBeats * rulerPxPerBeat) : Math.max(w, dur * rulerPxPerBeat * rulerBpm / 60);
// T l theo tempo (không giãn đy khung)
const rulerContentW = Math.max(1, rulerTotalBeats * rulerPxPerBeat);
const rulerPxPerSec = rulerPxPerBeat * rulerBpm / 60;
const rulerOffset = (playing && rulerContentW > w && dur > 0) ? Math.max(0, Math.min(rulerContentW - w, t * rulerPxPerSec - w / 2)) : 0;
for (let b = 0; b <= rulerTotalBeats; b += 4) {
@@ -9801,7 +9806,7 @@ const MediaExplorerPanel = ({ height }) => {
}
};
React.useEffect(() => { drawCanvas(currentTime); }, [peaks, audioBuffer, midiNotes, selected, folder, isPlaying]);
React.useEffect(() => { drawCanvas(currentTime); }, [peaks, audioBuffer, audioDuration, midiNotes, selected, folder, isPlaying]);
React.useEffect(() => () => { if (rafRef.current) cancelAnimationFrame(rafRef.current); }, []);
const handleSelect = (f) => {