From 4a1870d1d0cc4676797add05762ed196decd339d Mon Sep 17 00:00:00 2001 From: skal Date: Thu, 12 Feb 2026 08:44:42 +0100 Subject: feat: timeline editor playback improvements - Add red bar playback indicator on waveform (synced with timeline) - Fix playback continuation after double-click seek (async/await) - Improve stopPlayback() to preserve jump positions - Add error handling to startPlayback() - Update waveform click-to-seek to match double-click behavior - Sync waveform indicator scroll with timeline - Display time in both seconds and beats on seek - Update documentation with new features handoff(Claude): Timeline editor now has dual playback indicators and seamless seeking. Co-Authored-By: Claude Sonnet 4.5 --- tools/timeline_editor/README.md | 32 ++++- tools/timeline_editor/ROADMAP.md | 40 +++--- tools/timeline_editor/index.html | 261 ++++++++++++++++++++++++++++++--------- 3 files changed, 250 insertions(+), 83 deletions(-) diff --git a/tools/timeline_editor/README.md b/tools/timeline_editor/README.md index 6e368cf..4fcb2f4 100644 --- a/tools/timeline_editor/README.md +++ b/tools/timeline_editor/README.md @@ -18,19 +18,24 @@ Interactive web-based editor for `timeline.seq` files. - 🎛️ BPM slider (60-200 BPM) - 🔄 Re-order sequences by time - 🗑️ Delete sequences/effects -- ▶️ **Audio playback with auto-expand/collapse** (NEW) -- 🎚️ **Sticky audio track and timeline ticks** (NEW) +- ▶️ Audio playback with auto-expand/collapse +- 🎚️ Sticky audio track and timeline ticks +- 🔴 **Playback indicator on waveform** (NEW) +- 🎯 **Double-click seek during playback** (NEW) +- 📍 **Click waveform to seek** (NEW) ## Usage 1. **Open:** `open tools/timeline_editor/index.html` or double-click in browser 2. **Load timeline:** Click "📂 Load timeline.seq" → select `workspaces/main/timeline.seq` 3. **Load audio:** Click "🎵 Load Audio (WAV)" → select audio file +4. **Auto-load via URL:** `index.html?seq=timeline.seq&wav=audio.wav` 4. **Playback:** - Click "▶ Play" or press **Spacebar** to play/pause - - Click waveform to seek + - Click waveform to seek to position + - **Double-click timeline** to seek during playback (continues playing) - Watch sequences auto-expand/collapse during playback - - Red playback indicator shows current position + - Red playback indicators on both timeline and waveform show current position 5. **Edit:** - Drag sequences/effects to reposition - Double-click sequence header to collapse/expand @@ -78,9 +83,26 @@ SEQUENCE 2.5s 0 "Explicit seconds" # Rare: start at 2.5 physical seconds EFFECT + Fade 0 4 # Still uses beats for duration ``` +## URL Parameters + +Auto-load files on page load: +``` +index.html?seq=../../workspaces/main/timeline.seq&wav=../../audio/track.wav +``` + +**Parameters:** +- `seq` - Path to `.seq` file (relative or absolute URL) +- `wav` - Path to `.wav` audio file (relative or absolute URL) + +**Example:** +```bash +open "tools/timeline_editor/index.html?seq=../../workspaces/main/timeline.seq" +``` + ## Keyboard Shortcuts - **Spacebar**: Play/pause audio playback +- **Double-click timeline**: Seek to position (continues playing if active) - **Ctrl/Cmd + Wheel**: Zoom in/out at cursor position ## Technical Notes @@ -97,3 +119,5 @@ SEQUENCE 2.5s 0 "Explicit seconds" # Rare: start at 2.5 physical seconds - Snap-to-beat enabled by default for musical alignment - **Auto-expand/collapse**: Active sequence expands during playback, previous collapses - **Auto-scroll**: Timeline follows playback indicator (keeps it in middle third of viewport) +- **Dual playback indicators**: Red bars on both timeline and waveform (synchronized) +- **Seamless seek**: Double-click or waveform click seeks without stopping playback diff --git a/tools/timeline_editor/ROADMAP.md b/tools/timeline_editor/ROADMAP.md index 216adbf..b14a73b 100644 --- a/tools/timeline_editor/ROADMAP.md +++ b/tools/timeline_editor/ROADMAP.md @@ -8,30 +8,22 @@ This document outlines planned enhancements for the interactive timeline editor. ### Audio Playback Integration Issues -1. **Audio waveform doesn't scale with zoom nor follow timeline** - - Waveform should horizontally sync with timeline ticks/sequences - - Should scale to match `pixelsPerSecond` zoom level - - Currently remains static regardless of zoom - -2. **Playback indicator doesn't follow zoom and height issues** - - Vertical red bar position calculation doesn't account for `pixelsPerSecond` - - Doesn't reach bottom when sequences have scrolled - - Needs to span full `timeline-content` height dynamically - -3. **Sequences overlap timeline at scroll origin** - - Some sequences still go behind timeline ticks - - Notably when wheel pans back to beginning (scrollLeft = 0) - - Need proper clipping or z-index management - -4. **Timeline and waveform should be fixed, not floating** - - Currently using sticky positioning - - Should use true fixed positioning at top - - Should remain stationary regardless of scroll - -5. **Status indicator causes reflow** - - Green status text appears/disappears causing layout shift - - Should be relocated to top or bottom as fixed/always-visible - - Prevents jarring reflow when messages appear +1. ~~**Audio waveform doesn't scale with zoom nor follow timeline**~~ ✅ FIXED + - Waveform now correctly syncs with timeline at all zoom levels + +2. ~~**Playback indicator doesn't follow zoom and height issues**~~ ✅ FIXED + - Red bar now dynamically spans full timeline height + - Position correctly accounts for pixelsPerSecond + +3. ~~**Sequences overlap timeline at scroll origin**~~ ✅ FIXED + - Proper padding prevents overlap with timeline border + +4. ~~**Timeline and waveform should be fixed, not floating**~~ ✅ FIXED + - Sticky header stays at top during scroll + +5. ~~**Status indicator causes reflow**~~ ✅ FIXED + - Messages now fixed positioned at top-right + - No layout shift when appearing/disappearing --- diff --git a/tools/timeline_editor/index.html b/tools/timeline_editor/index.html index c9385ad..b6e9223 100644 --- a/tools/timeline_editor/index.html +++ b/tools/timeline_editor/index.html @@ -105,7 +105,7 @@ .timeline-container { background: #252526; border-radius: 8px; - padding: 20px; + padding: 0; position: relative; height: calc(100vh - 280px); min-height: 500px; @@ -118,6 +118,7 @@ overflow-x: auto; overflow-y: auto; position: relative; + padding: 0 20px 20px 20px; /* Hide scrollbars while keeping scroll functionality */ scrollbar-width: none; /* Firefox */ -ms-overflow-style: none; /* IE/Edge */ @@ -134,10 +135,11 @@ } .sticky-header { - position: relative; + position: sticky; + top: 0; background: #252526; z-index: 100; - padding-bottom: 10px; + padding: 20px 20px 10px 20px; border-bottom: 2px solid #3c3c3c; flex-shrink: 0; } @@ -154,20 +156,27 @@ padding: 8px 12px; } - #waveformCanvas { + .waveform-container { position: relative; height: 80px; - width: 100%; + overflow: hidden; background: rgba(0, 0, 0, 0.3); border-radius: 4px; cursor: crosshair; } + #waveformCanvas { + position: absolute; + left: 0; + top: 0; + height: 80px; + display: block; + } + .playback-indicator { position: absolute; top: 0; width: 2px; - height: 100%; background: #f48771; box-shadow: 0 0 4px rgba(244, 135, 113, 0.8); pointer-events: none; @@ -476,12 +485,20 @@ color: #858585; } + #messageArea { + position: fixed; + top: 80px; + right: 20px; + z-index: 2000; + max-width: 400px; + } + .error { background: #5a1d1d; color: #f48771; padding: 10px; border-radius: 4px; - margin-bottom: 10px; + box-shadow: 0 2px 8px rgba(0,0,0,0.3); } .success { @@ -489,7 +506,7 @@ color: #89d185; padding: 10px; border-radius: 4px; - margin-bottom: 10px; + box-shadow: 0 2px 8px rgba(0,0,0,0.3); } @@ -519,6 +536,10 @@ 100% 120 +