fix: canvas audioclip hiển thị theo tỉ lệ tempo, không giãn khung
This commit is contained in:
+11
-6
@@ -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 hiển 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 rộng hơn frame thì khóa giữa + 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) => {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -24,7 +24,7 @@
|
||||
<script src="/static/js/services/midiExtractor.js?v=202607281052"></script>
|
||||
<script src="/static/js/services/promptTemplateManager.js?v=202607281039"></script>
|
||||
<script src="/static/js/services/undoRedoEngine.js?v=202607290941"></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608021930" defer></script>
|
||||
<script src="/static/js/app.precompiled.js?v=202608021936" defer></script>
|
||||
<link rel="stylesheet" href="/static/css/styles.css?v=202607271016">
|
||||
<style>
|
||||
:root {
|
||||
|
||||
@@ -1139,3 +1139,8 @@
|
||||
- **Tóm tắt thay đổi:** (1) Fix canvas audio hiển thị sai: waveform server trả `duration` nhưng không lưu → `dur=0` nên ruler/playhead/time sai. Thêm state `audioDuration` (set ở loadWaveform local/server + playSelected, clear ở handleSelect), `fileDuration` ưu tiên dùng; bar width waveform sửa theo `contentW` thay vì `w` để scroll đúng. (2) Drag & drop file từ Media Explorer vào timeline MAIN SESSION + SECTION-TAB: file row `draggable` + `onDragStart` set `window.__mediaExplorerDragFile`; App thêm `resolveMediaExplorerDropFile()` chuyển entry → real File (client handle `getFile()`, server `file_id` fetch download, local `path` fetch `/media/file`); drop handlers trên track lane + wrapper timeline xử lý cả drag ME lẫn drag OS file (MIDI → new track / audio → load vào track).
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/static/js/app.precompiled.js`, `app/templates/index.html`
|
||||
- **Ghi chú/Test (nếu có):** Smoke jsdom: wav client → metadata Duration 3.00s (trước là 0); drag file row → payload text/plain=name + `__mediaExplorerDragFile` set → drop vào track lane → resolve thành File + load (uploadToServer gọi). Hard reload.
|
||||
|
||||
### [2026-08-02 19:36] Task: Fix canvas audioclip giãn đầy khung preview
|
||||
- **Tóm tắt thay đổi:** `drawCanvas` branch audio: bỏ `contentW = Math.max(w, dur*pxPerSec)` (giãn đầy frame) → `contentW = max(1, dur*pxPerSec)` với `pxPerBeat=42`, `pxPerSec = 42*bpm/60` (cùng tỉ lệ tempo với MIDI). Clip ngắn hiển thị đúng chiều rộng theo tempo (2s@120 → 168px), clip dài scroll; playhead theo tỉ lệ tempo (`t*pxPerSec`, khóa giữa khi scroll). Ruler cùng scale (bỏ stretch `Math.max(w, ...)`). Thêm `audioDuration` vào deps effect redraw.
|
||||
- **Các file ảnh hưởng:** `app/static/js/app.jsx`, `app/static/js/app.precompiled.js`, `app/templates/index.html`
|
||||
- **Ghi chú/Test (nếu có):** Probe drawCanvas: 2s@120 → contentW=168, waveform maxX 167.8 < 300 (không giãn); 10s → 840 scroll; 2s@240 → 336 (rộng hơn theo tempo). Hard reload.
|
||||
|
||||
Reference in New Issue
Block a user