mirror of
https://github.com/penpot/penpot.git
synced 2026-06-17 21:02:05 +00:00
⚡ Capture snapshot only when needed and downscaled
This commit is contained in:
parent
12e7ea038f
commit
1ba43c863a
@ -86,10 +86,6 @@
|
||||
(defonce transition-image-url* (atom nil))
|
||||
(defonce transition-epoch* (atom 0))
|
||||
(defonce transition-tiles-handler* (atom nil))
|
||||
(defonce snapshot-tiles-handler* (atom nil))
|
||||
|
||||
(def ^:private snapshot-capture-debounce-ms 250)
|
||||
|
||||
|
||||
(defn initialized?
|
||||
"True when the WASM render context is ready to receive design-state
|
||||
@ -173,31 +169,6 @@
|
||||
(f))
|
||||
#js {:once true}))
|
||||
|
||||
(defonce ^:private schedule-canvas-snapshot-capture!
|
||||
(fns/debounce
|
||||
(fn []
|
||||
(when (and (initialized?)
|
||||
(some? wasm/canvas))
|
||||
(-> (webgl/capture-canvas-snapshot-url)
|
||||
(p/catch (fn [_] nil)))))
|
||||
snapshot-capture-debounce-ms))
|
||||
|
||||
(defn- start-canvas-snapshot-listener!
|
||||
[]
|
||||
(when-let [prev @snapshot-tiles-handler*]
|
||||
(.removeEventListener ^js ug/document "penpot:wasm:tiles-complete" prev))
|
||||
(let [handler (fn [_] (schedule-canvas-snapshot-capture!))]
|
||||
(reset! snapshot-tiles-handler* handler)
|
||||
(.addEventListener ^js ug/document "penpot:wasm:tiles-complete" handler)))
|
||||
|
||||
(defn- stop-canvas-snapshot-listener!
|
||||
[]
|
||||
(when-let [prev @snapshot-tiles-handler*]
|
||||
(.removeEventListener ^js ug/document "penpot:wasm:tiles-complete" prev))
|
||||
(reset! snapshot-tiles-handler* nil)
|
||||
(when-let [cancel (unchecked-get schedule-canvas-snapshot-capture! "cancel")]
|
||||
(cancel)))
|
||||
|
||||
(defn text-editor-wasm?
|
||||
[]
|
||||
(or (contains? cf/flags :feature-text-editor-wasm)
|
||||
@ -2072,7 +2043,6 @@
|
||||
(when can-listen?
|
||||
(.addEventListener canvas "webglcontextlost" on-webgl-context-lost)
|
||||
(.addEventListener canvas "webglcontextrestored" on-webgl-context-restored))
|
||||
(start-canvas-snapshot-listener!)
|
||||
(reset! wasm/context-lost? false)
|
||||
(set! wasm/context-initialized? true)))
|
||||
|
||||
@ -2099,7 +2069,6 @@
|
||||
(when wasm/canvas
|
||||
(.removeEventListener wasm/canvas "webglcontextlost" on-webgl-context-lost)
|
||||
(.removeEventListener wasm/canvas "webglcontextrestored" on-webgl-context-restored))
|
||||
(stop-canvas-snapshot-listener!)
|
||||
|
||||
(when (wasm/module-ready?)
|
||||
(free-gpu-resources)
|
||||
|
||||
@ -134,11 +134,24 @@ void main() {
|
||||
(.bindTexture ^js gl (.-TEXTURE_2D ^js gl) nil)
|
||||
(.deleteTexture ^js gl texture))))
|
||||
|
||||
(defn capture-canvas-snapshot-url
|
||||
"Captures the current viewport canvas as a PNG `blob:` URL and stores it in
|
||||
`wasm/canvas-snapshot-url`.
|
||||
;; Codec for the transition snapshot. The snapshot is only ever shown as a
|
||||
;; heavily-blurred overlay (see TRANSITION_BLUR_RADIUS), so a lossy, alpha-capable
|
||||
;; codec is fine and encodes much faster than lossless PNG -- on a full-viewport
|
||||
;; canvas, PNG `toBlob` of millions of pixels costs ~1s+ on the main thread.
|
||||
;; WebP keeps the alpha channel (unlike JPEG) and encodes in a fraction of that.
|
||||
(def ^:private SNAPSHOT_MIME "image/webp")
|
||||
(def ^:private SNAPSHOT_QUALITY 0.6)
|
||||
|
||||
Returns a promise resolving to the URL string (or nil)."
|
||||
;; The snapshot is only shown heavily blurred, so it is downscaled to this max
|
||||
;; side before encoding to keep the WebP encode cheap on big/high-DPI canvases.
|
||||
(def ^:private SNAPSHOT_MAX_DIM 1024)
|
||||
|
||||
(defonce ^:private snapshot-scratch-canvas
|
||||
(delay (js/document.createElement "canvas")))
|
||||
|
||||
(defn capture-canvas-snapshot-url
|
||||
"Captures the current viewport canvas as a downscaled WebP `blob:` URL and
|
||||
stores it in `wasm/canvas-snapshot-url`. Returns a promise of the URL or nil."
|
||||
[]
|
||||
(if-let [^js canvas wasm/canvas]
|
||||
(p/create
|
||||
@ -148,14 +161,26 @@ void main() {
|
||||
(when (and (string? prev) (.startsWith ^js prev "blob:"))
|
||||
(js/URL.revokeObjectURL prev)))
|
||||
(set! wasm/canvas-snapshot-url nil)
|
||||
(.toBlob canvas
|
||||
(fn [^js blob]
|
||||
(if blob
|
||||
(let [url (js/URL.createObjectURL blob)]
|
||||
(set! wasm/canvas-snapshot-url url)
|
||||
(resolve url))
|
||||
(resolve nil)))
|
||||
"image/png")))
|
||||
(let [cw (.-width canvas)
|
||||
ch (.-height canvas)
|
||||
;; Cap the longest side to SNAPSHOT_MAX_DIM (never upscale).
|
||||
scale (min 1.0 (/ SNAPSHOT_MAX_DIM (max 1 cw ch)))
|
||||
tw (max 1 (js/Math.round (* cw scale)))
|
||||
th (max 1 (js/Math.round (* ch scale)))
|
||||
^js sc @snapshot-scratch-canvas
|
||||
^js ctx (.getContext sc "2d")]
|
||||
(set! (.-width sc) tw)
|
||||
(set! (.-height sc) th)
|
||||
(.drawImage ctx canvas 0 0 tw th)
|
||||
(.toBlob sc
|
||||
(fn [^js blob]
|
||||
(if blob
|
||||
(let [url (js/URL.createObjectURL blob)]
|
||||
(set! wasm/canvas-snapshot-url url)
|
||||
(resolve url))
|
||||
(resolve nil)))
|
||||
SNAPSHOT_MIME
|
||||
SNAPSHOT_QUALITY))))
|
||||
(p/resolved nil)))
|
||||
|
||||
(defn draw-thumbnail-to-canvas
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user