diff options
Diffstat (limited to 'tools/timeline_editor/index.html')
| -rw-r--r-- | tools/timeline_editor/index.html | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/tools/timeline_editor/index.html b/tools/timeline_editor/index.html index 4dd37ee..22e5239 100644 --- a/tools/timeline_editor/index.html +++ b/tools/timeline_editor/index.html @@ -16,11 +16,16 @@ background: #1e1e1e; color: #d4d4d4; padding: 20px; + margin: 0; + min-height: 100vh; + box-sizing: border-box; } .container { - max-width: 1400px; + max-width: 100%; + width: 100%; margin: 0 auto; + box-sizing: border-box; } header { @@ -393,6 +398,7 @@ // DOM elements const timeline = document.getElementById('timeline'); + const timelineContainer = document.querySelector('.timeline-container'); const fileInput = document.getElementById('fileInput'); const saveBtn = document.getElementById('saveBtn'); const addSequenceBtn = document.getElementById('addSequenceBtn'); @@ -573,30 +579,37 @@ seqDiv.className = 'sequence'; seqDiv.dataset.index = seqIndex; - // Calculate sequence duration based on effects - let seqDuration = 10; // Default + // Calculate sequence bounds based on effects (dynamic start/end) + let seqVisualStart = seq.startTime; + let seqVisualEnd = seq.startTime + 10; // Default 10s duration + if (seq.effects.length > 0) { - seqDuration = Math.max(...seq.effects.map(e => e.endTime)); + const minEffectStart = Math.min(...seq.effects.map(e => e.startTime)); + const maxEffectEnd = Math.max(...seq.effects.map(e => e.endTime)); + seqVisualStart = seq.startTime + minEffectStart; + seqVisualEnd = seq.startTime + maxEffectEnd; } + const seqVisualWidth = seqVisualEnd - seqVisualStart; + // Calculate sequence height based on number of effects (stacked vertically) const numEffects = seq.effects.length; const effectSpacing = 30; // Reduced from 40px const seqHeight = Math.max(70, 20 + numEffects * effectSpacing + 5); - seqDiv.style.left = `${seq.startTime * pixelsPerSecond}px`; + seqDiv.style.left = `${seqVisualStart * pixelsPerSecond}px`; seqDiv.style.top = `${seqIndex * 80}px`; - seqDiv.style.width = `${seqDuration * pixelsPerSecond}px`; + seqDiv.style.width = `${seqVisualWidth * pixelsPerSecond}px`; seqDiv.style.height = `${seqHeight}px`; - // Format time display based on mode + // Format time display based on mode (show visual start, not seq.startTime) let seqTimeDisplay; if (showBeats) { const beatDuration = 60.0 / bpm; - const startBeat = (seq.startTime / beatDuration).toFixed(1); + const startBeat = (seqVisualStart / beatDuration).toFixed(1); seqTimeDisplay = `Start: ${startBeat}b`; } else { - seqTimeDisplay = `Start: ${seq.startTime.toFixed(2)}s`; + seqTimeDisplay = `Start: ${seqVisualStart.toFixed(2)}s`; } // Create sequence name overlay (large, centered, fades on hover) @@ -916,6 +929,17 @@ updateProperties(); }); + // Mouse wheel horizontal scroll + timelineContainer.addEventListener('wheel', (e) => { + e.preventDefault(); + timelineContainer.scrollLeft += e.deltaY; + }, { passive: false }); + + // Window resize handler + window.addEventListener('resize', () => { + renderTimeline(); + }); + // Utilities function showMessage(text, type) { messageArea.innerHTML = `<div class="${type}">${text}</div>`; |
