mirror of
https://github.com/penpot/penpot.git
synced 2025-05-11 19:36:38 +02:00
✨ Improved performance for auto-width/auto-height texts
This commit is contained in:
parent
29b1b4dbc9
commit
32350bcf87
12 changed files with 112 additions and 53 deletions
|
@ -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]
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))))
|
||||
|
|
|
@ -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]
|
||||
(dch/update-shapes
|
||||
[id]
|
||||
(fn [shape]
|
||||
(let [{:keys [width height]} modifiers]
|
||||
(-> shape
|
||||
(assoc :content content)
|
||||
(merge modifiers)
|
||||
(cts/setup-rect-selrect))))
|
||||
(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]
|
||||
{shape-width :width shape-height :height} selrect
|
||||
|
||||
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))
|
||||
(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)))))]
|
||||
(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
|
||||
[]
|
||||
|
|
|
@ -258,6 +258,8 @@
|
|||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(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)
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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])]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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!
|
||||
(->> (uw/ask-buffered!
|
||||
{:cmd :selection/query
|
||||
:page-id page-id
|
||||
:rect rect
|
||||
:include-frames? true
|
||||
:clip-children? (not mod?)})))))
|
||||
: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
|
||||
|
|
|
@ -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]
|
||||
|
@ -20,8 +21,10 @@
|
|||
[props]
|
||||
(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]
|
||||
(let [modifier (get modifiers (:id shape))]
|
||||
[:& outline {:key (str "outline-" (:id shape))
|
||||
:shape shape
|
||||
:modifier modifier
|
||||
:zoom zoom
|
||||
:color color}])))
|
||||
: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}]]))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue