mirror of
https://github.com/penpot/penpot.git
synced 2025-05-30 15:36:11 +02:00
✨ Mainly cosmetic and performance improvements on shape render.
This commit is contained in:
parent
a3c583af1d
commit
c5f4ae2242
6 changed files with 80 additions and 67 deletions
|
@ -31,6 +31,7 @@
|
|||
[app.main.ui.workspace.shapes.path :as path]
|
||||
[app.main.ui.workspace.shapes.text :as text]
|
||||
[app.util.object :as obj]
|
||||
[app.util.debug :refer [debug?]]
|
||||
[beicon.core :as rx]
|
||||
[okulary.core :as l]
|
||||
[rumext.alpha :as mf]))
|
||||
|
@ -44,15 +45,17 @@
|
|||
|
||||
(defn- shape-wrapper-memo-equals?
|
||||
[np op]
|
||||
(let [n-shape (obj/get np "shape")
|
||||
o-shape (obj/get op "shape")
|
||||
n-frame (obj/get np "frame")
|
||||
o-frame (obj/get op "frame")]
|
||||
;; (prn "shape-wrapper-memo-equals?" (identical? n-frame o-frame))
|
||||
(let [n-shape (obj/get np "shape")]
|
||||
(if (= (:type n-shape) :group)
|
||||
false
|
||||
(and (identical? n-shape o-shape)
|
||||
(identical? n-frame o-frame)))))
|
||||
(let [o-shape (obj/get op "shape")
|
||||
n-frame (obj/get np "frame")
|
||||
o-frame (obj/get op "frame")
|
||||
n-ghost (obj/get np "ghost?")
|
||||
o-ghost (obj/get op "ghost?")]
|
||||
(and (identical? n-shape o-shape)
|
||||
(identical? n-frame o-frame)
|
||||
(identical? n-ghost o-ghost))))))
|
||||
|
||||
(defn make-is-moving-ref
|
||||
[id]
|
||||
|
@ -94,7 +97,9 @@
|
|||
;; Only used when drawing a new frame.
|
||||
:frame [:> frame-wrapper {:shape shape}]
|
||||
nil)
|
||||
[:& bounding-box {:shape shape :frame frame}]])))
|
||||
|
||||
(when (debug? :bounding-boxes)
|
||||
[:& bounding-box {:shape shape :frame frame}])])))
|
||||
|
||||
(def group-wrapper (group/group-wrapper-factory shape-wrapper))
|
||||
(def frame-wrapper (frame/frame-wrapper-factory shape-wrapper))
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
:fill "transparent"
|
||||
:stroke-width "1px"
|
||||
:stroke-opacity 0.5
|
||||
:stroke-dasharray 4
|
||||
:stroke-dasharray 4
|
||||
:pointer-events "none"}}])
|
||||
|
||||
(mf/defc render-rect-points [{:keys [points color]}]
|
||||
|
@ -59,37 +59,36 @@
|
|||
(mf/defc bounding-box
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(when (debug? :bounding-boxes)
|
||||
(let [shape (-> (unchecked-get props "shape"))
|
||||
frame (unchecked-get props "frame")
|
||||
selrect (gsh/points->selrect (-> shape :points))
|
||||
shape-center (gsh/center-shape shape)
|
||||
line-color (rdcolor #js {:seed (str (:id shape))})
|
||||
zoom (mf/deref refs/selected-zoom)
|
||||
childs-ref (mf/use-memo (mf/deps shape) #(refs/objects-by-id (:shapes shape)))
|
||||
childs (->> (mf/deref childs-ref)
|
||||
(map gsh/transform-shape))]
|
||||
(let [shape (-> (unchecked-get props "shape"))
|
||||
frame (unchecked-get props "frame")
|
||||
selrect (gsh/points->selrect (-> shape :points))
|
||||
shape-center (gsh/center-shape shape)
|
||||
line-color (rdcolor #js {:seed (str (:id shape))})
|
||||
zoom (mf/deref refs/selected-zoom)
|
||||
childs-ref (mf/use-memo (mf/deps shape) #(refs/objects-by-id (:shapes shape)))
|
||||
childs (->> (mf/deref childs-ref)
|
||||
(map gsh/transform-shape))]
|
||||
|
||||
[:g.bounding-box
|
||||
[:text {:x (:x selrect)
|
||||
:y (- (:y selrect) 5)
|
||||
:font-size 10
|
||||
:fill line-color
|
||||
:stroke "white"
|
||||
:stroke-width 0.1}
|
||||
(str/format "%s - (%s, %s)" (str/slice (str (:id shape)) 0 8) (fixed (:x shape)) (fixed (:y shape)))]
|
||||
[:g.bounding-box
|
||||
[:text {:x (:x selrect)
|
||||
:y (- (:y selrect) 5)
|
||||
:font-size 10
|
||||
:fill line-color
|
||||
:stroke "white"
|
||||
:stroke-width 0.1}
|
||||
(str/format "%s - (%s, %s)" (str/slice (str (:id shape)) 0 8) (fixed (:x shape)) (fixed (:y shape)))]
|
||||
|
||||
[:& cross-point {:point shape-center
|
||||
[:& cross-point {:point shape-center
|
||||
:zoom zoom
|
||||
:color line-color}]
|
||||
|
||||
(for [point (:points shape)]
|
||||
[:& cross-point {:point point
|
||||
:zoom zoom
|
||||
:color line-color}]
|
||||
:color line-color}])
|
||||
|
||||
(for [point (:points shape)]
|
||||
[:& cross-point {:point point
|
||||
:zoom zoom
|
||||
:color line-color}])
|
||||
[:& render-rect-points {:rect selrect
|
||||
:color line-color}]
|
||||
|
||||
[:& render-rect-points {:rect selrect
|
||||
:color line-color}]
|
||||
|
||||
[:& render-rect {:rect selrect
|
||||
:color line-color}]])))
|
||||
[:& render-rect {:rect selrect
|
||||
:color line-color}]]))
|
||||
|
|
|
@ -68,10 +68,10 @@
|
|||
|
||||
(mf/defc frame-title
|
||||
[{:keys [frame]}]
|
||||
(let [zoom (mf/deref refs/selected-zoom)
|
||||
{:keys [width x y]} frame
|
||||
label-pos (gpt/point x (- y (/ 10 zoom)))
|
||||
handle-click (use-select-shape frame)
|
||||
(let [{:keys [width x y]} frame
|
||||
zoom (mf/deref refs/selected-zoom)
|
||||
label-pos (gpt/point x (- y (/ 10 zoom)))
|
||||
handle-click (use-select-shape frame)
|
||||
handle-pointer-enter (we/use-pointer-enter frame)
|
||||
handle-pointer-leave (we/use-pointer-leave frame)]
|
||||
[:text {:x 0
|
||||
|
@ -92,33 +92,47 @@
|
|||
(contains? (:selected local) id)))]
|
||||
(l/derived check-moving refs/workspace-local)))
|
||||
|
||||
;; This custom deffered don't deffer rendering when ghost rendering is
|
||||
;; used.
|
||||
(defn custom-deferred
|
||||
[component]
|
||||
(mf/fnc deferred
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [tmp (mf/useState false)
|
||||
^boolean render? (aget tmp 0)
|
||||
^js set-render (aget tmp 1)]
|
||||
(mf/use-layout-effect (fn [] (ts/schedule-on-idle #(set-render true))))
|
||||
(if (unchecked-get props "ghost?")
|
||||
(mf/create-element component props)
|
||||
(when render? (mf/create-element component props))))))
|
||||
|
||||
(defn frame-wrapper-factory
|
||||
[shape-wrapper]
|
||||
(let [frame-shape (frame/frame-shape shape-wrapper)]
|
||||
(mf/fnc frame-wrapper
|
||||
{::mf/wrap [#(mf/memo' % frame-wrapper-factory-equals?)
|
||||
#(mf/deferred % ts/schedule-on-idle)]
|
||||
{::mf/wrap [#(mf/memo' % frame-wrapper-factory-equals?) custom-deferred]
|
||||
::mf/wrap-props false}
|
||||
[props]
|
||||
(let [shape (unchecked-get props "shape")
|
||||
objects (unchecked-get props "objects")
|
||||
ghost? (unchecked-get props "ghost?")
|
||||
ghost? (unchecked-get props "ghost?")
|
||||
|
||||
moving-iref (mf/use-memo (mf/deps (:id shape))
|
||||
#(make-is-moving-ref (:id shape)))
|
||||
moving? (mf/deref moving-iref)
|
||||
moving-iref (mf/use-memo (mf/deps (:id shape))
|
||||
#(make-is-moving-ref (:id shape)))
|
||||
moving? (mf/deref moving-iref)
|
||||
|
||||
selected-iref (mf/use-memo (mf/deps (:id shape))
|
||||
#(refs/make-selected-ref (:id shape)))
|
||||
selected? (mf/deref selected-iref)
|
||||
selected? (mf/deref selected-iref)
|
||||
|
||||
shape (gsh/transform-shape shape)
|
||||
children (mapv #(get objects %) (:shapes shape))
|
||||
ds-modifier (get-in shape [:modifiers :displacement])
|
||||
shape (gsh/transform-shape shape)
|
||||
children (mapv #(get objects %) (:shapes shape))
|
||||
ds-modifier (get-in shape [:modifiers :displacement])
|
||||
|
||||
handle-context-menu (we/use-context-menu shape)
|
||||
handle-double-click (use-select-shape shape)
|
||||
handle-mouse-down (we/use-mouse-down shape)]
|
||||
handle-mouse-down (we/use-mouse-down shape)]
|
||||
|
||||
(when (and shape
|
||||
(or ghost? (not moving?))
|
||||
|
|
|
@ -167,6 +167,7 @@
|
|||
shapes (if ids
|
||||
(->> ids (map #(get objects %)))
|
||||
shapes)]
|
||||
|
||||
[:*
|
||||
[:g.shapes
|
||||
(for [item shapes]
|
||||
|
|
|
@ -16,7 +16,11 @@
|
|||
(defn debug! [option] (swap! *debug* conj option))
|
||||
(defn -debug! [option] (swap! *debug* disj option))
|
||||
|
||||
(defn ^:export debug? [option] (@*debug* option))
|
||||
(defn ^:export ^boolean debug?
|
||||
[option]
|
||||
(if *assert*
|
||||
(boolean (@*debug* option))
|
||||
false))
|
||||
|
||||
(defn ^:export toggle-debug [name] (let [option (keyword name)]
|
||||
(if (debug? option)
|
||||
|
@ -28,7 +32,7 @@
|
|||
(defn ^:export tap
|
||||
"Transducer function that can execute a side-effect `effect-fn` per input"
|
||||
[effect-fn]
|
||||
|
||||
|
||||
(fn [rf]
|
||||
(fn
|
||||
([] (rf))
|
||||
|
|
|
@ -27,16 +27,6 @@
|
|||
;; percentiles of render time measures. The log function is
|
||||
;; automatically debouced for avod excesive spam to the console.
|
||||
|
||||
;; #?(:clj
|
||||
;; (defmacro with-measure
|
||||
;; [name & body]
|
||||
;; `(let [start# (js/performance.now)
|
||||
;; res# (do ~@body)
|
||||
;; end# (js/performance.now)
|
||||
;; time# (.toFixed (- end# start#) 2)]
|
||||
;; (println (str "[perf|" ~name "] => " time#))
|
||||
;; res#)))
|
||||
|
||||
(defn tdigest
|
||||
[]
|
||||
(specify! (td/TDigest.)
|
||||
|
@ -111,7 +101,7 @@
|
|||
(mf/deps label)
|
||||
#(on-render-factory label))]
|
||||
(if enabled?
|
||||
[:> react/Profiler {:id label
|
||||
:on-render on-render}
|
||||
[:> react/Profiler #js {:id label
|
||||
:onRender on-render}
|
||||
children]
|
||||
children)))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue