From 86d2449619a9c62909ccdf2548b0c143daf60881 Mon Sep 17 00:00:00 2001 From: Tadas Petra <60107328+tadaspetra@users.noreply.github.com> Date: Thu, 11 Jun 2026 14:32:04 -0500 Subject: [PATCH] Draggable playhead --- src/index.html | 29 ++++++++++++++++++++++++++--- src/renderer/app.ts | 21 +++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/index.html b/src/index.html index 04baf9c..f0f233e 100644 --- a/src/index.html +++ b/src/index.html @@ -372,6 +372,7 @@

R
+
@@ -404,6 +405,28 @@

R class="relative cursor-pointer select-none" style="min-width: 100%" > + +
+
+
+
+
@@ -438,11 +461,11 @@

R style="opacity: 0.65" >

- +

diff --git a/src/renderer/app.ts b/src/renderer/app.ts index b2aa5d2..ea8c92b 100644 --- a/src/renderer/app.ts +++ b/src/renderer/app.ts @@ -123,6 +123,8 @@ const editorTimelineWrapper = document.getElementById('editorTimelineWrapper'); const editorTimeline = document.getElementById('editorTimeline'); const editorSectionMarkers = document.getElementById('editorSectionMarkers'); const editorScrubber = document.getElementById('editorScrubber'); +const editorPlayhead = document.getElementById('editorPlayhead'); +const editorPlayheadRuler = document.getElementById('editorPlayheadRuler'); const editorCameraTrack = document.getElementById('editorCameraTrack'); const editorCameraMarkers = document.getElementById('editorCameraMarkers'); const cameraTrackLabel = document.getElementById('cameraTrackLabel'); @@ -4683,6 +4685,7 @@ function updateScrubberPosition() { if (!editorState || editorState.duration <= 0) return; const pct = (editorState.currentTime / editorState.duration) * 100; editorScrubber.style.left = pct + '%'; + if (editorPlayhead) editorPlayhead.style.left = pct + '%'; if (editorState.playing) scrollTimelineToPlayhead(); } @@ -5062,6 +5065,24 @@ function seekFromTimeline(e) { editorSeek(pct * editorState.duration); } +// Playhead ruler above the tracks: dedicated drag-to-scrub surface that cannot +// accidentally hit section clips or trim handles. +if (editorPlayheadRuler) { + editorPlayheadRuler.addEventListener('mousedown', (e) => { + if (!editorState || editorState.rendering) return; + e.preventDefault(); + e.stopPropagation(); + seekFromTimeline(e); + const onMove = (e2) => seekFromTimeline(e2); + const onUp = () => { + window.removeEventListener('mousemove', onMove); + window.removeEventListener('mouseup', onUp); + }; + window.addEventListener('mousemove', onMove); + window.addEventListener('mouseup', onUp); + }); +} + const SECTION_DRAG_THRESHOLD = 5; function getDragSelectedIds() {