0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-14 08:41:48 -05:00

Performance improvements

This commit is contained in:
alonso.torres 2022-11-11 10:37:09 +01:00
parent 7b2f0303e8
commit efc1b87ab0
10 changed files with 292 additions and 129 deletions

View file

@ -263,3 +263,10 @@
matrix matrix
(translate-matrix (gpt/negate center)))) (translate-matrix (gpt/negate center))))
point)) point))
(defn move?
[{:keys [a b c d _ _]}]
(and (mth/almost-zero? (- a 1))
(mth/almost-zero? b)
(mth/almost-zero? c)
(mth/almost-zero? (- d 1))))

View file

@ -175,7 +175,6 @@
(dm/export gtr/transform-selrect-matrix) (dm/export gtr/transform-selrect-matrix)
(dm/export gtr/transform-bounds) (dm/export gtr/transform-bounds)
(dm/export gtr/move-position-data) (dm/export gtr/move-position-data)
(dm/export gtr/apply-transform)
(dm/export gtr/apply-objects-modifiers) (dm/export gtr/apply-objects-modifiers)
(dm/export gtr/parent-coords-rect) (dm/export gtr/parent-coords-rect)
(dm/export gtr/parent-coords-points) (dm/export gtr/parent-coords-points)

View file

@ -8,7 +8,8 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.matrix :as gmt] [app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt])) [app.common.geom.point :as gpt]
[app.common.geom.shapes.rect :as gpr]))
(defn center-rect (defn center-rect
[{:keys [x y width height]}] [{:keys [x y width height]}]
@ -31,6 +32,22 @@
(gpt/point (/ (+ minx maxx) 2.0) (gpt/point (/ (+ minx maxx) 2.0)
(/ (+ miny maxy) 2.0)))) (/ (+ miny maxy) 2.0))))
(defn center-bounds [[a b c d]]
(let [xa (:x a)
ya (:y a)
xb (:x b)
yb (:y b)
xc (:x c)
yc (:y c)
xd (:x d)
yd (:y d)
minx (min xa xb xc xd)
miny (min ya yb yc yd)
maxx (max xa xb xc xd)
maxy (max ya yb yc yd)]
(gpt/point (/ (+ minx maxx) 2.0)
(/ (+ miny maxy) 2.0))))
(defn center-shape (defn center-shape
"Calculate the center of the shape." "Calculate the center of the shape."
[shape] [shape]
@ -49,3 +66,8 @@
(gpt/transform point (gmt/multiply prev matrix post)))] (gpt/transform point (gmt/multiply prev matrix post)))]
(mapv tr-point points)) (mapv tr-point points))
points))) points)))
(defn transform-selrect
[{:keys [x1 y1 x2 y2] :as sr} matrix]
(let [[c1 c2] (transform-points [(gpt/point x1 y1) (gpt/point x2 y2)] matrix)]
(gpr/corners->selrect c1 c2)))

View file

