Add performance oriented refactor to the outline component

This commit is contained in:
Andrey Antukh 2023-07-28 16:38:28 +02:00
parent c3eb90b1fa
commit b616a20b28

View file

@ -7,8 +7,10 @@
(ns app.main.ui.workspace.viewport.outline (ns app.main.ui.workspace.viewport.outline
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.pages.helpers :as cph]
[app.common.types.container :as ctn] [app.common.types.container :as ctn]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
@ -16,83 +18,95 @@
[app.util.object :as obj] [app.util.object :as obj]
[app.util.path.format :as upf] [app.util.path.format :as upf]
[clojure.set :as set] [clojure.set :as set]
[rumext.v2 :as mf] [rumext.v2 :as mf]))
[rumext.v2.util :refer [map->obj]]))
(mf/defc outline (mf/defc outline
{::mf/wrap-props false} {::mf/wrap-props false}
[props] [props]
(let [shape (obj/get props "shape") (let [shape (unchecked-get props "shape")
zoom (obj/get props "zoom" 1) modifier (unchecked-get props "modifier")
modifier (obj/get props "modifier")
shape (gsh/transform-shape shape (:modifiers modifier)) zoom (d/nilv (unchecked-get props "zoom") 1)
shape (gsh/transform-shape shape (:modifiers modifier))
transform (gsh/transform-str shape) transform (gsh/transform-str shape)
path? (= :path (:type shape))
path-data
(mf/use-memo
(mf/deps shape)
#(when path?
(or (ex/ignoring (upf/format-path (:content shape)))
"")))
;; Note that we don't use mf/deref to avoid a repaint dependency here
objects (deref refs/workspace-page-objects)
;; NOTE: that we don't use mf/deref to avoid a repaint dependency here
objects (deref refs/workspace-page-objects)
color (if (ctn/in-any-component? objects shape) color (if (ctn/in-any-component? objects shape)
"var(--color-component-highlight)" "var(--color-component-highlight)"
"var(--color-primary)") "var(--color-primary)")
{:keys [x y width height selrect]} shape x (dm/get-prop shape :x)
y (dm/get-prop shape :y)
width (dm/get-prop shape :width)
height (dm/get-prop shape :height)
selrect (dm/get-prop shape :selrect)
type (dm/get-prop shape :type)
content (get shape :content)
path? (cph/path-shape? shape)
border-radius-attrs (attrs/extract-border-radius shape) path-data
(mf/with-memo [path? content]
(when (and ^boolean path? (some? content))
(d/nilv (ex/ignoring (upf/format-path content)) "")))
path? (some? (.-d border-radius-attrs)) border-attrs
(attrs/extract-border-radius shape)
outline-type (case (:type shape) outline-type
:circle "ellipse" (case type
:path "path" :circle "ellipse"
(if path? "path" "rect")) :path "path"
(if (some? (obj/get border-attrs "d"))
"path"
"rect"))
common {:fill "none" props
:stroke color (obj/merge!
:strokeWidth (/ 2 zoom) #js {:fill "none"
:pointerEvents "none" :stroke color
:transform transform} :strokeWidth (/ 2 zoom)
:pointerEvents "none"
:transform transform}
props (case (:type shape) (case type
:circle :circle
{:cx (+ x (/ width 2)) #js {:cx (+ x (/ width 2))
:cy (+ y (/ height 2)) :cy (+ y (/ height 2))
:rx (/ width 2) :rx (/ width 2)
:ry (/ height 2)} :ry (/ height 2)}
:path :path
{:d path-data #js {:d path-data
:transform nil} :transform nil}
{:x (:x selrect) (let [x (dm/get-prop selrect :x)
:y (:y selrect) y (dm/get-prop selrect :y)
:width (:width selrect) w (dm/get-prop selrect :width)
:height (:height selrect) h (dm/get-prop selrect :height)]
:rx (.-rx border-radius-attrs) #js {:x x
:ry (.-ry border-radius-attrs) :y y
:d (.-d border-radius-attrs)})] :width w
:height h
:rx (obj/get border-attrs "rx")
:ry (obj/get border-attrs "ry")
:d (obj/get border-attrs "d")})))
]
[:> outline-type (map->obj (merge common props))])) [:> outline-type props]))
(mf/defc shape-outlines-render (mf/defc shape-outlines-render
{::mf/wrap-props false {::mf/wrap-props false
::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "zoom" "modifiers"]))]} ::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "zoom" "modifiers"]))]}
[props] [props]
(let [shapes (unchecked-get props "shapes")
(let [shapes (obj/get props "shapes") zoom (unchecked-get props "zoom")
zoom (obj/get props "zoom") modifiers (unchecked-get props "modifiers")]
modifiers (obj/get props "modifiers")]
(for [shape shapes] (for [shape shapes]
(let [modifier (get modifiers (:id shape))] (let [shape-id (dm/get-prop shape :id)
[:& outline {:key (str "outline-" (:id shape)) modifier (get modifiers shape-id)]
[:& outline {:key (dm/str "outline-" shape-id)
:shape shape :shape shape
:modifier modifier :modifier modifier
:zoom zoom}])))) :zoom zoom}]))))