Improved performance for auto-width/auto-height texts

This commit is contained in:
alonso.torres 2022-12-01 16:13:21 +01:00 committed by Alonso Torres
parent 29b1b4dbc9
commit 32350bcf87
12 changed files with 112 additions and 53 deletions

View file

@ -11,7 +11,7 @@
[app.common.math :as mth]
[app.common.types.shape.layout :as ctl]))
(defn- child-layout-bound-points
(defn child-layout-bound-points
"Returns the bounds of the children as points"
[parent child parent-bounds child-bounds]

View file

@ -12,7 +12,6 @@
[app.common.geom.shapes.constraints :as gct]
[app.common.geom.shapes.flex-layout :as gcl]
[app.common.geom.shapes.pixel-precision :as gpp]
[app.common.geom.shapes.points :as cpo]
[app.common.geom.shapes.points :as gpo]
[app.common.geom.shapes.transforms :as gtr]
[app.common.pages.helpers :as cph]
@ -158,7 +157,7 @@
children-bounds
(->> children
(mapv #(get-group-bounds objects bounds modif-tree %)))]
(cpo/merge-parent-coords-bounds children-bounds current-bounds))
(gpo/merge-parent-coords-bounds children-bounds current-bounds))
(cph/mask-shape? shape)
(get-group-bounds objects bounds modif-tree (-> children first))

View file

@ -384,6 +384,17 @@
(-> (empty)
(scale-content value)))
(defn change-size
[{:keys [selrect points transform transform-inverse] :as shape} width height]
(let [old-width (-> selrect :width)
old-height (-> selrect :height)
width (or width old-width)
height (or height old-height)
origin (first points)
scalex (/ width old-width)
scaley (/ height old-height)]
(resize-modifiers (gpt/point scalex scaley) origin transform transform-inverse)))
(defn change-dimensions-modifiers
[{:keys [transform transform-inverse] :as shape} attr value]
(us/assert map? shape)

View file

@ -375,7 +375,10 @@
"Initializes the selrect and points for a shape."
[shape]
(let [selrect (gsh/rect->selrect shape)
points (gsh/rect->points shape)]
points (gsh/rect->points shape)
points (cond-> points
(:transform shape)
(gsh/transform-points (gsh/center-points points) (:transform shape)))]
(-> shape
(assoc :selrect selrect
:points points))))

View file