@ -91,20 +91,30 @@
(defn- set-children-modifiers (defn- set-children-modifiers
"Propagates the modifiers from a parent too its children applying constraints if necesary" "Propagates the modifiers from a parent too its children applying constraints if necesary"
[modif-tree objects parent transformed-parent ignore-constraints snap-pixel?] [modif-tree objects parent transformed-parent ignore-constraints]
(let [children (map (d/getf objects) (:shapes parent)) (let [children (:shapes parent)
modifiers (dm/get-in modif-tree [(:id parent) :modifiers]) modifiers (dm/get-in modif-tree [(:id parent) :modifiers])]
parent (gtr/transform-shape parent (ctm/select-parent-modifiers modifiers))
set-child (if (ctm/only-move? modifiers)
(fn [modif-tree child] ;; Move modifiers don't need to calculate constraints
(let [child-modifiers (gct/calc-child-modifiers parent child modifiers ignore-constraints transformed-parent) (loop [modif-tree modif-tree
child-modifiers (cond-> child-modifiers snap-pixel? (gpp/set-pixel-precision child))] children (seq children)]
(cond-> modif-tree (if-let [current (first children)]
(not (ctm/empty? child-modifiers)) (recur (update-in modif-tree [current :modifiers] ctm/add-modifiers modifiers)
(update-in [(:id child) :modifiers] ctm/add-modifiers child-modifiers))))] (rest children))
modif-tree))
(reduce set-child modif-tree children))) ;; Check the constraints, then resize
(let [parent (gtr/transform-shape parent (ctm/select-parent-modifiers modifiers))]
(loop [modif-tree modif-tree
children (seq children)]
(if-let [current (first children)]
(let [child-modifiers (gct/calc-child-modifiers parent (get objects current) modifiers ignore-constraints transformed-parent)]
(recur (cond-> modif-tree
(not (ctm/empty? child-modifiers))
(update-in [current :modifiers] ctm/add-modifiers child-modifiers))
(rest children)))
modif-tree))))))
(defn- process-layout-children (defn- process-layout-children
[modif-tree objects parent transformed-parent] [modif-tree objects parent transformed-parent]
@ -210,17 +220,11 @@
(assoc-in modif-tree [(:id parent) :modifiers] modifiers)))) (assoc-in modif-tree [(:id parent) :modifiers] modifiers))))
(defn- propagate-modifiers (defn- propagate-modifiers
[objects snap-pixel? ignore-constraints [modif-tree recalculate] parent] "Propagate modifiers to its children"
[objects ignore-constraints [modif-tree recalculate] parent]
(let [parent-id (:id parent) (let [parent-id (:id parent)
root? (= uuid/zero parent-id) root? (= uuid/zero parent-id)
modifiers (dm/get-in modif-tree [parent-id :modifiers]) modifiers (dm/get-in modif-tree [parent-id :modifiers])
modifiers (cond-> modifiers
(and (not root?) (ctm/has-geometry? modifiers) snap-pixel?)
(gpp/set-pixel-precision parent))
modif-tree (-> modif-tree (assoc-in [parent-id :modifiers] modifiers))
transformed-parent (gtr/transform-shape parent modifiers) transformed-parent (gtr/transform-shape parent modifiers)
has-modifiers? (ctm/child-modifiers? modifiers) has-modifiers? (ctm/child-modifiers? modifiers)
@ -233,7 +237,7 @@
[(cond-> modif-tree [(cond-> modif-tree
(and (not is-layout?) has-modifiers? is-parent? (not root?)) (and (not is-layout?) has-modifiers? is-parent? (not root?))
(set-children-modifiers objects parent transformed-parent (or ignore-constraints is-inside-layout?) snap-pixel?) (set-children-modifiers objects parent transformed-parent (or ignore-constraints is-inside-layout?))
is-layout? is-layout?
(-> (process-layout-children objects parent transformed-parent) (-> (process-layout-children objects parent transformed-parent)
@ -266,7 +270,7 @@
(let [shapes-tree (resolve-tree-sequence (-> modif-tree keys set) objects) (let [shapes-tree (resolve-tree-sequence (-> modif-tree keys set) objects)
[modif-tree recalculate] [modif-tree recalculate]
(reduce (partial propagate-modifiers objects snap-pixel? ignore-constraints) [modif-tree #{}] shapes-tree) (reduce (partial propagate-modifiers objects ignore-constraints) [modif-tree #{}] shapes-tree)
shapes-tree (resolve-tree-sequence recalculate objects) shapes-tree (resolve-tree-sequence recalculate objects)
@ -281,7 +285,11 @@
modif-tree modif-tree
(->> shapes-tree (->> shapes-tree
(filter ctl/layout?) (filter ctl/layout?)
(reduce (partial calculate-reflow-layout objects) modif-tree ))] (reduce (partial calculate-reflow-layout objects) modif-tree))
modif-tree
(cond-> modif-tree
snap-pixel? (gpp/adjust-pixel-precision objects))]
;;#?(:cljs ;;#?(:cljs
;; (.log js/console ">result" (modif->js modif-tree objects))) ;; (.log js/console ">result" (modif->js modif-tree objects)))

View file

@ -6,6 +6,8 @@
(ns app.common.geom.shapes.pixel-precision (ns app.common.geom.shapes.pixel-precision
(:require (:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes.points :as gpo] [app.common.geom.shapes.points :as gpo]
[app.common.geom.shapes.rect :as gpr] [app.common.geom.shapes.rect :as gpr]
@ -15,9 +17,8 @@
[app.common.types.modifiers :as ctm])) [app.common.types.modifiers :as ctm]))
(defn size-pixel-precision (defn size-pixel-precision
[modifiers shape] [modifiers {:keys [points transform transform-inverse] :as shape}]
(let [{:keys [points transform transform-inverse] :as shape} (gtr/transform-shape shape modifiers) (let [origin (gpo/origin points)
origin (gpo/origin points)
curr-width (gpo/width-points points) curr-width (gpo/width-points points)
curr-height (gpo/height-points points) curr-height (gpo/height-points points)
@ -35,9 +36,8 @@
(ctm/resize scalev origin transform transform-inverse)))) (ctm/resize scalev origin transform transform-inverse))))
(defn position-pixel-precision (defn position-pixel-precision
[modifiers shape] [modifiers {:keys [points]}]
(let [{:keys [points]} (gtr/transform-shape shape modifiers) (let [bounds (gpr/points->rect points)
bounds (gpr/points->rect points)
corner (gpt/point bounds) corner (gpt/point bounds)
target-corner (gpt/round corner) target-corner (gpt/round corner)
deltav (gpt/to-vec corner target-corner)] deltav (gpt/to-vec corner target-corner)]
@ -47,7 +47,25 @@
(defn set-pixel-precision (defn set-pixel-precision
"Adjust modifiers so they adjust to the pixel grid" "Adjust modifiers so they adjust to the pixel grid"
[modifiers shape] [modifiers shape]
(let [move? (ctm/only-move? modifiers)]
(-> modifiers (cond-> modifiers
(not move?)
(size-pixel-precision shape) (size-pixel-precision shape)
(position-pixel-precision shape)))
:always
(position-pixel-precision shape))))
(defn adjust-pixel-precision
[modif-tree objects]
(let [update-modifiers
(fn [modif-tree shape]
(let [modifiers (dm/get-in modif-tree [(:id shape) :modifiers])]
(if-not (ctm/has-geometry? modifiers)
modif-tree
(let [shape (gtr/transform-shape shape modifiers)]
(-> modif-tree
(update-in [(:id shape) :modifiers] set-pixel-precision shape))))))]
(->> (keys modif-tree)
(map (d/getf objects))
(reduce update-modifiers modif-tree))))

View file

@ -192,3 +192,10 @@
(>= (:y1 sr2) (:y1 sr1)) (>= (:y1 sr2) (:y1 sr1))
(<= (:y2 sr2) (:y2 sr1)))) (<= (:y2 sr2) (:y2 sr1))))
(defn corners->selrect
[p1 p2]
(let [xp1 (:x p1)
xp2 (:x p2)
yp1 (:y p1)
yp2 (:y p2)]
(make-selrect (min xp1 xp2) (min yp1 yp2) (abs (- xp1 xp2)) (abs (- yp1 yp2)))))

View file

@ -188,55 +188,52 @@
"Calculates a matrix that is a series of transformations we have to do to the transformed rectangle so that "Calculates a matrix that is a series of transformations we have to do to the transformed rectangle so that
after applying them the end result is the `shape-path-temp`. after applying them the end result is the `shape-path-temp`.
This is compose of three transformations: skew, resize and rotation" This is compose of three transformations: skew, resize and rotation"
([points-temp points-rec] [points-temp points-rec flip-x flip-y]
(calculate-adjust-matrix points-temp points-rec false false)) (let [center (gco/center-bounds points-temp)
([points-temp points-rec flip-x flip-y] stretch-matrix (gmt/matrix)
(let [center (gco/center-points points-temp)
stretch-matrix (gmt/matrix) skew-angle (calculate-skew-angle points-temp)
skew-angle (calculate-skew-angle points-temp) ;; When one of the axis is flipped we have to reverse the skew
;; skew-angle (if (neg? (* (:x resize-vector) (:y resize-vector))) (- skew-angle) skew-angle )
skew-angle (if (and (or flip-x flip-y)
(not (and flip-x flip-y))) (- skew-angle) skew-angle )
skew-angle (if (mth/nan? skew-angle) 0 skew-angle)
;; When one of the axis is flipped we have to reverse the skew stretch-matrix (gmt/multiply stretch-matrix (gmt/skew-matrix skew-angle 0))
;; skew-angle (if (neg? (* (:x resize-vector) (:y resize-vector))) (- skew-angle) skew-angle )
skew-angle (if (and (or flip-x flip-y)
(not (and flip-x flip-y))) (- skew-angle) skew-angle )
skew-angle (if (mth/nan? skew-angle) 0 skew-angle)
stretch-matrix (gmt/multiply stretch-matrix (gmt/skew-matrix skew-angle 0)) h1 (max 1 (calculate-height points-temp))
h2 (max 1 (calculate-height (gco/transform-points points-rec center stretch-matrix)))
h3 (if-not (mth/almost-zero? h2) (/ h1 h2) 1)
h3 (if (mth/nan? h3) 1 h3)
h1 (max 1 (calculate-height points-temp)) w1 (max 1 (calculate-width points-temp))
h2 (max 1 (calculate-height (gco/transform-points points-rec center stretch-matrix))) w2 (max 1 (calculate-width (gco/transform-points points-rec center stretch-matrix)))
h3 (if-not (mth/almost-zero? h2) (/ h1 h2) 1) w3 (if-not (mth/almost-zero? w2) (/ w1 w2) 1)
h3 (if (mth/nan? h3) 1 h3) w3 (if (mth/nan? w3) 1 w3)
w1 (max 1 (calculate-width points-temp)) stretch-matrix (gmt/multiply stretch-matrix (gmt/scale-matrix (gpt/point w3 h3)))
w2 (max 1 (calculate-width (gco/transform-points points-rec center stretch-matrix)))
w3 (if-not (mth/almost-zero? w2) (/ w1 w2) 1)
w3 (if (mth/nan? w3) 1 w3)
stretch-matrix (gmt/multiply stretch-matrix (gmt/scale-matrix (gpt/point w3 h3))) rotation-angle (calculate-rotation
center
(gco/transform-points points-rec (gco/center-points points-rec) stretch-matrix)
points-temp
flip-x
flip-y)
rotation-angle (calculate-rotation stretch-matrix (gmt/multiply (gmt/rotate-matrix rotation-angle) stretch-matrix)
center
(gco/transform-points points-rec (gco/center-points points-rec) stretch-matrix)
points-temp
flip-x
flip-y)
stretch-matrix (gmt/multiply (gmt/rotate-matrix rotation-angle) stretch-matrix) ;; This is the inverse to be able to remove the transformation
stretch-matrix-inverse
;; This is the inverse to be able to remove the transformation (gmt/multiply (gmt/scale-matrix (gpt/point (/ 1 w3) (/ 1 h3)))
stretch-matrix-inverse (gmt/skew-matrix (- skew-angle) 0)
(gmt/multiply (gmt/scale-matrix (gpt/point (/ 1 w3) (/ 1 h3))) (gmt/rotate-matrix (- rotation-angle)))]
(gmt/skew-matrix (- skew-angle) 0) [stretch-matrix stretch-matrix-inverse rotation-angle]))
(gmt/rotate-matrix (- rotation-angle)))]
[stretch-matrix stretch-matrix-inverse rotation-angle])))
(defn- adjust-rotated-transform (defn- adjust-rotated-transform
[{:keys [transform transform-inverse flip-x flip-y]} points] [{:keys [transform transform-inverse flip-x flip-y]} points]
(let [center (gco/center-points points) (let [center (gco/center-bounds points)
points-temp (cond-> points points-temp (cond-> points
(some? transform-inverse) (some? transform-inverse)
@ -280,7 +277,28 @@
(-> (update :flip-y not) (-> (update :flip-y not)
(update :rotation -))))) (update :rotation -)))))
(defn apply-transform (defn- apply-transform-move
"Given a new set of points transformed, set up the rectangle so it keeps
its properties. We adjust de x,y,width,height and create a custom transform"
[shape transform-mtx]
(let [bool? (= (:type shape) :bool)
path? (= (:type shape) :path)
points (gco/transform-points (:points shape) transform-mtx)
selrect (gco/transform-selrect (:selrect shape) transform-mtx)]
(-> shape
(cond-> bool?
(update :bool-content gpa/transform-content transform-mtx))
(cond-> path?
(update :content gpa/transform-content transform-mtx))
(cond-> (not path?)
(assoc :x (:x selrect)
:y (:y selrect)
:width (:width selrect)
:height (:height selrect)))
(assoc :selrect selrect)
(assoc :points points))))
(defn- apply-transform-generic
"Given a new set of points transformed, set up the rectangle so it keeps "Given a new set of points transformed, set up the rectangle so it keeps
its properties. We adjust de x,y,width,height and create a custom transform" its properties. We adjust de x,y,width,height and create a custom transform"
[shape transform-mtx] [shape transform-mtx]
@ -303,7 +321,10 @@
(cond-> path? (cond-> path?
(update :content gpa/transform-content transform-mtx)) (update :content gpa/transform-content transform-mtx))
(cond-> (not path?) (cond-> (not path?)
(-> (merge (select-keys selrect [:x :y :width :height])))) (assoc :x (:x selrect)
:y (:y selrect)
:width (:width selrect)
:height (:height selrect)))
(cond-> transform (cond-> transform
(-> (assoc :transform transform) (-> (assoc :transform transform)
(assoc :transform-inverse transform-inverse))) (assoc :transform-inverse transform-inverse)))
@ -316,6 +337,14 @@
(assoc :points points)) (assoc :points points))
(assoc :rotation rotation)))) (assoc :rotation rotation))))
(defn- apply-transform
"Given a new set of points transformed, set up the rectangle so it keeps
its properties. We adjust de x,y,width,height and create a custom transform"
[shape transform-mtx]
(if (gmt/move? transform-mtx)
(apply-transform-move shape transform-mtx)
(apply-transform-generic shape transform-mtx)))
(defn- update-group-viewbox (defn- update-group-viewbox
"Updates the viewbox for groups imported from SVG's" "Updates the viewbox for groups imported from SVG's"
[{:keys [selrect svg-viewbox] :as group} new-selrect] [{:keys [selrect svg-viewbox] :as group} new-selrect]
@ -376,24 +405,6 @@
(assoc :flip-x (-> mask :flip-x)) (assoc :flip-x (-> mask :flip-x))
(assoc :flip-y (-> mask :flip-y))))) (assoc :flip-y (-> mask :flip-y)))))
(defn apply-modifiers
[shape modifiers]
(let [transform (ctm/modifiers->transform modifiers)]
(cond-> shape
(and (some? transform)
;; Never transform the root frame
(not= uuid/zero (:id shape)))
(apply-transform transform)
:always
(ctm/apply-structure-modifiers modifiers))))
(defn apply-objects-modifiers
[objects modifiers]
(letfn [(process-shape [objects [id modifier]]
(d/update-when objects id apply-modifiers (:modifiers modifier)))]
(reduce process-shape objects modifiers)))
(defn transform-shape (defn transform-shape
([shape] ([shape]
(let [modifiers (:modifiers shape)] (let [modifiers (:modifiers shape)]
@ -402,9 +413,35 @@
(transform-shape modifiers)))) (transform-shape modifiers))))
([shape modifiers] ([shape modifiers]
(cond-> shape (letfn [(apply-modifiers
(and (some? modifiers) (not (ctm/empty? modifiers))) [shape modifiers]
(apply-modifiers modifiers)))) (if (ctm/empty? modifiers)
shape
(let [transform (ctm/modifiers->transform modifiers)]
(cond-> shape
(and (some? transform) (not= uuid/zero (:id shape))) ;; Never transform the root frame
(apply-transform transform)
(ctm/has-structure? modifiers)
(ctm/apply-structure-modifiers modifiers)))))]
(cond-> shape
(and (some? modifiers) (not (ctm/empty? modifiers)))
(apply-modifiers modifiers)))))
(defn apply-objects-modifiers
[objects modifiers]
(loop [objects objects
entry (first modifiers)
modifiers (rest modifiers)]
(if (nil? entry)
objects
(let [[id modifier] entry]
(recur (d/update-when objects id transform-shape (:modifiers modifier))
(first modifiers)
(rest modifiers))))))
(defn transform-bounds (defn transform-bounds
([points modifiers] ([points modifiers]
@ -412,7 +449,9 @@
([points center modifiers] ([points center modifiers]
(let [transform (ctm/modifiers->transform modifiers)] (let [transform (ctm/modifiers->transform modifiers)]
(gco/transform-points points center transform)))) (cond-> points
(some? transform)
(gco/transform-points center transform)))))
(defn transform-selrect (defn transform-selrect
[selrect modifiers] [selrect modifiers]

View file

@ -156,7 +156,7 @@
(if (> num to) to num))) (if (> num to) to num)))
(defn almost-zero? [num] (defn almost-zero? [num]
(< (abs (double num)) 1e-5)) (< (abs (double num)) 1e-4))
(defonce float-equal-precision 0.001) (defonce float-equal-precision 0.001)

View file

@ -38,21 +38,79 @@
;; * rotation ;; * rotation
;; * change-properties ;; * change-properties
;; Private aux functions
(def conjv (fnil conj [])) (def conjv (fnil conj []))
(defn- move-vec? [vector]
(or (not (mth/almost-zero? (:x vector)))
(not (mth/almost-zero? (:y vector)))))
(defn- resize-vec? [vector]
(or (not (mth/almost-zero? (- (:x vector) 1)))
(not (mth/almost-zero? (- (:y vector) 1)))))
(defn- mergeable-move?
[op1 op2]
(and (= :move (:type op1))
(= :move (:type op2))))
(defn- mergeable-resize?
[op1 op2]
(and (= :resize (:type op1))
(= :resize (:type op2))
;; Same transforms
(gmt/close? (or (:transform op1) (gmt/matrix)) (or (:transform op2) (gmt/matrix)))
(gmt/close? (or (:transform-inverse op1) (gmt/matrix)) (or (:transform-inverse op2) (gmt/matrix)))
;; Same origin
(gpt/close? (:origin op1) (:origin op2))))
(defn- merge-move
[op1 op2]
{:type :move
:vector (gpt/add (:vector op1) (:vector op2))})
(defn- merge-resize
[op1 op2]
(let [vector (gpt/point (* (-> op1 :vector :x) (-> op2 :vector :x))
(* (-> op1 :vector :y) (-> op2 :vector :y)))]
(assoc op1 :vector vector)))
(defn- maybe-add-move
"Check the last operation to check if we can stack it over the last one"
[operations op]
(if (c/empty? operations)
[op]
(let [head (peek operations)]
(if (mergeable-move? head op)
(let [item (merge-move head op)]
(cond-> (pop operations)
(move-vec? (:vector item))
(conj item)))
(conj operations op)))))
(defn- maybe-add-resize
"Check the last operation to check if we can stack it over the last one"
[operations op]
(if (c/empty? operations)
[op]
(let [head (peek operations)]
(if (mergeable-resize? head op)
(let [item (merge-resize head op)]
(cond-> (pop operations)
(resize-vec? (:vector item))
(conj item)))
(conj operations op)))))
;; Public builder API ;; Public builder API
(defn empty [] (defn empty []
{}) {})
(defn move-vec? [vector]
(or (not (mth/almost-zero? (:x vector)))
(not (mth/almost-zero? (:y vector)))))
(defn resize-vec? [vector]
(or (not (mth/almost-zero? (- (:x vector) 1)))
(not (mth/almost-zero? (- (:y vector) 1)))))
(defn move-parent (defn move-parent
([modifiers x y] ([modifiers x y]
(move-parent modifiers (gpt/point x y))) (move-parent modifiers (gpt/point x y)))
@ -66,18 +124,18 @@
([modifiers vector origin] ([modifiers vector origin]
(cond-> modifiers (cond-> modifiers
(resize-vec? vector) (resize-vec? vector)
(update :geometry-parent conjv {:type :resize (update :geometry-parent maybe-add-resize {:type :resize
:vector vector :vector vector
:origin origin}))) :origin origin})))
([modifiers vector origin transform transform-inverse] ([modifiers vector origin transform transform-inverse]
(cond-> modifiers (cond-> modifiers
(resize-vec? vector) (resize-vec? vector)
(update :geometry-parent conjv {:type :resize (update :geometry-parent maybe-add-resize {:type :resize
:vector vector :vector vector
:origin origin :origin origin
:transform transform :transform transform
:transform-inverse transform-inverse})))) :transform-inverse transform-inverse}))))
(defn move (defn move
([modifiers x y] ([modifiers x y]
(move modifiers (gpt/point x y))) (move modifiers (gpt/point x y)))
@ -85,24 +143,24 @@
([modifiers vector] ([modifiers vector]
(cond-> modifiers (cond-> modifiers
(move-vec? vector) (move-vec? vector)
(update :geometry-child conjv {:type :move :vector vector})))) (update :geometry-child maybe-add-move {:type :move :vector vector}))))
(defn resize (defn resize
([modifiers vector origin] ([modifiers vector origin]
(cond-> modifiers (cond-> modifiers
(resize-vec? vector) (resize-vec? vector)
(update :geometry-child conjv {:type :resize (update :geometry-child maybe-add-resize {:type :resize
:vector vector :vector vector
:origin origin}))) :origin origin})))
([modifiers vector origin transform transform-inverse] ([modifiers vector origin transform transform-inverse]
(cond-> modifiers (cond-> modifiers
(resize-vec? vector) (resize-vec? vector)
(update :geometry-child conjv {:type :resize (update :geometry-child maybe-add-resize {:type :resize
:vector vector :vector vector
:origin origin :origin origin
:transform transform :transform transform
:transform-inverse transform-inverse})))) :transform-inverse transform-inverse}))))
(defn rotation (defn rotation
[modifiers center angle] [modifiers center angle]
@ -296,17 +354,20 @@
(defn only-move? (defn only-move?
"Returns true if there are only move operations" "Returns true if there are only move operations"
[modifier] [{:keys [geometry-child geometry-parent]}]
(or (and (= 1 (-> modifier :geometry-child count)) (and (every? #(= :move (:type %)) geometry-child)
(= :move (-> modifier :geometry-child first :type))) (every? #(= :move (:type %)) geometry-parent)))
(and (= 1 (-> modifier :geometry-parent count))
(= :move (-> modifier :geometry-parent first :type)))))
(defn has-geometry? (defn has-geometry?
[{:keys [geometry-parent geometry-child]}] [{:keys [geometry-parent geometry-child]}]
(or (d/not-empty? geometry-parent) (or (d/not-empty? geometry-parent)
(d/not-empty? geometry-child))) (d/not-empty? geometry-child)))
(defn has-structure?
[{:keys [structure-parent structure-child]}]
(or (d/not-empty? structure-parent)
(d/not-empty? structure-child)))
;; Extract subsets of modifiers ;; Extract subsets of modifiers
(defn select-child-modifiers (defn select-child-modifiers
@ -374,8 +435,9 @@
(let [modifiers (if (d/not-empty? (:geometry-parent modifiers)) (let [modifiers (if (d/not-empty? (:geometry-parent modifiers))
(d/concat-vec (:geometry-parent modifiers) (:geometry-child modifiers)) (d/concat-vec (:geometry-parent modifiers) (:geometry-child modifiers))
(:geometry-child modifiers))] (:geometry-child modifiers))]
(->> modifiers (when (d/not-empty? modifiers)
(reduce apply-modifier (gmt/matrix)))))) (->> modifiers
(reduce apply-modifier (gmt/matrix)))))))
(defn apply-structure-modifiers (defn apply-structure-modifiers
"Apply structure changes to a shape" "Apply structure changes to a shape"

View file

@ -200,8 +200,8 @@
(when (some? modifiers) (when (some? modifiers)
(d/mapm (fn [id {modifiers :modifiers}] (d/mapm (fn [id {modifiers :modifiers}]
(let [shape (get objects id) (let [shape (get objects id)
text? (= :text (:type shape)) adapt-text? (and (= :text (:type shape)) (not (ctm/only-move? modifiers)))
modifiers (cond-> modifiers text? (adapt-text-modifiers shape))] modifiers (cond-> modifiers adapt-text? (adapt-text-modifiers shape))]
(ctm/modifiers->transform modifiers))) (ctm/modifiers->transform modifiers)))
modifiers)))) modifiers))))
@ -214,6 +214,7 @@
(mf/deps transforms) (mf/deps transforms)
(fn [] (fn []
(->> (keys transforms) (->> (keys transforms)
(filter #(some? (get transforms %)))
(mapv (d/getf objects))))) (mapv (d/getf objects)))))
prev-shapes (mf/use-var nil) prev-shapes (mf/use-var nil)