summaryrefslogtreecommitdiff
path: root/tools/timeline_editor
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-12 13:26:22 +0100
committerskal <pascal.massimino@gmail.com>2026-02-12 13:26:22 +0100
commita27925e8cbe97b3219437608b40432e886782316 (patch)
tree124cf8224177332921490c3c689c633de5ab5558 /tools/timeline_editor
parent82d34d198b3c916df4d5d39142095edb410e7500 (diff)
Timeline editor: fix seek position when zoomed
Use helper functions (beatsToTime, timeToBeats) consistently in click handlers. Fixes red cursor jumping to wrong position during seek. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'tools/timeline_editor')
-rw-r--r--tools/timeline_editor/index.html19
1 files changed, 10 insertions, 9 deletions
diff --git a/tools/timeline_editor/index.html b/tools/timeline_editor/index.html
index 2c66ddd..402c580 100644
--- a/tools/timeline_editor/index.html
+++ b/tools/timeline_editor/index.html
@@ -852,15 +852,15 @@
if (!state.audioBuffer) return;
const rect = dom.waveformContainer.getBoundingClientRect();
const clickX = e.clientX - rect.left + dom.timelineContent.scrollLeft;
- const clickTime = (clickX / state.pixelsPerSecond) * 60.0 / state.bpm;
+ const clickBeats = clickX / state.pixelsPerSecond;
+ const clickTime = beatsToTime(clickBeats);
const wasPlaying = state.isPlaying;
if (wasPlaying) stopPlayback(false);
state.playbackOffset = Math.max(0, Math.min(clickTime, state.audioDuration));
- const clickBeats = state.playbackOffset * state.bpm / 60.0;
- dom.playbackTime.textContent = `${state.playbackOffset.toFixed(2)}s (${clickBeats.toFixed(2)}b)`;
- const indicatorX = clickBeats * state.pixelsPerSecond;
- dom.playbackIndicator.style.left = `${indicatorX}px`;
- dom.waveformPlaybackIndicator.style.left = `${indicatorX}px`;
+ const pausedBeats = timeToBeats(state.playbackOffset);
+ dom.playbackTime.textContent = `${state.playbackOffset.toFixed(2)}s (${pausedBeats.toFixed(2)}b)`;
+ const indicatorX = pausedBeats * state.pixelsPerSecond;
+ dom.playbackIndicator.style.left = dom.waveformPlaybackIndicator.style.left = `${indicatorX}px`;
if (wasPlaying) await startPlayback();
});
@@ -917,15 +917,16 @@
if (e.target !== dom.timeline) return;
const timelineRect = dom.timeline.getBoundingClientRect();
const clickX = e.clientX - timelineRect.left + dom.timelineContent.scrollLeft;
- const clickBeats = clickX / state.pixelsPerSecond, clickTime = clickBeats * 60.0 / state.bpm;
+ const clickBeats = clickX / state.pixelsPerSecond;
+ const clickTime = beatsToTime(clickBeats);
if (state.audioBuffer) {
const wasPlaying = state.isPlaying;
if (wasPlaying) stopPlayback(false);
state.playbackOffset = Math.max(0, Math.min(clickTime, state.audioDuration));
- const pausedBeats = state.playbackOffset * state.bpm / 60.0;
+ const pausedBeats = timeToBeats(state.playbackOffset);
dom.playbackTime.textContent = `${state.playbackOffset.toFixed(2)}s (${pausedBeats.toFixed(2)}b)`;
const indicatorX = pausedBeats * state.pixelsPerSecond;
- dom.playbackIndicator.style.left = `${indicatorX}px`; dom.waveformPlaybackIndicator.style.left = `${indicatorX}px`;
+ dom.playbackIndicator.style.left = dom.waveformPlaybackIndicator.style.left = `${indicatorX}px`;
if (wasPlaying) await startPlayback();
showMessage(`Seek to ${clickTime.toFixed(2)}s (${clickBeats.toFixed(2)}b)`, 'success');
}