@ -14,13 +14,12 @@
[app.common.pages.helpers :as cph]
[app.common.text :as txt]
[app.common.types.modifiers :as ctm]
[app.common.types.shape :as cts]
[app.common.uuid :as uuid]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.modifiers :as dwm]
[app.main.data.workspace.selection :as dws]
[app.main.data.workspace.shapes :as dwsh]
[app.main.data.workspace.shapes-update-layout :as dwul]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.undo :as dwu]
[app.util.router :as rt]
@ -74,11 +73,14 @@
(when (and (not= content (:content shape))
(some? (:current-page-id state)))
(rx/of
(dch/update-shapes [id] (fn [shape]
(-> shape
(assoc :content content)
(merge modifiers)
(cts/setup-rect-selrect))))
(dch/update-shapes
[id]
(fn [shape]
(let [{:keys [width height]} modifiers]
(-> shape
(assoc :content content)
(cond-> (or (some? width) (some? height))
(gsh/transform-shape (ctm/change-size shape width height)))))))
(dwu/commit-undo-transaction (:id shape))))))
(when (some? id)
@ -323,20 +325,25 @@
(let [shape (wsh/lookup-shape state id)]
(letfn [(update-fn [shape]
(let [{:keys [selrect grow-type]} shape
{shape-width :width shape-height :height} selrect]
(cond-> shape
(and (not-changed? shape-width new-width) (= grow-type :auto-width))
(gsh/transform-shape (ctm/change-dimensions-modifiers shape :width new-width))
{shape-width :width shape-height :height} selrect
(and (not-changed? shape-height new-height)
(or (= grow-type :auto-height) (= grow-type :auto-width)))
(gsh/transform-shape (ctm/change-dimensions-modifiers shape :height new-height)))))]
shape
(cond-> shape
(and (not-changed? shape-width new-width) (= grow-type :auto-width))
(gsh/transform-shape (ctm/change-dimensions-modifiers shape :width new-width)))
shape
(cond-> shape
(and (not-changed? shape-height new-height)
(or (= grow-type :auto-height) (= grow-type :auto-width)))
(gsh/transform-shape (ctm/change-dimensions-modifiers shape :height new-height)))]
shape))]
(when (or (and (not-changed? (:width shape) new-width) (= (:grow-type shape) :auto-width))
(and (not-changed? (:height shape) new-height)
(or (= (:grow-type shape) :auto-height) (= (:grow-type shape) :auto-width))))
(rx/of (dch/update-shapes [id] update-fn {:reg-objects? true :save-undo? false})
(dwul/update-layout-positions [id]))))))))
(rx/of (dch/update-shapes [id] update-fn {:reg-objects? true :save-undo? false}))))))))
(defn save-font
[data]
@ -385,7 +392,9 @@
(not (mth/close? (:width props) (:width shape))))
(and (some? (:height props))
(not (mth/close? (:height props) (:height shape)))))
(rx/of (dwul/update-layout-positions [id])))))))
(let [modif-tree (dwm/create-modif-tree [id] (ctm/reflow-modifiers))]
(rx/of (dwm/set-modifiers modif-tree))))))))
(defn clean-text-modifier
[id]
@ -401,7 +410,11 @@
(ptk/reify ::remove-text-modifier
ptk/UpdateEvent
(update [_ state]
(d/dissoc-in state [:workspace-text-modifier id]))))
(d/dissoc-in state [:workspace-text-modifier id]))
ptk/WatchEvent
(watch [_ _ _]
(rx/of (dwm/apply-modifiers)))))
(defn commit-position-data
[]

View file

@ -257,7 +257,9 @@
(mf/defc text-editor-svg
{::mf/wrap-props false}
[props]
(let [shape (obj/get props "shape")
(let [shape (obj/get props "shape")
modifiers (obj/get props "modifiers")
modifiers (get-in modifiers [(:id shape) :modifiers])
clip-id
(dm/str "text-edition-clip" (:id shape))
@ -270,7 +272,10 @@
shape (cond-> shape
(some? text-modifier)
(dwt/apply-text-modifier text-modifier))
(dwt/apply-text-modifier text-modifier)
(some? modifiers)
(gsh/transform-shape modifiers))
bounding-box (gsht/position-data-selrect shape)

View file

@ -12,14 +12,19 @@
[rumext.v2 :as mf]))
(mf/defc text-edition-outline
[{:keys [shape zoom]}]
(let [text-modifier-ref
[{:keys [shape zoom modifiers]}]
(let [modifiers (get-in modifiers [(:id shape) :modifiers])
text-modifier-ref
(mf/use-memo (mf/deps (:id shape)) #(refs/workspace-text-modifier-by-id (:id shape)))
text-modifier
(mf/deref text-modifier-ref)
shape (cond-> shape
(some? modifiers)
(gsh/transform-shape modifiers)
(some? text-modifier)
(dwt/apply-text-modifier text-modifier))

View file

@ -36,13 +36,11 @@
(dissoc :position-data)))
(defn fix-position [shape modifier]
(let [shape' (-> shape
(assoc :grow-type :fixed)
(gsh/transform-shape modifier))
(let [shape' (gsh/transform-shape shape modifier)
;; We need to remove the movement because the dynamic modifiers will have move it
deltav (gpt/to-vec (gpt/point (:selrect shape'))
(gpt/point (:selrect shape)))]
(gsh/transform-shape shape' (ctm/move-modifiers deltav))))
(gsh/transform-shape shape (ctm/move modifier deltav))))
(defn process-shape [modifiers {:keys [id] :as shape}]
(let [modifier (dm/get-in modifiers [id :modifiers])]

View file

@ -204,9 +204,9 @@
[:div.viewport-overlays
;; The behaviour inside a foreign object is a bit different that in plain HTML so we wrap
;; inside a foreign object "dummy" so this awkward behaviour is take into account
[:svg {:style {:top 0 :left 0 :position "fixed" :width "100%" :height "100%" :opacity 0}}
[:svg {:style {:top 0 :left 0 :position "fixed" :width "100%" :height "100%" :opacity (when-not (debug? :html-text) 0)}}
[:foreignObject {:x 0 :y 0 :width "100%" :height "100%"}
[:div {:style {:pointer-events "none"}}
[:div {:style {:pointer-events (when-not (debug? :html-text) "none")}}
[:& stvh/viewport-texts
{:key (dm/str "texts-" page-id)
:page-id page-id
@ -289,7 +289,8 @@
[:g {:style {:pointer-events (if disable-events? "none" "auto")}}
(when show-text-editor?
[:& editor/text-editor-svg {:shape editing-shape}])
[:& editor/text-editor-svg {:shape editing-shape
:modifiers modifiers}])
(when show-frame-outline?
[:& outline/shape-outlines
@ -298,7 +299,8 @@
(filter #(cph/frame-shape? (get base-objects %)))
(remove selected)
(first))}
:zoom zoom}])
:zoom zoom
:modifiers modifiers}])
(when show-outlines?
[:& outline/shape-outlines
@ -307,7 +309,8 @@
:hover #{(:id @hover) @frame-hover}
:highlighted highlighted
:edition edition
:zoom zoom}])
:zoom zoom
:modifiers modifiers}])
(when show-selection-handlers?
[:& selection/selection-area
@ -321,7 +324,8 @@
(when show-text-editor?
[:& text-edition-outline
{:shape (get base-objects edition)
:zoom zoom}])
:zoom zoom
:modifiers modifiers}])
(when show-measures?
[:& msr/measurement

View file

@ -130,12 +130,15 @@
rect (gsh/center->rect point (/ 5 zoom) (/ 5 zoom))]
(if (mf/ref-val hover-disabled-ref)
(rx/of nil)
(uw/ask-buffered!
{:cmd :selection/query
:page-id page-id
:rect rect
:include-frames? true
:clip-children? (not mod?)})))))
(->> (uw/ask-buffered!
{:cmd :selection/query
:page-id page-id
:rect rect
:include-frames? true
:clip-children? (not mod?)})
;; When the ask-buffered is canceled returns null. We filter them
;; to improve the behavior
(rx/filter some?))))))
over-shapes-stream
(mf/use-memo

View file

@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.exceptions :as ex]
[app.common.geom.shapes :as gsh]
[app.main.ui.hooks :as hooks]
[app.util.object :as obj]
[app.util.path.format :as upf]
[clojure.set :as set]
@ -18,10 +19,12 @@
(mf/defc outline
{::mf/wrap-props false}
[props]
(let [shape (obj/get props "shape")
zoom (obj/get props "zoom" 1)
(let [shape (obj/get props "shape")
zoom (obj/get props "zoom" 1)
color (obj/get props "color")
modifier (obj/get props "modifier")
color (unchecked-get props "color")
shape (gsh/transform-shape shape (:modifiers modifier))
transform (gsh/transform-str shape)
path? (= :path (:type shape))
path-data
@ -64,17 +67,22 @@
(mf/defc shape-outlines-render
{::mf/wrap-props false
::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "zoom"]))]}
::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "zoom" "modifiers"]))]}
[props]
(let [shapes (obj/get props "shapes")
zoom (obj/get props "zoom")
modifiers (obj/get props "modifiers")
color (if (or (> (count shapes) 1) (nil? (:shape-ref (first shapes))))
"var(--color-primary)" "var(--color-component-highlight)")]
(for [shape shapes]
[:& outline {:key (str "outline-" (:id shape))
:shape shape
:zoom zoom
:color color}])))
(let [modifier (get modifiers (:id shape))]
[:& outline {:key (str "outline-" (:id shape))
:shape shape
:modifier modifier
:zoom zoom
:color color}]))))
(defn- show-outline?
[shape]
@ -91,6 +99,7 @@
objects (obj/get props "objects")
edition (obj/get props "edition")
zoom (obj/get props "zoom")
modifiers (obj/get props "modifiers")
lookup (d/getf objects)
edition? (fn [o] (= edition o))
@ -102,7 +111,13 @@
(set/union selected hover))
(into (comp (remove edition?)
(keep lookup))
highlighted))]
highlighted))
modifiers (select-keys modifiers (map :id shapes))
modifiers (hooks/use-equal-memo modifiers)
shapes (hooks/use-equal-memo shapes)]
[:g.outlines
[:& shape-outlines-render {:shapes shapes :zoom zoom}]]))
[:& shape-outlines-render {:shapes shapes
:zoom zoom
:modifiers modifiers}]]))

View file

@ -83,6 +83,9 @@
;; Show the bounds relative to the parent
:parent-bounds
;; Show html text
:html-text
})
;; These events are excluded when we activate the :events flag