diff --git a/frontend/src/app/main/data/event.cljs b/frontend/src/app/main/data/event.cljs index b8c439f553..aa9df88085 100644 --- a/frontend/src/app/main/data/event.cljs +++ b/frontend/src/app/main/data/event.cljs @@ -23,6 +23,7 @@ [app.util.object :as obj] [app.util.perf :as perf] [app.util.storage :as storage] + [app.util.timers :as timers] [beicon.v2.core :as rx] [beicon.v2.operators :as rxo] [cuerdas.core :as str] @@ -216,7 +217,7 @@ (rx/create (fn [subs] (let [start (perf/now)] - (js/requestAnimationFrame + (timers/raf #(.postTask js/scheduler (fn [] (let [time (- (perf/now) start)] diff --git a/frontend/src/app/main/data/workspace/thumbnails_wasm.cljs b/frontend/src/app/main/data/workspace/thumbnails_wasm.cljs index 507714578c..612bdd2e53 100644 --- a/frontend/src/app/main/data/workspace/thumbnails_wasm.cljs +++ b/frontend/src/app/main/data/workspace/thumbnails_wasm.cljs @@ -25,6 +25,7 @@ [app.main.repo :as rp] [app.main.store :as st] [app.render-wasm.api :as wasm.api] + [app.util.timers :as timers] [app.util.webapi :as wapi] [beicon.v2.core :as rx] [cuerdas.core :as str] @@ -58,7 +59,7 @@ (rx/create (fn [subs] (let [req-id - (js/requestAnimationFrame + (timers/raf (fn [_] (try (let [objects (dsh/lookup-page-objects @st/state file-id page-id)] @@ -83,7 +84,7 @@ (rx/error! subs "Frame not found"))) (catch :default err (rx/error! subs err)))))] - #(js/cancelAnimationFrame req-id))))) + #(timers/cancel-af! req-id))))) (defn render-thumbnail "Renders a component thumbnail via WASM and updates the UI immediately. diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs index 10e9638cf2..3eb9a4f939 100644 --- a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs +++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs @@ -322,7 +322,7 @@ (let [trigger-el (mf/ref-val trigger-ref) tooltip-el (mf/ref-val tooltip-ref)] (when (and trigger-el tooltip-el) - (js/requestAnimationFrame + (ts/raf (fn [] (let [origin-brect (dom/get-bounding-rect trigger-el) tooltip-brect (dom/get-bounding-rect tooltip-el) diff --git a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/floating_dropdown.cljs b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/floating_dropdown.cljs index d7cf90a3f3..cddb3b9eb4 100644 --- a/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/floating_dropdown.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/management/forms/controls/floating_dropdown.cljs @@ -7,6 +7,7 @@ (ns app.main.ui.workspace.tokens.management.forms.controls.floating-dropdown (:require [app.util.dom :as dom] + [app.util.timers :as timers] [rumext.v2 :as mf])) (defn use-floating-dropdown [is-open input-wrapper-ref outer-wrapper-ref dropdown-ref] @@ -48,7 +49,7 @@ (when is-open (let [recalculate (fn [] - (js/requestAnimationFrame + (timers/raf (fn [] (let [input-node (mf/ref-val input-wrapper-ref)] (calculate-position input-node))))) diff --git a/frontend/src/app/main/ui/workspace/viewport/pixel_overlay.cljs b/frontend/src/app/main/ui/workspace/viewport/pixel_overlay.cljs index 1cf70067a6..89f1f9737c 100644 --- a/frontend/src/app/main/ui/workspace/viewport/pixel_overlay.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/pixel_overlay.cljs @@ -22,6 +22,7 @@ [app.util.globals :as ug] [app.util.keyboard :as kbd] [app.util.object :as obj] + [app.util.timers :as timers] [beicon.v2.core :as rx] [goog.events :as events] [rumext.v2 :as mf])) @@ -96,7 +97,7 @@ ;; Store latest color synchronously so the click handler always reads ;; the correct pixel even before the rAF fires (fixes race condition) (mf/set-ref-val! last-picked-color color) - (js/requestAnimationFrame + (timers/raf (fn [] (st/emit! (dwc/pick-color color)))))))))) @@ -304,7 +305,7 @@ ;; the correct pixel even before the rAF fires (fixes race condition) (mf/set-ref-val! last-picked-color color) ;; rAF throttles state updates to avoid an infinite React re-render loop - (js/requestAnimationFrame + (timers/raf (fn [] (st/emit! (dwc/pick-color color)))))))))) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index f3b6cdc244..6924456411 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -53,6 +53,7 @@ [app.util.i18n :refer [tr]] [app.util.modules :as mod] [app.util.text.content :as tc] + [app.util.timers :as timers] [beicon.v2.core :as rx] [cuerdas.core :as str] [promesa.core :as p] @@ -398,7 +399,7 @@ (when-not @pending-render (reset! pending-render true) (let [frame-id - (js/requestAnimationFrame + (timers/raf (fn [ts] (reset! pending-render false) (set! wasm/internal-frame-id nil) @@ -1708,7 +1709,7 @@ [] (p/create (fn [resolve _reject] - (js/requestAnimationFrame (fn [] (resolve nil)))))) + (timers/raf (fn [] (resolve nil)))))) (def ^:private default-context-options #js {:antialias false @@ -1878,7 +1879,7 @@ ;; Cancel any pending animation frame to prevent race conditions. (when wasm/internal-frame-id - (js/cancelAnimationFrame wasm/internal-frame-id)) + (timers/cancel-af! wasm/internal-frame-id)) ;; Reset render flags to prevent new renders from being scheduled. (reset! pending-render false) diff --git a/frontend/src/app/util/timers.cljs b/frontend/src/app/util/timers.cljs index f943d35457..afc7e79daf 100644 --- a/frontend/src/app/util/timers.cljs +++ b/frontend/src/app/util/timers.cljs @@ -65,11 +65,20 @@ #(.requestAnimationFrame js/globalThis %) #(js/setTimeout % 16))) +(def ^:private cancel-animation-frame + (if (and (exists? js/globalThis) + (exists? (.-cancelAnimationFrame js/globalThis))) + #(.cancelAnimationFrame js/globalThis %) + #(js/clearTimeout %))) + (defn raf [f] (^function request-animation-frame f)) +(defn cancel-af! + [frame-id] + (^function cancel-animation-frame frame-id)) + (defn idle-then-raf [f] (schedule-on-idle #(^function raf f))) -