0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-10 08:50:57 -05:00

Improved performance for options and area selection

This commit is contained in:
alonso.torres 2021-11-29 22:01:39 +01:00
parent 3bbcd235e1
commit b05908a760
5 changed files with 77 additions and 38 deletions

View file

@ -65,27 +65,33 @@
(watch [_ state stream]
(let [zoom (get-in state [:workspace-local :zoom] 1)
stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
stoper (->> stream (rx/filter stop?))]
stoper (->> stream (rx/filter stop?))
calculate-selrect
(fn [data pos]
(if data
(assoc data :stop pos)
{:start pos :stop pos}))
selrect-stream
(->> ms/mouse-position
(rx/scan calculate-selrect nil)
(rx/map data->selrect)
(rx/filter #(or (> (:width %) (/ 10 zoom))
(> (:height %) (/ 10 zoom))))
(rx/take-until stoper))]
(rx/concat
(when-not preserve?
(rx/of (deselect-all)))
(->> ms/mouse-position
(rx/scan (fn [data pos]
(if data
(assoc data :stop pos)
{:start pos :stop pos}))
nil)
(rx/map data->selrect)
(rx/filter #(or (> (:width %) (/ 10 zoom))
(> (:height %) (/ 10 zoom))))
(if preserve?
(rx/empty)
(rx/of (deselect-all)))
(rx/flat-map
(fn [selrect]
(rx/of (update-selrect selrect)
(select-shapes-by-current-selrect preserve?))))
(rx/merge
(->> selrect-stream (rx/map update-selrect))
(->> selrect-stream
(rx/debounce 50)
(rx/map #(select-shapes-by-current-selrect preserve?))))
(rx/take-until stoper))
(rx/of (update-selrect nil))))))))
(rx/of (update-selrect nil))))))))
;; --- Toggle shape's selection status (selected or deselected)
@ -221,11 +227,13 @@
selrect (get-in state [:workspace-local :selrect])
blocked? (fn [id] (get-in objects [id :blocked] false))]
(when selrect
(->> (uw/ask! {:cmd :selection/query
:page-id page-id
:rect selrect
:include-frames? true
:full-frame? true})
(rx/empty)
(->> (uw/ask-buffered!
{:cmd :selection/query
:page-id page-id
:rect selrect
:include-frames? true
:full-frame? true})
(rx/map #(cp/clean-loops objects %))
(rx/map #(into initial-set (filter (comp not blocked?)) %))
(rx/map select-shapes)))))))

View file

@ -247,7 +247,7 @@
(gsh/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect)]
(cond-> modif-tree
(not (empty? (d/without-keys child-modifiers [:ignore-geometry?])))
(d/not-empty? (d/without-keys child-modifiers [:ignore-geometry?]))
(set-modifiers-recursive objects
child
child-modifiers

View file

@ -59,7 +59,6 @@
[:& thumbnail {:shape shape}]
[:rect {:x x :y y :width width :height height :style {:fill (or fill-color "white")}}])))
;; used.
(defn custom-deferred
[component]
(mf/fnc deferred

View file

@ -19,6 +19,7 @@
[app.util.keyboard :as kbd]
[app.util.object :as obj]
[app.util.timers :as ts]
[beicon.core :as rx]
[cuerdas.core :as str]
[okulary.core :as l]
[rumext.alpha :as mf]))
@ -205,8 +206,12 @@
(mf/use-effect
(mf/deps selected)
(fn []
(when (and (= (count selected) 1) selected?)
(.scrollIntoView (mf/ref-val dref) #js {:block "nearest", :behavior "smooth"}))))
(let [subid
(when (and (= (count selected) 1) selected?)
(ts/schedule-on-idle
#(.scrollIntoView (mf/ref-val dref) #js {:block "nearest", :behavior "smooth"})))]
#(when (some? subid)
(rx/dispose! subid)))))
[:li {:on-context-menu on-context-menu
:ref dref

View file

@ -9,6 +9,7 @@
[app.common.attrs :as attrs]
[app.common.data :as d]
[app.common.text :as txt]
[app.main.ui.hooks :as hooks]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-attrs blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs fill-menu]]
@ -189,6 +190,14 @@
(def get-attrs (memoize get-attrs*))
(defn basic-shape [_ shape]
(cond-> shape
:always
(dissoc :selrect :points :x :y :width :height :transform :transform-inverse :rotation :svg-transform :svg-viewbox :thumbnail)
(= (:type shape) :path)
(dissoc :content)))
(mf/defc options
{::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "shapes-with-children"]))]
::mf/wrap-props false}
@ -197,18 +206,36 @@
shapes-with-children (unchecked-get props "shapes-with-children")
objects (->> shapes-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
type :multiple
[measure-ids measure-values] (get-attrs shapes objects :measure)
[layer-ids layer-values] (get-attrs shapes objects :layer)
[constraint-ids constraint-values] (get-attrs shapes objects :constraint)
[fill-ids fill-values] (get-attrs shapes objects :fill)
[shadow-ids shadow-values] (get-attrs shapes objects :shadow)
[blur-ids blur-values] (get-attrs shapes objects :blur)
[stroke-ids stroke-values] (get-attrs shapes objects :stroke)
;; Selrect/points only used for measures and it's the one that changes the most. We separate it
;; so we can memoize it
objects-no-measures (->> objects (d/mapm basic-shape))
objects-no-measures (hooks/use-equal-memo objects-no-measures)
;; FIXME: Improve performance
[text-ids text-values] (get-attrs shapes objects :text)
]
type :multiple
[measure-ids measure-values] (get-attrs shapes objects :measure)
[layer-ids layer-values
constraint-ids constraint-values
fill-ids fill-values
shadow-ids shadow-values
blur-ids blur-values
stroke-ids stroke-values
text-ids text-values]
(mf/use-memo
(mf/deps objects-no-measures)
(fn []
(into
[]
(mapcat identity)
[(get-attrs shapes objects-no-measures :layer)
(get-attrs shapes objects-no-measures :constraint)
(get-attrs shapes objects-no-measures :fill)
(get-attrs shapes objects-no-measures :shadow)
(get-attrs shapes objects-no-measures :shadow)
(get-attrs shapes objects-no-measures :stroke)
(get-attrs shapes objects-no-measures :text)])))]
[:div.options
(when-not (empty? measure-ids)