From 194a47a99b3e3ae03c085721e94e5dd5b9a9f460 Mon Sep 17 00:00:00 2001 From: skal Date: Thu, 5 Feb 2026 21:41:37 +0100 Subject: feat(timeline-editor): Diagonal scroll following time-ordered sequence cascade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enhancement: Smart Vertical Scrolling - Mouse wheel now scrolls diagonally (horizontal + vertical) - Automatically brings relevant sequence to top-left of viewport - Follows the time-ordered cascade of sequences Algorithm: 1. Scroll horizontally as before (timeline.scrollLeft += deltaY) 2. Calculate current time position (left edge of viewport) currentTime = scrollLeft / pixelsPerSecond 3. Find closest sequence at that time: - Last sequence that starts before or at currentTime - Sequences sorted by startTime 4. Smooth scroll vertically to target sequence: - targetScrollTop = seqIndex * 80px - Smooth transition: scrollTop += diff * 0.3 (not instant jump) User Experience: - Scroll forward in time → later sequences move to top - Scroll backward in time → earlier sequences move to top - Creates natural "diagonal" navigation along timeline - Top-left corner always shows the most relevant sequence Example timeline: Seq 0 (0s) ────────────── Seq 1 (5s) ────────────── Seq 2 (10s) ────────────── Scroll to 7s → Seq 1 moves to top (it's active at that time) Scroll to 12s → Seq 2 moves to top (it's active at that time) This provides intuitive navigation through time-ordered sequences. --- tools/timeline_editor/index.html | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/timeline_editor/index.html b/tools/timeline_editor/index.html index 22e5239..ea8b454 100644 --- a/tools/timeline_editor/index.html +++ b/tools/timeline_editor/index.html @@ -929,10 +929,37 @@ updateProperties(); }); - // Mouse wheel horizontal scroll + // Mouse wheel diagonal scroll (follows time-ordered sequence cascade) timelineContainer.addEventListener('wheel', (e) => { e.preventDefault(); + + // Horizontal scroll timelineContainer.scrollLeft += e.deltaY; + + // Calculate current time position (left edge of viewport) + const currentScrollLeft = timelineContainer.scrollLeft; + const currentTime = currentScrollLeft / pixelsPerSecond; + + // Find the closest sequence that should be visible at current time + // (the last sequence that starts before or at current time) + let targetSeqIndex = 0; + for (let i = 0; i < sequences.length; i++) { + if (sequences[i].startTime <= currentTime) { + targetSeqIndex = i; + } else { + break; + } + } + + // Smooth vertical scroll to bring target sequence to top of viewport + const targetScrollTop = targetSeqIndex * 80; // 80px per sequence + const currentScrollTop = timelineContainer.scrollTop; + const scrollDiff = targetScrollTop - currentScrollTop; + + // Smooth transition (don't jump instantly) + if (Math.abs(scrollDiff) > 5) { + timelineContainer.scrollTop += scrollDiff * 0.3; + } }, { passive: false }); // Window resize handler -- cgit v1.2.3