From 2031e24c976d1a11eb48badb97e824b1db07741a Mon Sep 17 00:00:00 2001 From: skal Date: Sun, 15 Feb 2026 14:54:32 +0100 Subject: feat(timeline-editor): add timing tooltip and cursor in waveform view Shows precise time (seconds) and beat position under mouse cursor with a vertical guide line for accurate sample timing measurements. Co-Authored-By: Claude Sonnet 4.5 --- tools/timeline_editor/timeline-viewport.js | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'tools/timeline_editor/timeline-viewport.js') diff --git a/tools/timeline_editor/timeline-viewport.js b/tools/timeline_editor/timeline-viewport.js index becf8e9..396b648 100644 --- a/tools/timeline_editor/timeline-viewport.js +++ b/tools/timeline_editor/timeline-viewport.js @@ -32,6 +32,11 @@ export class ViewportController { this.dom.propertiesPanel.addEventListener('wheel', e => e.stopPropagation()); document.querySelector('.zoom-controls').addEventListener('wheel', e => e.stopPropagation()); document.querySelector('.stats').addEventListener('wheel', e => e.stopPropagation()); + + // Waveform hover tracking + this.dom.waveformContainer.addEventListener('mouseenter', () => this.showWaveformCursor()); + this.dom.waveformContainer.addEventListener('mouseleave', () => this.hideWaveformCursor()); + this.dom.waveformContainer.addEventListener('mousemove', e => this.updateWaveformCursor(e)); } handleZoomSlider(e) { @@ -126,6 +131,37 @@ export class ViewportController { } } + showWaveformCursor() { + this.dom.waveformCursor.style.display = 'block'; + this.dom.waveformTooltip.style.display = 'block'; + } + + hideWaveformCursor() { + this.dom.waveformCursor.style.display = 'none'; + this.dom.waveformTooltip.style.display = 'none'; + } + + updateWaveformCursor(e) { + const rect = this.dom.waveformContainer.getBoundingClientRect(); + const mouseX = e.clientX - rect.left; + const scrollLeft = this.dom.timelineContent.scrollLeft; + const timeBeats = (scrollLeft + mouseX - this.TIMELINE_LEFT_PADDING) / this.state.pixelsPerSecond; + const timeSeconds = timeBeats * 60.0 / this.state.bpm; + + // Position cursor + this.dom.waveformCursor.style.left = `${mouseX}px`; + + // Position and update tooltip + const tooltipText = `${timeSeconds.toFixed(3)}s (${timeBeats.toFixed(2)}b)`; + this.dom.waveformTooltip.textContent = tooltipText; + + // Position tooltip above cursor, offset to the right + const tooltipX = mouseX + 10; + const tooltipY = 5; + this.dom.waveformTooltip.style.left = `${tooltipX}px`; + this.dom.waveformTooltip.style.top = `${tooltipY}px`; + } + // Helper timeToBeats(seconds) { return seconds * this.state.bpm / 60.0; -- cgit v1.2.3