fix: scale time ruler tick marks to prevent overlap, use HH:MM:SS format
Dynamically calculate tick intervals to maintain ~80px minimum spacing between marks regardless of zoom level. Prevents overlapping labels at high zoom. Change time format from adaptive (m/s/·) to consistent HH:MM:SS or MM:SS format. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
d93b92f4a5
commit
1cdb0de042
1 changed files with 16 additions and 15 deletions
|
|
@ -305,29 +305,30 @@
|
|||
|
||||
;; --- timeline ruler -------------------------------------------------------
|
||||
|
||||
(defn- format-time-hhmmss [seconds]
|
||||
"Format seconds as HH:MM:SS or MM:SS if < 1 hour"
|
||||
(let [h (int (/ seconds 3600))
|
||||
m (int (mod (/ seconds 60) 60))
|
||||
s (int (mod seconds 60))]
|
||||
(if (> h 0)
|
||||
(str h ":" (if (< m 10) "0" "") m ":" (if (< s 10) "0" "") s)
|
||||
(str m ":" (if (< s 10) "0" "") s))))
|
||||
|
||||
(defn- time-ruler [len fps zoom]
|
||||
"Generate tick marks and labels for the timeline ruler.
|
||||
Returns a vector of {:frame :px :label} with major/minor ticks."
|
||||
Scales tick intervals to maintain ~80px minimum spacing and uses HH:MM:SS format."
|
||||
(let [px-per-sec (* fps zoom)
|
||||
;; choose tick interval in frames based on zoom level
|
||||
tick-frames (cond
|
||||
(< px-per-sec 10) (* 30 fps) ; 30 sec intervals
|
||||
(< px-per-sec 20) (* 10 fps) ; 10 sec intervals
|
||||
(< px-per-sec 40) (* 5 fps) ; 5 sec intervals
|
||||
(< px-per-sec 80) fps ; 1 sec intervals
|
||||
:else (/ fps 2)) ; 0.5 sec intervals
|
||||
sec-per-tick (/ tick-frames fps)]
|
||||
;; Ensure minimum ~80px between ticks for readability
|
||||
min-px-spacing 80
|
||||
;; Calculate tick interval in seconds that gives good spacing
|
||||
sec-per-tick (js/Math.max 0.5 (js/Math.ceil (/ min-px-spacing px-per-sec)))
|
||||
tick-frames (* sec-per-tick fps)]
|
||||
(loop [frame 0 tick-num 0 ticks []]
|
||||
(if (>= frame len)
|
||||
ticks
|
||||
(let [px (* (/ frame fps) zoom)
|
||||
total-sec (* tick-num sec-per-tick)
|
||||
label (cond
|
||||
(>= sec-per-tick 10) (let [m (int (/ total-sec 60))
|
||||
s (int (mod total-sec 60))]
|
||||
(if (> s 0) (str m ":" (if (< s 10) "0" "") s) (str m "m")))
|
||||
(>= sec-per-tick 1) (str (int total-sec) "s")
|
||||
:else (str (js/Math.round (* total-sec 10)) "·"))]
|
||||
label (format-time-hhmmss total-sec)]
|
||||
(recur (+ frame tick-frames) (inc tick-num)
|
||||
(conj ticks {:frame frame :px px :label label})))))))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue