diff --git a/tl/src/tl/views.cljs b/tl/src/tl/views.cljs index 716c2d7..f33a055 100644 --- a/tl/src/tl/views.cljs +++ b/tl/src/tl/views.cljs @@ -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})))))))