mirror of
https://github.com/penpot/penpot.git
synced 2026-09-10 05:58:47 +00:00
🐛 Fix WASM viewport interaction lifecycle for pan/zoom
This commit is contained in:
parent
97c8fcd4ad
commit
9ebf7875ea
@ -1578,6 +1578,7 @@
|
|||||||
(dm/export dwv/initialize-viewport)
|
(dm/export dwv/initialize-viewport)
|
||||||
(dm/export dwv/update-viewport-position)
|
(dm/export dwv/update-viewport-position)
|
||||||
(dm/export dwv/update-viewport-size)
|
(dm/export dwv/update-viewport-size)
|
||||||
|
(dm/export dwv/sync-wasm-workspace-viewport)
|
||||||
(dm/export dwv/start-panning)
|
(dm/export dwv/start-panning)
|
||||||
(dm/export dwv/finish-panning)
|
(dm/export dwv/finish-panning)
|
||||||
|
|
||||||
|
|||||||
@ -16,13 +16,19 @@
|
|||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.helpers :as dsh]
|
[app.main.data.helpers :as dsh]
|
||||||
|
[app.main.data.workspace.viewport-wasm :as dwvw]
|
||||||
[app.util.mouse :as mse]
|
[app.util.mouse :as mse]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
(defn- render-context-lost?
|
(defn sync-wasm-workspace-viewport
|
||||||
[state]
|
"Effect-only: pushes the current workspace zoom/view box to WASM after other
|
||||||
(true? (get-in state [:render-state :lost])))
|
events (e.g. `update-viewport-size`) have updated the store."
|
||||||
|
[]
|
||||||
|
(ptk/reify ::sync-wasm-workspace-viewport
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state))))
|
||||||
|
|
||||||
(defn initialize-viewport
|
(defn initialize-viewport
|
||||||
[{:keys [width height] :as size}]
|
[{:keys [width height] :as size}]
|
||||||
@ -86,7 +92,11 @@
|
|||||||
(update [_ state]
|
(update [_ state]
|
||||||
(update state :workspace-local
|
(update state :workspace-local
|
||||||
(fn [local]
|
(fn [local]
|
||||||
(setup state local)))))))
|
(setup state local))))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state)))))
|
||||||
|
|
||||||
(defn calculate-centered-viewbox
|
(defn calculate-centered-viewbox
|
||||||
"Updates the viewbox coordinates for a given center position"
|
"Updates the viewbox coordinates for a given center position"
|
||||||
@ -105,9 +115,13 @@
|
|||||||
(ptk/reify ::update-viewport-position-center
|
(ptk/reify ::update-viewport-position-center
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (render-context-lost? state)
|
(if (dwvw/render-context-lost? state)
|
||||||
state
|
state
|
||||||
(update state :workspace-local calculate-centered-viewbox position)))))
|
(update state :workspace-local calculate-centered-viewbox position)))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state))))
|
||||||
|
|
||||||
(defn update-viewport-position
|
(defn update-viewport-position
|
||||||
[{:keys [x y] :or {x identity y identity}}]
|
[{:keys [x y] :or {x identity y identity}}]
|
||||||
@ -124,13 +138,17 @@
|
|||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (render-context-lost? state)
|
(if (dwvw/render-context-lost? state)
|
||||||
state
|
state
|
||||||
(update-in state [:workspace-local :vbox]
|
(update-in state [:workspace-local :vbox]
|
||||||
(fn [vbox]
|
(fn [vbox]
|
||||||
(-> vbox
|
(-> vbox
|
||||||
(update :x x)
|
(update :x x)
|
||||||
(update :y y))))))))
|
(update :y y))))))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state))))
|
||||||
|
|
||||||
(defn update-viewport-size
|
(defn update-viewport-size
|
||||||
[resize-type {:keys [width height] :as size}]
|
[resize-type {:keys [width height] :as size}]
|
||||||
@ -174,16 +192,27 @@
|
|||||||
(assoc-in [:vbox :width] vbox-width')
|
(assoc-in [:vbox :width] vbox-width')
|
||||||
(assoc-in [:vbox :height] vbox-height')))))))))
|
(assoc-in [:vbox :height] vbox-height')))))))))
|
||||||
|
|
||||||
|
(defn- activate-panning []
|
||||||
|
(ptk/reify ::activate-panning
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(-> state
|
||||||
|
(assoc-in [:workspace-local :panning] true)))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-view-interaction-start! state))))
|
||||||
|
|
||||||
(defn start-panning []
|
(defn start-panning []
|
||||||
(ptk/reify ::start-panning
|
(ptk/reify ::start-panning
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [stopper (->> stream (rx/filter (ptk/type? ::finish-panning)))
|
(let [stopper (->> stream (rx/filter (ptk/type? ::finish-panning)))
|
||||||
zoom (get-in state [:workspace-local :zoom])]
|
zoom (get-in state [:workspace-local :zoom])]
|
||||||
(when (and (not (render-context-lost? state))
|
(when (and (not (dwvw/render-context-lost? state))
|
||||||
(not (get-in state [:workspace-local :panning])))
|
(not (get-in state [:workspace-local :panning])))
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of #(-> % (assoc-in [:workspace-local :panning] true)))
|
(rx/of (activate-panning))
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter mse/pointer-event?)
|
(rx/filter mse/pointer-event?)
|
||||||
(rx/filter #(some? (mse/get-pointer-movement %)))
|
(rx/filter #(some? (mse/get-pointer-movement %)))
|
||||||
@ -200,4 +229,8 @@
|
|||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(-> state
|
||||||
(update :workspace-local dissoc :panning)))))
|
(update :workspace-local dissoc :panning)))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-view-interaction-end! state))))
|
||||||
|
|||||||
30
frontend/src/app/main/data/workspace/viewport_wasm.cljs
Normal file
30
frontend/src/app/main/data/workspace/viewport_wasm.cljs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.main.data.workspace.viewport-wasm
|
||||||
|
(:require
|
||||||
|
[app.main.features :as features]
|
||||||
|
[app.render-wasm.api :as wasm.api]))
|
||||||
|
|
||||||
|
(defn render-context-lost?
|
||||||
|
[state]
|
||||||
|
(true? (get-in state [:render-state :lost])))
|
||||||
|
|
||||||
|
(defn maybe-sync-workspace-local-viewport!
|
||||||
|
"When `render-wasm/v1` is active, pushes workspace zoom and vbox into WASM."
|
||||||
|
[state]
|
||||||
|
(when (and (features/active-feature? state "render-wasm/v1") (not (render-context-lost? state)))
|
||||||
|
(wasm.api/sync-workspace-local-viewport! state)))
|
||||||
|
|
||||||
|
(defn maybe-view-interaction-start!
|
||||||
|
[state]
|
||||||
|
(when (and (features/active-feature? state "render-wasm/v1") (not (render-context-lost? state)))
|
||||||
|
(wasm.api/view-interaction-start!)))
|
||||||
|
|
||||||
|
(defn maybe-view-interaction-end!
|
||||||
|
[state]
|
||||||
|
(when (and (features/active-feature? state "render-wasm/v1") (not (render-context-lost? state)))
|
||||||
|
(wasm.api/view-interaction-end!)))
|
||||||
@ -16,15 +16,12 @@
|
|||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.main.data.event :as ev]
|
[app.main.data.event :as ev]
|
||||||
[app.main.data.helpers :as dsh]
|
[app.main.data.helpers :as dsh]
|
||||||
|
[app.main.data.workspace.viewport-wasm :as dwvw]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.mouse :as mse]
|
[app.util.mouse :as mse]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
(defn- render-context-lost?
|
|
||||||
[state]
|
|
||||||
(true? (get-in state [:render-state :lost])))
|
|
||||||
|
|
||||||
(defn impl-update-zoom
|
(defn impl-update-zoom
|
||||||
[{:keys [vbox] :as local} center zoom]
|
[{:keys [vbox] :as local} center zoom]
|
||||||
(let [new-zoom (if (fn? zoom) (zoom (:zoom local)) zoom)
|
(let [new-zoom (if (fn? zoom) (zoom (:zoom local)) zoom)
|
||||||
@ -47,11 +44,15 @@
|
|||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (render-context-lost? state)
|
(if (dwvw/render-context-lost? state)
|
||||||
state
|
state
|
||||||
(let [center (if (= center ::auto) @ms/mouse-position center)]
|
(let [center (if (= center ::auto) @ms/mouse-position center)]
|
||||||
(update state :workspace-local
|
(update state :workspace-local
|
||||||
#(impl-update-zoom % center (fn [z] (min (* z 1.3) 200))))))))))
|
#(impl-update-zoom % center (fn [z] (min (* z 1.3) 200)))))))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state)))))
|
||||||
|
|
||||||
(defn decrease-zoom
|
(defn decrease-zoom
|
||||||
([]
|
([]
|
||||||
@ -62,11 +63,15 @@
|
|||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (render-context-lost? state)
|
(if (dwvw/render-context-lost? state)
|
||||||
state
|
state
|
||||||
(let [center (if (= center ::auto) @ms/mouse-position center)]
|
(let [center (if (= center ::auto) @ms/mouse-position center)]
|
||||||
(update state :workspace-local
|
(update state :workspace-local
|
||||||
#(impl-update-zoom % center (fn [z] (max (/ z 1.3) 0.01))))))))))
|
#(impl-update-zoom % center (fn [z] (max (/ z 1.3) 0.01)))))))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state)))))
|
||||||
|
|
||||||
(defn set-zoom
|
(defn set-zoom
|
||||||
([scale]
|
([scale]
|
||||||
@ -77,7 +82,7 @@
|
|||||||
|
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (render-context-lost? state)
|
(if (dwvw/render-context-lost? state)
|
||||||
state
|
state
|
||||||
(let [vp (dm/get-in state [:workspace-local :vbox])
|
(let [vp (dm/get-in state [:workspace-local :vbox])
|
||||||
x (+ (:x vp) (/ (:width vp) 2))
|
x (+ (:x vp) (/ (:width vp) 2))
|
||||||
@ -86,22 +91,30 @@
|
|||||||
(update state :workspace-local
|
(update state :workspace-local
|
||||||
#(impl-update-zoom % center (fn [z] (-> (* z scale)
|
#(impl-update-zoom % center (fn [z] (-> (* z scale)
|
||||||
(max 0.01)
|
(max 0.01)
|
||||||
(min 200)))))))))))
|
(min 200))))))))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state)))))
|
||||||
|
|
||||||
(def reset-zoom
|
(def reset-zoom
|
||||||
(ptk/reify ::reset-zoom
|
(ptk/reify ::reset-zoom
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (render-context-lost? state)
|
(if (dwvw/render-context-lost? state)
|
||||||
state
|
state
|
||||||
(update state :workspace-local
|
(update state :workspace-local
|
||||||
#(impl-update-zoom % nil 1))))))
|
#(impl-update-zoom % nil 1))))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state))))
|
||||||
|
|
||||||
(def zoom-to-fit-all
|
(def zoom-to-fit-all
|
||||||
(ptk/reify ::zoom-to-fit-all
|
(ptk/reify ::zoom-to-fit-all
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (render-context-lost? state)
|
(if (dwvw/render-context-lost? state)
|
||||||
state
|
state
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (dsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
@ -116,13 +129,17 @@
|
|||||||
(-> local
|
(-> local
|
||||||
(assoc :zoom zoom)
|
(assoc :zoom zoom)
|
||||||
(assoc :zoom-inverse (/ 1 zoom))
|
(assoc :zoom-inverse (/ 1 zoom))
|
||||||
(update :vbox merge srect)))))))))))
|
(update :vbox merge srect)))))))))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state))))
|
||||||
|
|
||||||
(def zoom-to-selected-shape
|
(def zoom-to-selected-shape
|
||||||
(ptk/reify ::zoom-to-selected-shape
|
(ptk/reify ::zoom-to-selected-shape
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (render-context-lost? state)
|
(if (dwvw/render-context-lost? state)
|
||||||
state
|
state
|
||||||
(let [selected (dsh/lookup-selected state)]
|
(let [selected (dsh/lookup-selected state)]
|
||||||
(if (empty? selected)
|
(if (empty? selected)
|
||||||
@ -139,14 +156,18 @@
|
|||||||
(-> local
|
(-> local
|
||||||
(assoc :zoom zoom)
|
(assoc :zoom zoom)
|
||||||
(assoc :zoom-inverse (/ 1 zoom))
|
(assoc :zoom-inverse (/ 1 zoom))
|
||||||
(update :vbox merge srect))))))))))))
|
(update :vbox merge srect))))))))))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state))))
|
||||||
|
|
||||||
(defn fit-to-shapes
|
(defn fit-to-shapes
|
||||||
[ids]
|
[ids]
|
||||||
(ptk/reify ::fit-to-shapes
|
(ptk/reify ::fit-to-shapes
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(if (or (render-context-lost? state) (empty? ids))
|
(if (or (dwvw/render-context-lost? state) (empty? ids))
|
||||||
state
|
state
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (dsh/lookup-page-objects state page-id)
|
objects (dsh/lookup-page-objects state page-id)
|
||||||
@ -164,16 +185,21 @@
|
|||||||
(-> local
|
(-> local
|
||||||
(assoc :zoom zoom)
|
(assoc :zoom zoom)
|
||||||
(assoc :zoom-inverse (/ 1 zoom))
|
(assoc :zoom-inverse (/ 1 zoom))
|
||||||
(update :vbox merge srect))))))))))
|
(update :vbox merge srect))))))))
|
||||||
|
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-sync-workspace-local-viewport! state))))
|
||||||
|
|
||||||
(defn start-zooming [pt]
|
(defn start-zooming [pt]
|
||||||
(ptk/reify ::start-zooming
|
(ptk/reify ::start-zooming
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [stopper (->> stream (rx/filter (ptk/type? ::finish-zooming)))]
|
(let [stopper (->> stream (rx/filter (ptk/type? ::finish-zooming)))]
|
||||||
(when (and (not (render-context-lost? state))
|
(when (and (not (dwvw/render-context-lost? state))
|
||||||
(not (get-in state [:workspace-local :zooming])))
|
(not (get-in state [:workspace-local :zooming])))
|
||||||
(rx/concat
|
(rx/concat
|
||||||
|
(rx/of (fn [s] (dwvw/maybe-view-interaction-start! s) s))
|
||||||
(rx/of #(-> % (assoc-in [:workspace-local :zooming] true)))
|
(rx/of #(-> % (assoc-in [:workspace-local :zooming] true)))
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter mse/pointer-event?)
|
(rx/filter mse/pointer-event?)
|
||||||
@ -189,4 +215,7 @@
|
|||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(-> state
|
||||||
(update :workspace-local dissoc :zooming)))))
|
(update :workspace-local dissoc :zooming)))
|
||||||
|
ptk/EffectEvent
|
||||||
|
(effect [_ state _]
|
||||||
|
(dwvw/maybe-view-interaction-end! state))))
|
||||||
|
|||||||
@ -77,7 +77,8 @@
|
|||||||
(mf/deps vport)
|
(mf/deps vport)
|
||||||
(fn [resize-type size]
|
(fn [resize-type size]
|
||||||
(when (and vport (not= size vport))
|
(when (and vport (not= size vport))
|
||||||
(st/emit! (dw/update-viewport-size resize-type size)))))
|
(st/emit! (dw/update-viewport-size resize-type size)
|
||||||
|
(dw/sync-wasm-workspace-viewport)))))
|
||||||
|
|
||||||
on-resize-palette
|
on-resize-palette
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
|||||||
@ -436,7 +436,8 @@
|
|||||||
|
|
||||||
(mf/with-effect [vport]
|
(mf/with-effect [vport]
|
||||||
(when (and @canvas-init? @initialized?)
|
(when (and @canvas-init? @initialized?)
|
||||||
(wasm.api/resize-viewbox (:width vport) (:height vport))))
|
(wasm.api/resize-viewbox (:width vport) (:height vport))
|
||||||
|
(wasm.api/set-view-box zoom vbox)))
|
||||||
|
|
||||||
(mf/with-effect [@canvas-init? preview-blend]
|
(mf/with-effect [@canvas-init? preview-blend]
|
||||||
(when (and @canvas-init? preview-blend)
|
(when (and @canvas-init? preview-blend)
|
||||||
@ -467,10 +468,6 @@
|
|||||||
(wasm.api/clear-focus-mode)
|
(wasm.api/clear-focus-mode)
|
||||||
(wasm.api/set-focus-mode focus)))))
|
(wasm.api/set-focus-mode focus)))))
|
||||||
|
|
||||||
(mf/with-effect [vbox zoom]
|
|
||||||
(when (and @canvas-init? @initialized?)
|
|
||||||
(wasm.api/set-view-box zoom vbox)))
|
|
||||||
|
|
||||||
(mf/with-effect [background]
|
(mf/with-effect [background]
|
||||||
(when (and @canvas-init? @initialized?)
|
(when (and @canvas-init? @initialized?)
|
||||||
(wasm.api/set-canvas-background background)))
|
(wasm.api/set-canvas-background background)))
|
||||||
|
|||||||
@ -208,6 +208,8 @@
|
|||||||
|
|
||||||
(def ^:const DEBOUNCE_DELAY_MS 100)
|
(def ^:const DEBOUNCE_DELAY_MS 100)
|
||||||
|
|
||||||
|
(defonce ^:private view-interaction-active? (atom false))
|
||||||
|
|
||||||
;; Time budget (ms) per chunk of shape processing before yielding to browser
|
;; Time budget (ms) per chunk of shape processing before yielding to browser
|
||||||
(def ^:private ^:const CHUNK_TIME_BUDGET_MS 8)
|
(def ^:private ^:const CHUNK_TIME_BUDGET_MS 8)
|
||||||
;; Threshold below which we use synchronous processing (no chunking overhead)
|
;; Threshold below which we use synchronous processing (no chunking overhead)
|
||||||
@ -1146,14 +1148,26 @@
|
|||||||
(= result 1))
|
(= result 1))
|
||||||
false))
|
false))
|
||||||
|
|
||||||
|
(defn view-interaction-start!
|
||||||
|
[]
|
||||||
|
(when-not @view-interaction-active?
|
||||||
|
(h/call wasm/internal-module "_set_view_start")
|
||||||
|
(reset! view-interaction-active? true)))
|
||||||
|
|
||||||
|
(defn view-interaction-end!
|
||||||
|
[]
|
||||||
|
(when @view-interaction-active?
|
||||||
|
(perf/begin-measure "render-finish")
|
||||||
|
(h/call wasm/internal-module "_set_view_end")
|
||||||
|
(perf/end-measure "render-finish")
|
||||||
|
(reset! view-interaction-active? false)))
|
||||||
|
|
||||||
(def render-finish
|
(def render-finish
|
||||||
(letfn [(do-render []
|
(letfn [(do-render []
|
||||||
;; Check if context is still initialized before executing
|
;; Check if context is still initialized before executing
|
||||||
;; to prevent errors when navigating quickly
|
;; to prevent errors when navigating quickly
|
||||||
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
||||||
(perf/begin-measure "render-finish")
|
(view-interaction-end!)
|
||||||
(h/call wasm/internal-module "_set_view_end")
|
|
||||||
(perf/end-measure "render-finish")
|
|
||||||
;; Use async _render: visible tiles render synchronously
|
;; Use async _render: visible tiles render synchronously
|
||||||
;; (no yield), interest-area tiles render progressively
|
;; (no yield), interest-area tiles render progressively
|
||||||
;; via rAF. _set_view_end already rebuilt the tile
|
;; via rAF. _set_view_end already rebuilt the tile
|
||||||
@ -1167,7 +1181,7 @@
|
|||||||
(defn set-view-box
|
(defn set-view-box
|
||||||
[zoom vbox]
|
[zoom vbox]
|
||||||
(perf/begin-measure "set-view-box")
|
(perf/begin-measure "set-view-box")
|
||||||
(h/call wasm/internal-module "_set_view_start")
|
(view-interaction-start!)
|
||||||
(h/call wasm/internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
(h/call wasm/internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||||
(perf/end-measure "set-view-box")
|
(perf/end-measure "set-view-box")
|
||||||
|
|
||||||
@ -1176,6 +1190,16 @@
|
|||||||
(render-finish)
|
(render-finish)
|
||||||
(perf/end-measure "render-from-cache"))
|
(perf/end-measure "render-from-cache"))
|
||||||
|
|
||||||
|
(defn sync-workspace-local-viewport!
|
||||||
|
"Pushes `[:workspace-local :zoom]` and `:vbox` into WASM."
|
||||||
|
[state]
|
||||||
|
(when (and wasm/context-initialized?
|
||||||
|
(not @wasm/context-lost?))
|
||||||
|
(let [zoom (get-in state [:workspace-local :zoom])
|
||||||
|
vbox (get-in state [:workspace-local :vbox])]
|
||||||
|
(when (and zoom vbox)
|
||||||
|
(set-view-box zoom vbox)))))
|
||||||
|
|
||||||
(defn- ensure-text-content
|
(defn- ensure-text-content
|
||||||
"Guarantee that the shape always sends a valid text tree to WASM. When the
|
"Guarantee that the shape always sends a valid text tree to WASM. When the
|
||||||
content is nil (freshly created text) we fall back to
|
content is nil (freshly created text) we fall back to
|
||||||
@ -1344,6 +1368,7 @@
|
|||||||
;; Rebuild the tile index so _render knows which shapes
|
;; Rebuild the tile index so _render knows which shapes
|
||||||
;; map to which tiles after a page switch.
|
;; map to which tiles after a page switch.
|
||||||
(h/call wasm/internal-module "_set_view_end")
|
(h/call wasm/internal-module "_set_view_end")
|
||||||
|
(reset! view-interaction-active? false)
|
||||||
|
|
||||||
;; Text layouts must run after _end_loading (they
|
;; Text layouts must run after _end_loading (they
|
||||||
;; depend on state that is only correct when loading
|
;; depend on state that is only correct when loading
|
||||||
@ -1402,6 +1427,7 @@
|
|||||||
;; Rebuild the tile index so _render knows which shapes
|
;; Rebuild the tile index so _render knows which shapes
|
||||||
;; map to which tiles after a page switch.
|
;; map to which tiles after a page switch.
|
||||||
(h/call wasm/internal-module "_set_view_end")
|
(h/call wasm/internal-module "_set_view_end")
|
||||||
|
(reset! view-interaction-active? false)
|
||||||
(process-pending shapes thumbnails full
|
(process-pending shapes thumbnails full
|
||||||
(fn []
|
(fn []
|
||||||
(if render-callback
|
(if render-callback
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user