From c01c46041d4a6e0304f20477d8b7ae1ac3b8e27f Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 29 Sep 2022 13:37:54 +0200 Subject: [PATCH] :sparkles: Adds autolayout positions calculations --- common/src/app/common/geom/matrix.cljc | 11 + common/src/app/common/geom/shapes.cljc | 10 +- .../app/common/geom/shapes/constraints.cljc | 312 ++++++++++------ .../src/app/common/geom/shapes/intersect.cljc | 22 ++ common/src/app/common/geom/shapes/layout.cljc | 76 +++- .../src/app/common/geom/shapes/modifiers.cljc | 164 +++++---- .../app/common/geom/shapes/transforms.cljc | 343 ++++++------------ common/src/app/common/pages/migrations.cljc | 8 +- common/src/app/common/types/modifiers.cljc | 256 +++++++++++++ .../src/app/main/data/workspace/comments.cljs | 4 +- .../app/main/data/workspace/drawing/box.cljs | 5 +- .../main/data/workspace/drawing/common.cljs | 9 +- .../src/app/main/data/workspace/guides.cljs | 3 +- .../app/main/data/workspace/shape_layout.cljs | 2 +- .../main/data/workspace/state_helpers.cljs | 7 +- .../src/app/main/data/workspace/texts.cljs | 23 +- .../app/main/data/workspace/transforms.cljs | 81 +++-- frontend/src/app/main/render.cljs | 44 +-- frontend/src/app/main/ui/shapes/bool.cljs | 4 +- frontend/src/app/main/ui/shapes/mask.cljs | 7 +- .../app/main/ui/viewer/handoff/render.cljs | 5 +- .../src/app/main/ui/viewer/interactions.cljs | 9 +- frontend/src/app/main/ui/viewer/shapes.cljs | 5 +- .../shapes/frame/dynamic_modifiers.cljs | 11 +- .../app/main/ui/workspace/shapes/text.cljs | 2 +- .../shapes/text/viewport_texts_html.cljs | 6 +- .../main/ui/workspace/sidebar/options.cljs | 4 +- .../src/app/main/ui/workspace/viewport.cljs | 17 +- .../main/ui/workspace/viewport/drawarea.cljs | 5 +- .../main/ui/workspace/viewport/guides.cljs | 2 +- .../ui/workspace/viewport/interactions.cljs | 7 +- .../main/ui/workspace/viewport/outline.cljs | 2 +- .../main/ui/workspace/viewport/selection.cljs | 21 +- .../ui/workspace/viewport/snap_points.cljs | 23 +- .../app/main/ui/workspace/viewport/utils.cljs | 4 +- .../main/ui/workspace/viewport/widgets.cljs | 11 +- frontend/src/app/util/geom/snap_points.cljs | 7 +- 37 files changed, 938 insertions(+), 594 deletions(-) create mode 100644 common/src/app/common/types/modifiers.cljc diff --git a/common/src/app/common/geom/matrix.cljc b/common/src/app/common/geom/matrix.cljc index e4448acb7..53f3d1748 100644 --- a/common/src/app/common/geom/matrix.cljc +++ b/common/src/app/common/geom/matrix.cljc @@ -252,3 +252,14 @@ (update :d mth/precision 4) (update :e mth/precision 4) (update :f mth/precision 4))) + +(defn transform-point-center + "Transform a point around the shape center" + [point center matrix] + (if (and (some? point) (some? matrix) (some? center)) + (gpt/transform + point + (multiply (translate-matrix center) + matrix + (translate-matrix (gpt/negate center)))) + point)) diff --git a/common/src/app/common/geom/shapes.cljc b/common/src/app/common/geom/shapes.cljc index d0d05d47f..a217d5322 100644 --- a/common/src/app/common/geom/shapes.cljc +++ b/common/src/app/common/geom/shapes.cljc @@ -28,7 +28,7 @@ rotation of each shape. Mainly used for multiple selection." [shapes] (->> shapes - (map (comp gpr/points->selrect :points gtr/transform-shape)) + (map (comp gpr/points->selrect :points)) (gpr/join-selrects))) (defn translate-to-frame @@ -166,23 +166,17 @@ (dm/export gtr/transform-matrix) (dm/export gtr/transform-str) (dm/export gtr/inverse-transform-matrix) -(dm/export gtr/transform-point-center) (dm/export gtr/transform-rect) (dm/export gtr/calculate-adjust-matrix) (dm/export gtr/update-group-selrect) (dm/export gtr/update-mask-selrect) -(dm/export gtr/resize-modifiers) -(dm/export gtr/change-orientation-modifiers) -(dm/export gtr/rotation-modifiers) -(dm/export gtr/merge-modifiers) (dm/export gtr/transform-shape) (dm/export gtr/transform-selrect) (dm/export gtr/transform-selrect-matrix) (dm/export gtr/transform-bounds) -(dm/export gtr/modifiers->transform) -(dm/export gtr/empty-modifiers?) (dm/export gtr/move-position-data) (dm/export gtr/apply-transform) +(dm/export gtr/apply-objects-modifiers) ;; Constratins (dm/export gct/calc-child-modifiers) diff --git a/common/src/app/common/geom/shapes/constraints.cljc b/common/src/app/common/geom/shapes/constraints.cljc index 79821b364..49db8a69d 100644 --- a/common/src/app/common/geom/shapes/constraints.cljc +++ b/common/src/app/common/geom/shapes/constraints.cljc @@ -6,14 +6,19 @@ (ns app.common.geom.shapes.constraints (:require - [app.common.geom.matrix :as gmt] + [app.common.data :as d] [app.common.geom.point :as gpt] [app.common.geom.shapes.common :as gco] + [app.common.geom.shapes.intersect :as gsi] [app.common.geom.shapes.rect :as gre] + [app.common.geom.shapes.transforms :as gst] [app.common.math :as mth] [app.common.uuid :as uuid])) ;; Auxiliary methods to work in an specifica axis +(defn other-axis [axis] + (if (= :x axis) :y :x)) + (defn get-delta-start [axis rect tr-rect] (if (= :x axis) (- (:x1 tr-rect) (:x1 rect)) @@ -29,6 +34,11 @@ (- (:width tr-rect) (:width rect)) (- (:height tr-rect) (:height rect)))) +(defn get-delta-scale [axis rect tr-rect] + (if (= :x axis) + (/ (:width tr-rect) (:width rect)) + (/ (:height tr-rect) (:height rect)))) + (defn get-delta-center [axis center tr-center] (if (= :x axis) (- (:x tr-center) (:x center)) @@ -53,78 +63,138 @@ (:width rect) (:height rect))) +(defn right-vector + [child-points parent-points] + (let [[p0 p1 p2 _] parent-points + [_c0 c1 _ _] child-points + dir-v (gpt/to-vec p0 p1) + cp (gsi/line-line-intersect c1 (gpt/add c1 dir-v) p1 p2)] + (gpt/to-vec c1 cp))) + +(defn left-vector + [child-points parent-points] + + (let [[p0 p1 _ p3] parent-points + [_ _ _ c3] child-points + dir-v (gpt/to-vec p0 p1) + cp (gsi/line-line-intersect c3 (gpt/add c3 dir-v) p0 p3)] + (gpt/to-vec c3 cp))) + + +(defn top-vector + [child-points parent-points] + + (let [[p0 p1 _ p3] parent-points + [c0 _ _ _] child-points + dir-v (gpt/to-vec p0 p3) + cp (gsi/line-line-intersect c0 (gpt/add c0 dir-v) p0 p1)] + (gpt/to-vec c0 cp))) + +(defn bottom-vector + [child-points parent-points] + + (let [[p0 _ p2 p3] parent-points + [_ _ c2 _] child-points + dir-v (gpt/to-vec p0 p3) + cp (gsi/line-line-intersect c2 (gpt/add c2 dir-v) p2 p3)] + (gpt/to-vec c2 cp))) + +(defn center-horizontal-vector + [child-points parent-points] + + (let [[p0 p1 _ p3] parent-points + [_ c1 _ _] child-points + + dir-v (gpt/to-vec p0 p1) + + p1c (gpt/add p0 (gpt/scale dir-v 0.5)) + p2c (gpt/add p3 (gpt/scale dir-v 0.5)) + + cp (gsi/line-line-intersect c1 (gpt/add c1 dir-v) p1c p2c)] + + (gpt/to-vec c1 cp))) + +(defn center-vertical-vector + [child-points parent-points] + (let [[p0 p1 p2 _] parent-points + [_ c1 _ _] child-points + + dir-v (gpt/to-vec p1 p2) + + p3c (gpt/add p0 (gpt/scale dir-v 0.5)) + p2c (gpt/add p1 (gpt/scale dir-v 0.5)) + + cp (gsi/line-line-intersect c1 (gpt/add c1 dir-v) p3c p2c)] + + (gpt/to-vec c1 cp))) + +(defn start-vector + [axis child-points parent-points] + ((if (= :x axis) left-vector top-vector) child-points parent-points)) + +(defn end-vector + [axis child-points parent-points] + ((if (= :x axis) right-vector bottom-vector) child-points parent-points)) + +(defn center-vector + [axis child-points parent-points] + ((if (= :x axis) center-horizontal-vector center-vertical-vector) child-points parent-points)) + + ;; Constraint function definitions (defmulti constraint-modifier (fn [type & _] type)) -(defmethod constraint-modifier :start - [_ axis parent _ _ transformed-parent-rect] - - (let [parent-rect (:selrect parent) - delta-start (get-delta-start axis parent-rect transformed-parent-rect)] - (if-not (mth/almost-zero? delta-start) - {:displacement (get-displacement axis delta-start)} - {}))) - (defmethod constraint-modifier :end - [_ axis parent _ _ transformed-parent-rect] - (let [parent-rect (:selrect parent) - delta-end (get-delta-end axis parent-rect transformed-parent-rect)] - (if-not (mth/almost-zero? delta-end) - {:displacement (get-displacement axis delta-end)} - {}))) + [_ axis child-points-before parent-points-before child-points-after parent-points-after] + (let [end-before (end-vector axis child-points-before parent-points-before) + end-after (end-vector axis child-points-after parent-points-after) + end-angl (gpt/angle-with-other end-before end-after) + target-end (if (mth/close? end-angl 180) (- (gpt/length end-before)) (gpt/length end-before)) + disp-vector-end (gpt/subtract end-after (gpt/scale (gpt/unit end-after) target-end))] + [{:type :move + :vector disp-vector-end}])) (defmethod constraint-modifier :fixed - [_ axis parent child _ transformed-parent-rect] - (let [parent-rect (:selrect parent) - child-rect (gre/points->rect (:points child)) + [_ axis child-points-before parent-points-before child-points-after parent-points-after transformed-parent] + (let [[c0 c1 _ c4] child-points-after - delta-start (get-delta-start axis parent-rect transformed-parent-rect) - delta-size (get-delta-size axis parent-rect transformed-parent-rect) - child-size (get-size axis child-rect)] - (if (or (not (mth/almost-zero? delta-start)) - (not (mth/almost-zero? delta-size))) + ;; Same as constraint end + end-before (end-vector axis child-points-before parent-points-before) + end-after (end-vector axis child-points-after parent-points-after) + end-angl (gpt/angle-with-other end-before end-after) + target-end (if (mth/close? end-angl 180) (- (gpt/length end-before)) (gpt/length end-before)) + disp-vector-end (gpt/subtract end-after (gpt/scale (gpt/unit end-after) target-end)) - {:displacement (get-displacement axis delta-start) - :resize-origin (get-displacement axis delta-start (:x child-rect) (:y child-rect)) - :resize-vector (get-scale axis (/ (+ child-size delta-size) child-size))} - {}))) + before-vec (if (= axis :x) (gpt/to-vec c0 c1) (gpt/to-vec c0 c4)) + after-vec (if (= axis :x) + (gpt/to-vec c0 (gpt/add c1 disp-vector-end)) + (gpt/to-vec c0 (gpt/add c4 disp-vector-end)) + ) + + resize-angl (gpt/angle-with-other before-vec after-vec) + resize-sign (if (mth/close? resize-angl 180) -1 1) + + scale (* resize-sign (/ (gpt/length after-vec) (gpt/length before-vec))) + ] + [{:type :resize + :vector (get-scale axis scale) + :origin c0 + :transform (:transform transformed-parent) + :transform-inverse (:transform-inverse transformed-parent)}])) (defmethod constraint-modifier :center - [_ axis parent _ _ transformed-parent-rect] - (let [parent-rect (:selrect parent) - parent-center (gco/center-rect parent-rect) - transformed-parent-center (gco/center-rect transformed-parent-rect) - delta-center (get-delta-center axis parent-center transformed-parent-center)] - (if-not (mth/almost-zero? delta-center) - {:displacement (get-displacement axis delta-center)} - {}))) - -(defmethod constraint-modifier :scale - [_ axis _ _ modifiers _] - (let [{:keys [resize-vector resize-vector-2 displacement]} modifiers] - (cond-> {} - (and (some? resize-vector) - (not= (axis resize-vector) 1)) - (assoc :resize-origin (:resize-origin modifiers) - :resize-vector (if (= :x axis) - (gpt/point (:x resize-vector) 1) - (gpt/point 1 (:y resize-vector)))) - - (and (= :y axis) (some? resize-vector-2) - (not (mth/close? (:y resize-vector-2) 1))) - (assoc :resize-origin (:resize-origin-2 modifiers) - :resize-vector (gpt/point 1 (:y resize-vector-2))) - - (some? displacement) - (assoc :displacement - (get-displacement axis (-> (gpt/point 0 0) - (gpt/transform displacement) - (gpt/transform (:resize-transform-inverse modifiers (gmt/matrix))) - axis)))))) + [_ axis child-points-before parent-points-before child-points-after parent-points-after] + (let [center-before (center-vector axis child-points-before parent-points-before) + center-after (center-vector axis child-points-after parent-points-after) + center-angl (gpt/angle-with-other center-before center-after) + target-center (if (mth/close? center-angl 180) (- (gpt/length center-before)) (gpt/length center-before)) + disp-vector-center (gpt/subtract center-after (gpt/scale (gpt/unit center-after) target-center))] + [{:type :move + :vector disp-vector-center}])) (defmethod constraint-modifier :default [_ _ _ _ _] - {}) + []) (def const->type+axis {:left :start @@ -152,7 +222,7 @@ :top :scale))) -(defn clean-modifiers +#_(defn clean-modifiers "Remove redundant modifiers" [{:keys [displacement resize-vector resize-vector-2] :as modifiers}] @@ -174,55 +244,91 @@ (mth/almost-zero? (- 1.0 (:y resize-vector-2)))) (dissoc :resize-origin-2 :resize-vector-2))) + +(defn bounding-box-parent-transform + "Returns a bounding box for the child in the same coordinate system + as the parent. + Returns a points array" + [child parent] + (-> child + :points + (gco/transform-points (:transform-inverse parent)) + (gre/points->rect) + (gre/rect->points) ;; Restore to points so we can transform them + (gco/transform-points (:transform parent)))) + +(defn normalize-modifiers + "Before aplying constraints we need to remove the deformation caused by the resizing of the parent" + [constraints-h constraints-v modifiers child parent transformed-child transformed-parent] + + (let [child-bb-before + (-> child + :points + (gco/transform-points (:transform-inverse parent)) + (gre/points->rect)) + + child-bb-after + (-> transformed-child + :points + (gco/transform-points (:transform-inverse transformed-parent)) + (gre/points->rect)) + + scale-x (/ (:width child-bb-before) (:width child-bb-after)) + scale-y (/ (:height child-bb-before) (:height child-bb-after))] + + (-> modifiers + (update :v2 #(cond-> % + (not= :scale constraints-h) + (conj + ;; This resize will leave the shape in its original position relative to the parent + {:type :resize + :transform (:transform transformed-parent) + :transform-inverse (:transform-inverse transformed-parent) + :origin (-> transformed-parent :points (nth 0)) + :vector (gpt/point scale-x 1)}) + + (not= :scale constraints-v) + (conj + {:type :resize + :transform (:transform transformed-parent) + :transform-inverse (:transform-inverse transformed-parent) + :origin (-> transformed-parent :points (nth 0)) + :vector (gpt/point 1 scale-y)})))))) + (defn calc-child-modifiers - [parent child modifiers ignore-constraints transformed-parent-rect] + [parent child modifiers ignore-constraints transformed-parent] - (if (and (nil? (:resize-vector modifiers)) - (nil? (:resize-vector-2 modifiers))) - ;; If we don't have a resize modifier we return the same modifiers - modifiers - (let [constraints-h - (if-not ignore-constraints - (:constraints-h child (default-constraints-h child)) - :scale) + (let [constraints-h + (if-not ignore-constraints + (:constraints-h child (default-constraints-h child)) + :scale) - constraints-v - (if-not ignore-constraints - (:constraints-v child (default-constraints-v child)) - :scale) + constraints-v + (if-not ignore-constraints + (:constraints-v child (default-constraints-v child)) + :scale)] - modifiers-h (constraint-modifier (constraints-h const->type+axis) :x parent child modifiers transformed-parent-rect) - modifiers-v (constraint-modifier (constraints-v const->type+axis) :y parent child modifiers transformed-parent-rect)] + (if (and (= :scale constraints-h) (= :scale constraints-v)) + modifiers - ;; Build final child modifiers. Apply transform again to the result, to get the - ;; real modifiers that need to be applied to the child, including rotation as needed. - (cond-> {} - (some? (:displacement-after modifiers)) - (assoc :displacement-after (:displacement-after modifiers)) + (let [transformed-child (gst/transform-shape child modifiers) + modifiers (normalize-modifiers constraints-h constraints-v modifiers child parent transformed-child transformed-parent) - (or (contains? modifiers-h :displacement) - (contains? modifiers-v :displacement)) - (assoc :displacement (cond-> (gpt/point (get-in modifiers-h [:displacement :x] 0) - (get-in modifiers-v [:displacement :y] 0)) - (some? (:resize-transform modifiers)) - (gpt/transform (:resize-transform modifiers)) + tranformed-child-2 (gst/transform-shape child modifiers) + parent-points-before (:points parent) + child-points-before (bounding-box-parent-transform child parent) - :always - (gmt/translate-matrix))) + parent-points-after (:points transformed-parent) + child-points-after (bounding-box-parent-transform tranformed-child-2 transformed-parent) - (:resize-vector modifiers-h) - (assoc :resize-origin (:resize-origin modifiers-h) - :resize-vector (gpt/point (get-in modifiers-h [:resize-vector :x] 1) - (get-in modifiers-h [:resize-vector :y] 1))) + modifiers-h (constraint-modifier (constraints-h const->type+axis) :x + child-points-before parent-points-before + child-points-after parent-points-after + transformed-parent) - (:resize-vector modifiers-v) - (assoc :resize-origin-2 (:resize-origin modifiers-v) - :resize-vector-2 (gpt/point (get-in modifiers-v [:resize-vector :x] 1) - (get-in modifiers-v [:resize-vector :y] 1))) + modifiers-v (constraint-modifier (constraints-v const->type+axis) :y + child-points-before parent-points-before + child-points-after parent-points-after + transformed-parent)] - (:resize-transform modifiers) - (assoc :resize-transform (:resize-transform modifiers) - :resize-transform-inverse (:resize-transform-inverse modifiers)) - - :always - (clean-modifiers))))) + (update modifiers :v2 d/concat-vec modifiers-h modifiers-v))))) diff --git a/common/src/app/common/geom/shapes/intersect.cljc b/common/src/app/common/geom/shapes/intersect.cljc index 34b5ec7f6..72d5bf47a 100644 --- a/common/src/app/common/geom/shapes/intersect.cljc +++ b/common/src/app/common/geom/shapes/intersect.cljc @@ -348,3 +348,25 @@ :points (every? (partial has-point-rect? rect)))) + +(defn line-line-intersect + "Calculates the interesection point for two lines given by the points a-b and b-c" + [a b c d] + + (let [;; Line equation representation: ax + by + c = 0 + a1 (- (:y b) (:y a)) + b1 (- (:x a) (:x b)) + c1 (+ (* a1 (:x a)) (* b1 (:y a))) + + a2 (- (:y d) (:y c)) + b2 (- (:x c) (:x d)) + c2 (+ (* a2 (:x c)) (* b2 (:y c))) + + ;; Cramer's rule + det (- (* a1 b2) (* a2 b1))] + + ;; If almost zero the lines are parallel + (when (not (mth/almost-zero? det)) + (let [x (/ (- (* b2 c1) (* b1 c2)) det) + y (/ (- (* c2 a1) (* c1 a2)) det)] + (gpt/point x y))))) diff --git a/common/src/app/common/geom/shapes/layout.cljc b/common/src/app/common/geom/shapes/layout.cljc index dc27fb429..e6f7cc70e 100644 --- a/common/src/app/common/geom/shapes/layout.cljc +++ b/common/src/app/common/geom/shapes/layout.cljc @@ -6,7 +6,6 @@ (ns app.common.geom.shapes.layout (:require - [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes.rect :as gre])) @@ -71,24 +70,39 @@ (let [wrap? (= layout-wrap-type :wrap) reduce-fn - (fn [[{:keys [line-width line-height num-children] :as line-data} result] child] + (fn [[{:keys [line-width line-height num-children child-fill? num-child-fill] :as line-data} result] child] (let [child-bounds (-> child :points gre/points->rect) - next-width (-> child-bounds :width) - next-height (-> child-bounds :height)] + + cur-child-fill? + (or (and (col? shape) (= :fill (:layout-h-behavior child))) + (and (row? shape) (= :fill (:layout-v-behavior child)))) + + next-width (if cur-child-fill? + 0 + (-> child-bounds :width)) + + next-height (if cur-child-fill? + 0 + (-> child-bounds :height))] (if (and (some? line-data) (or (not wrap?) (and (col? shape) (<= (+ line-width next-width (* layout-gap num-children)) width)) (and (row? shape) (<= (+ line-height next-height (* layout-gap num-children)) height)))) - [{:line-width (if (col? shape) (+ line-width next-width) (max line-width next-width)) - :line-height (if (row? shape) (+ line-height next-height) (max line-height next-height)) - :num-children (inc num-children)} + ;; Si autofill aƱadimos el minwidth que por defecto es 0 + [{:line-width (if (col? shape) (+ line-width next-width) (max line-width next-width)) + :line-height (if (row? shape) (+ line-height next-height) (max line-height next-height)) + :num-children (inc num-children) + :child-fill? (or cur-child-fill? child-fill?) + :num-child-fill (cond-> num-child-fill cur-child-fill? inc)} result] - [{:line-width next-width - :line-height next-height - :num-children 1} + [{:line-width next-width + :line-height next-height + :num-children 1 + :child-fill? child-fill? + :num-child-fill (if child-fill? 1 0)} (cond-> result (some? line-data) (conj line-data))]))) [line-data layout-lines] (reduce reduce-fn [nil []] children)] @@ -124,13 +138,14 @@ [base-x base-y])) (get-start-line - [{:keys [line-width line-height num-children]} base-x base-y] + [{:keys [line-width line-height num-children child-fill?]} base-x base-y] (let [children-gap (* layout-gap (dec num-children)) start-x (cond - (or (and (col? shape) (= :space-between layout-type)) + (or (and (col? shape) child-fill?) + (and (col? shape) (= :space-between layout-type)) (and (col? shape) (= :space-around layout-type))) x @@ -154,7 +169,8 @@ start-y (cond - (or (and (row? shape) (= :space-between layout-type)) + (or (and (row? shape) child-fill?) + (and (row? shape) (= :space-between layout-type)) (and (row? shape) (= :space-around layout-type))) y @@ -240,6 +256,7 @@ 0)] (assoc line-data + :layout-bounds layout-bounds :layout-gap layout-gap :margin-x margin-x :margin-y margin-y))) @@ -314,14 +331,39 @@ "Calculates the modifiers for the layout" [parent transform child layout-data] - (let [bounds (-> child :points gre/points->selrect) + (let [child-bounds (-> child :points gre/points->selrect) - [corner-p layout-data] (next-p parent bounds layout-data) + fill-space (- (-> layout-data :layout-bounds :width) (:line-width layout-data)) + + fill-width (- (/ fill-space (:num-child-fill layout-data)) + (* 2 (:layout-gap layout-data))) + + fill-scale (/ fill-width (:width child-bounds)) + + child-bounds + (cond-> child-bounds + (and (col? parent) (= :fill (:layout-h-behavior child))) + (assoc :width fill-width)) + + [corner-p layout-data] (next-p parent child-bounds layout-data) delta-p (-> corner-p - (gpt/subtract (gpt/point bounds)) + (gpt/subtract (gpt/point child-bounds)) (cond-> (some? transform) (gpt/transform transform))) - modifiers {:displacement-after (gmt/translate-matrix delta-p)}] + modifiers [] + + modifiers + (cond-> modifiers + (and (col? parent) (= :fill (:layout-h-behavior child))) + (conj {:type :resize + :from :layout + :origin (gpt/point child-bounds) + :vector (gpt/point fill-scale 1)})) + + modifiers + (conj modifiers {:type :move + :from :layout + :vector delta-p})] [modifiers layout-data])) diff --git a/common/src/app/common/geom/shapes/modifiers.cljc b/common/src/app/common/geom/shapes/modifiers.cljc index f93929abe..4645a6582 100644 --- a/common/src/app/common/geom/shapes/modifiers.cljc +++ b/common/src/app/common/geom/shapes/modifiers.cljc @@ -15,8 +15,10 @@ [app.common.geom.shapes.rect :as gpr] [app.common.geom.shapes.transforms :as gtr] [app.common.math :as mth] + [app.common.types.modifiers :as ctm] [app.common.uuid :as uuid])) +;; TODO LAYOUT: ADAPT TO NEW MODIFIERS (defn set-pixel-precision "Adjust modifiers so they adjust to the pixel grid" [modifiers shape] @@ -106,44 +108,65 @@ (defn set-children-modifiers - [modif-tree shape objects ignore-constraints snap-pixel?] - (letfn [(set-child [transformed-rect snap-pixel? modif-tree child] + [modif-tree objects shape ignore-constraints snap-pixel?] + ;; TODO LAYOUT: SNAP PIXEL! + (letfn [(set-child [transformed-parent _snap-pixel? modif-tree child] (let [modifiers (get-in modif-tree [(:id shape) :modifiers]) - child-modifiers (gct/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect) - child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))] - (cond-> modif-tree - (not (gtr/empty-modifiers? child-modifiers)) - (update-in [(:id child) :modifiers] #(merge child-modifiers %)))))] + + child-modifiers (gct/calc-child-modifiers shape child modifiers ignore-constraints transformed-parent) + + ;;_ (.log js/console (:name child) (clj->js child-modifiers)) + + ;;child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child)) + + result + (cond-> modif-tree + (not (ctm/empty-modifiers? child-modifiers)) + (update-in [(:id child) :modifiers :v2] #(d/concat-vec % (:v2 child-modifiers))) + #_(update-in [(:id child) :modifiers] #(merge-mod2 child-modifiers %)) + #_(update-in [(:id child) :modifiers] #(merge child-modifiers %))) + + ;;_ (.log js/console ">>>" (:name child)) + ;;_ (.log js/console " >" (clj->js child-modifiers)) + ;;_ (.log js/console " >" (clj->js (get-in modif-tree [(:id child) :modifiers]))) + ;;_ (.log js/console " >" (clj->js (get-in result [(:id child) :modifiers]))) + ] + result + )) + ] (let [children (map (d/getf objects) (:shapes shape)) modifiers (get-in modif-tree [(:id shape) :modifiers]) - transformed-rect (gtr/transform-selrect (:selrect shape) modifiers) + ;; transformed-rect (gtr/transform-selrect (:selrect shape) modifiers) + ;; transformed-rect (-> shape (merge {:modifiers modifiers}) gtr/transform-shape :selrect) + transformed-parent (-> shape (merge {:modifiers modifiers}) gtr/transform-shape) + resize-modif? (or (:resize-vector modifiers) (:resize-vector-2 modifiers))] - (reduce (partial set-child transformed-rect (and snap-pixel? resize-modif?)) modif-tree children)))) + (reduce (partial set-child transformed-parent (and snap-pixel? resize-modif?)) modif-tree children)))) (defn group? [shape] (or (= :group (:type shape)) (= :bool (:type shape)))) -(defn merge-modifiers - [modif-tree ids modifiers] - (reduce - (fn [modif-tree id] - (update-in modif-tree [id :modifiers] #(merge % modifiers))) - modif-tree - ids)) +(defn frame? [shape] + (= :frame (:type shape))) + +(defn layout? [shape] + (and (frame? shape) + (:layout shape))) (defn set-layout-modifiers - [modif-tree objects id] + ;; TODO LAYOUT: SNAP PIXEL! + [modif-tree objects parent _snap-pixel?] - (letfn [(transform-child [parent child] + (letfn [(transform-child [child] (let [modifiers (get modif-tree (:id child)) child (cond-> child - (not (group? child)) + (some? modifiers) (-> (merge modifiers) gtr/transform-shape) - (group? child) + (and (nil? modifiers) (group? child)) (gtr/apply-group-modifiers objects modif-tree)) child @@ -158,22 +181,17 @@ modif-tree (cond-> modif-tree - (not (gtr/empty-modifiers? modifiers)) - (merge-modifiers [(:id child)] modifiers) - - (and (not (gtr/empty-modifiers? modifiers)) (group? child)) - (merge-modifiers (:shapes child) modifiers))] + (d/not-empty? modifiers) + (update-in [(:id child) :modifiers :v2] d/concat-vec modifiers) + #_(merge-modifiers [(:id child)] modifiers))] [layout-data modif-tree]))] - (let [modifiers (get modif-tree id) - - shape (-> (get objects id) (merge modifiers) gtr/transform-shape) - - + (let [modifiers (get modif-tree (:id parent)) + shape (-> parent (merge modifiers) gtr/transform-shape) children (->> (:shapes shape) (map (d/getf objects)) - (map (partial transform-child shape))) + (map transform-child)) center (gco/center-shape shape) {:keys [transform transform-inverse]} shape @@ -230,6 +248,17 @@ :else (recur (:id parent) result))))) +(defn resolve-tree-sequence + ;; TODO LAYOUT: Esta ahora puesto al zero pero tiene que mirar todas las raices + "Given the ids that have changed search for layout roots to recalculate" + [_ids objects] + (->> (tree-seq + #(d/not-empty? (get-in objects [% :shapes])) + #(get-in objects [% :shapes]) + uuid/zero) + + (map #(get objects %)))) + (defn resolve-layout-ids "Given a list of ids, resolve the parent layouts that will need to update. This will go upwards in the tree while a layout is found" @@ -239,6 +268,28 @@ (map #(get-first-layout % objects)) ids)) +(defn inside-layout? + [objects shape] + + (loop [current-id (:id shape)] + (let [current (get objects current-id)] + (cond + (or (nil? current) (= current-id (:parent-id current))) + false + + (= :frame (:type current)) + (:layout current) + + :else + (recur (:parent-id current)))))) + +#_(defn modif->js + [modif-tree objects] + (clj->js (into {} + (map (fn [[k v]] + [(get-in objects [k :name]) v])) + modif-tree))) + (defn set-objects-modifiers [ids objects get-modifier ignore-constraints snap-pixel?] @@ -251,40 +302,27 @@ modif-tree (reduce set-modifiers {} ids) - ids (resolve-layout-ids ids objects) + shapes-tree (resolve-tree-sequence ids objects) - ;; First: Calculate children modifiers (constraints, etc) - [modif-tree touched-layouts] - (loop [current (first ids) - pending (rest ids) - modif-tree modif-tree - touched-layouts (d/ordered-set)] - (if (some? current) - (let [shape (get objects current) - pending (concat pending (:shapes shape)) - - touched-layouts - (cond-> touched-layouts - (:layout shape) - (conj (:id shape))) - - modif-tree - (-> modif-tree - (set-children-modifiers shape objects ignore-constraints snap-pixel?))] - - (recur (first pending) (rest pending) modif-tree touched-layouts)) - - [modif-tree touched-layouts])) - - ;; Second: Calculate layout positioning modif-tree - (loop [current (first touched-layouts) - pending (rest touched-layouts) - modif-tree modif-tree] + (->> shapes-tree + (reduce + (fn [modif-tree shape] + (let [has-modifiers? (some? (get-in modif-tree [(:id shape) :modifiers])) + is-layout? (layout? shape) + is-parent? (or (group? shape) (and (frame? shape) (not (layout? shape)))) - (if (some? current) - (let [modif-tree (set-layout-modifiers modif-tree objects current)] - (recur (first pending) (rest pending) modif-tree)) - modif-tree))] + ;; If the current child is inside the layout we ignore the constraints + is-inside-layout? (inside-layout? objects shape)] + (cond-> modif-tree + is-layout? + (set-layout-modifiers objects shape snap-pixel?) + + (and has-modifiers? is-parent?) + (set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?)))) + + modif-tree))] + + ;;(.log js/console ">result" (modif->js modif-tree objects)) modif-tree)) diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index be2792109..8b1dfaa36 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -14,8 +14,8 @@ [app.common.geom.shapes.path :as gpa] [app.common.geom.shapes.rect :as gpr] [app.common.math :as mth] - [app.common.spec :as us] - [app.common.text :as txt])) + [app.common.text :as txt] + [app.common.types.modifiers :as ctm])) (def ^:dynamic *skip-adjust* false) @@ -76,14 +76,6 @@ ; ---- Geometric operations -(defn- normalize-scale - "We normalize the scale so it's not too close to 0" - [scale] - (cond - (and (< scale 0) (> scale -0.01)) -0.01 - (and (>= scale 0) (< scale 0.01)) 0.01 - :else scale)) - (defn- calculate-skew-angle "Calculates the skew angle of the parallelogram given by the points" [[p1 _ p3 p4]] @@ -182,17 +174,6 @@ (gmt/multiply (:transform-inverse shape (gmt/matrix))) (gmt/translate (gpt/negate center))))) -(defn transform-point-center - "Transform a point around the shape center" - [point center matrix] - (if (and (some? point) (some? matrix) (some? center)) - (gpt/transform - point - (gmt/multiply (gmt/translate-matrix center) - matrix - (gmt/translate-matrix (gpt/negate center)))) - point)) - (defn transform-rect "Transform a rectangles and changes its attributes" [rect matrix] @@ -273,6 +254,30 @@ (if transform (gmt/multiply transform matrix) matrix) (if transform-inverse (gmt/multiply matrix-inverse transform-inverse) matrix-inverse)])) +(defn- adjust-shape-flips + "After some tranformations the flip-x/flip-y flags can change we need + to check this before adjusting the selrect" + [shape points] + + (let [points' (:points shape) + + xv1 (gpt/to-vec (nth points' 0) (nth points' 1)) + xv2 (gpt/to-vec (nth points 0) (nth points 1)) + dot-x (gpt/dot xv1 xv2) + + yv1 (gpt/to-vec (nth points' 0) (nth points' 3)) + yv2 (gpt/to-vec (nth points 0) (nth points 3)) + dot-y (gpt/dot yv1 yv2)] + + (cond-> shape + (neg? dot-x) + (-> (update :flip-x not) + (update :rotation -)) + + (neg? dot-y) + (-> (update :flip-y not) + (update :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" @@ -280,6 +285,7 @@ (let [points' (:points shape) points (gco/transform-points points' transform-mtx) + shape (-> shape (adjust-shape-flips points)) bool? (= (:type shape) :bool) path? (= (:type shape) :path) @@ -289,7 +295,6 @@ base-rotation (or (:rotation shape) 0) modif-rotation (or (get-in shape [:modifiers :rotation]) 0) rotation (mod (+ base-rotation modif-rotation) 360)] - (-> shape (cond-> bool? (update :bool-content gpa/transform-content transform-mtx)) @@ -368,173 +373,8 @@ (assoc :flip-x (-> mask :flip-x)) (assoc :flip-y (-> mask :flip-y))))) -;; --- Modifiers -;; The `modifiers` structure contains a list of transformations to -;; do make to a shape, in this order: -;; -;; - resize-origin (gpt/point) + resize-vector (gpt/point) -;; apply a scale vector to all points of the shapes, starting -;; from the origin point. -;; -;; - resize-origin-2 + resize-vector-2 -;; same as the previous one, for cases in that we need to make -;; two vectors from different origin points. -;; -;; - displacement (gmt/matrix) -;; apply a translation matrix to the shape -;; -;; - rotation (gmt/matrix) -;; apply a rotation matrix to the shape -;; -;; - resize-transform (gmt/matrix) + resize-transform-inverse (gmt/matrix) -;; a copy of the rotation matrix currently applied to the shape; -;; this is needed temporarily to apply the resize vectors. -;; -;; - resize-scale-text (bool) -;; tells if the resize vectors must be applied to text shapes -;; or not. - -(defn empty-modifiers? [modifiers] - (empty? (dissoc modifiers :ignore-geometry?))) - -(defn resize-modifiers - [shape attr value] - (us/assert map? shape) - (us/assert #{:width :height} attr) - (us/assert number? value) - (let [{:keys [proportion proportion-lock]} shape - size (select-keys (:selrect shape) [:width :height]) - new-size (if-not proportion-lock - (assoc size attr value) - (if (= attr :width) - (-> size - (assoc :width value) - (assoc :height (/ value proportion))) - (-> size - (assoc :height value) - (assoc :width (* value proportion))))) - width (:width new-size) - height (:height new-size) - - shape-transform (:transform shape) - shape-transform-inv (:transform-inverse shape) - shape-center (gco/center-shape shape) - {sr-width :width sr-height :height} (:selrect shape) - - origin (cond-> (gpt/point (:selrect shape)) - (some? shape-transform) - (transform-point-center shape-center shape-transform)) - - scalev (gpt/divide (gpt/point width height) - (gpt/point sr-width sr-height))] - {:resize-vector scalev - :resize-origin origin - :resize-transform shape-transform - :resize-transform-inverse shape-transform-inv})) - -(defn change-orientation-modifiers - [shape orientation] - (us/assert map? shape) - (us/verify #{:horiz :vert} orientation) - (let [width (:width shape) - height (:height shape) - new-width (if (= orientation :horiz) (max width height) (min width height)) - new-height (if (= orientation :horiz) (min width height) (max width height)) - - shape-transform (:transform shape) - shape-transform-inv (:transform-inverse shape) - shape-center (gco/center-shape shape) - {sr-width :width sr-height :height} (:selrect shape) - - origin (cond-> (gpt/point (:selrect shape)) - (some? shape-transform) - (transform-point-center shape-center shape-transform)) - - scalev (gpt/divide (gpt/point new-width new-height) - (gpt/point sr-width sr-height))] - {:resize-vector scalev - :resize-origin origin - :resize-transform shape-transform - :resize-transform-inverse shape-transform-inv})) - -(defn rotation-modifiers - [shape center angle] - (let [displacement (let [shape-center (gco/center-shape shape)] - (-> (gmt/matrix) - (gmt/rotate angle center) - (gmt/rotate (- angle) shape-center)))] - {:rotation angle - :displacement displacement})) - -(defn merge-modifiers - [objects modifiers] - - (let [set-modifier - (fn [objects [id modifiers]] - (-> objects - (d/update-when id merge modifiers)))] - (->> modifiers - (reduce set-modifier objects)))) - -(defn modifiers->transform - ([modifiers] - (modifiers->transform nil modifiers)) - - ([center modifiers] - (let [displacement (:displacement modifiers) - displacement-after (:displacement-after modifiers) - resize-v1 (:resize-vector modifiers) - resize-v2 (:resize-vector-2 modifiers) - origin-1 (:resize-origin modifiers (gpt/point)) - origin-2 (:resize-origin-2 modifiers (gpt/point)) - - ;; Normalize x/y vector coordinates because scale by 0 is infinite - resize-1 (when (some? resize-v1) - (gpt/point (normalize-scale (:x resize-v1)) - (normalize-scale (:y resize-v1)))) - - resize-2 (when (some? resize-v2) - (gpt/point (normalize-scale (:x resize-v2)) - (normalize-scale (:y resize-v2)))) - - - resize-transform (:resize-transform modifiers) - resize-transform-inverse (:resize-transform-inverse modifiers) - - rt-modif (:rotation modifiers)] - - (cond-> (gmt/matrix) - (some? displacement-after) - (gmt/multiply displacement-after) - - (some? resize-1) - (-> (gmt/translate origin-1) - (cond-> (some? resize-transform) - (gmt/multiply resize-transform)) - (gmt/scale resize-1) - (cond-> (some? resize-transform-inverse) - (gmt/multiply resize-transform-inverse)) - (gmt/translate (gpt/negate origin-1))) - - (some? resize-2) - (-> (gmt/translate origin-2) - (cond-> (some? resize-transform) - (gmt/multiply resize-transform)) - (gmt/scale resize-2) - (cond-> (some? resize-transform-inverse) - (gmt/multiply resize-transform-inverse)) - (gmt/translate (gpt/negate origin-2))) - - (some? displacement) - (gmt/multiply displacement) - - (some? rt-modif) - (-> (gmt/translate center) - (gmt/multiply (gmt/rotate-matrix rt-modif)) - (gmt/translate (gpt/negate center))))))) - -(defn- set-flip [shape modifiers] +#_(defn- set-flip [shape modifiers] (let [rv1x (or (get-in modifiers [:resize-vector :x]) 1) rv1y (or (get-in modifiers [:resize-vector :y]) 1) rv2x (or (get-in modifiers [:resize-vector-2 :x]) 1) @@ -547,7 +387,25 @@ (-> (update :flip-y not) (update :rotation -))))) -(defn- apply-displacement [shape] +#_(defn- set-flip-2 [shape transform] + (let [pt-a (gpt/point (:selrect shape)) + pt-b (gpt/point (-> shape :selrect :x2) (-> shape :selrect :y2)) + + shape-transform (:transform shape (gmt/matrix)) + pt-a' (gpt/transform pt-a (gmt/multiply shape-transform transform )) + pt-b' (gpt/transform pt-b (gmt/multiply shape-transform transform )) + + {:keys [x y]} (gpt/to-vec pt-a' pt-b')] + + (cond-> shape + (neg? x) + (-> (update :flip-x not) + (update :rotation -)) + (neg? y) + (-> (update :flip-y not) + (update :rotation -))))) + +#_(defn- apply-displacement [shape] (let [modifiers (:modifiers shape)] (if (contains? modifiers :displacement) (let [mov-vec (-> (gpt/point 0 0) @@ -580,64 +438,87 @@ (defn apply-modifiers [shape modifiers] (let [center (gco/center-shape shape) - transform (modifiers->transform center modifiers)] - (apply-transform shape transform))) + transform (ctm/modifiers->transform center modifiers)] + (-> shape + #_(set-flip-2 transform) + (apply-transform transform)))) + +(defn apply-objects-modifiers + [objects modifiers] + (letfn [(process-shape [objects [id modifier]] + (update objects id apply-modifiers (:modifiers modifier)))] + (reduce process-shape objects modifiers))) (defn transform-shape - [shape] - (let [modifiers (:modifiers shape)] - (cond - (nil? modifiers) - shape + ([shape] + (let [modifiers (:modifiers shape)] + (-> shape + (dissoc :modifiers) + (transform-shape modifiers)))) - (empty-modifiers? modifiers) - (dissoc shape :modifiers) + ([shape modifiers] + (cond-> shape + (and (some? modifiers) (not (ctm/empty-modifiers? modifiers))) + (-> (apply-modifiers modifiers) + (apply-text-resize modifiers))))) - :else - (let [shape (apply-displacement shape) - modifiers (:modifiers shape)] - (cond-> shape - (not (empty-modifiers? modifiers)) - (-> (set-flip modifiers) - (apply-modifiers modifiers) - (apply-text-resize modifiers)) +(defn transform-bounds-v2 + [points center modifiers] + (let [transform (ctm/modifiers->transform center {:v2 modifiers}) + result (gco/transform-points points center transform)] - :always - (dissoc :modifiers)))))) + ;;(.log js/console "??" (str transform) (clj->js result)) + result) + + #_(letfn [(apply-modifier [points {:keys [type vector origin]}] + (case type + :move + (let [displacement (gmt/translate-matrix vector)] + (gco/transform-points points displacement)) + + :resize + (gco/transform-points points origin (gmt/scale-matrix vector)) + + points))] + (->> modifiers + (reduce apply-modifier points)))) (defn transform-bounds - [points center {:keys [displacement displacement-after resize-transform-inverse resize-vector resize-origin resize-vector-2 resize-origin-2]}] + [points center {:keys [v2 displacement displacement-after resize-transform-inverse resize-vector resize-origin resize-vector-2 resize-origin-2]}] + ;; FIXME: Improve Performance - (let [resize-transform-inverse (or resize-transform-inverse (gmt/matrix)) + (if (some? v2) + (transform-bounds-v2 points center v2) + (let [resize-transform-inverse (or resize-transform-inverse (gmt/matrix)) - displacement - (when (some? displacement) - (gmt/multiply resize-transform-inverse displacement)) + displacement + (when (some? displacement) + (gmt/multiply resize-transform-inverse displacement)) - resize-origin - (when (some? resize-origin) - (transform-point-center resize-origin center resize-transform-inverse)) + resize-origin + (when (some? resize-origin) + (gmt/transform-point-center resize-origin center resize-transform-inverse)) - resize-origin-2 - (when (some? resize-origin-2) - (transform-point-center resize-origin-2 center resize-transform-inverse)) - ] + resize-origin-2 + (when (some? resize-origin-2) + (gmt/transform-point-center resize-origin-2 center resize-transform-inverse)) + ] - (if (and (nil? displacement) (nil? resize-origin) (nil? resize-origin-2) (nil? displacement-after)) - points + (if (and (nil? displacement) (nil? resize-origin) (nil? resize-origin-2) (nil? displacement-after)) + points - (cond-> points - (some? displacement) - (gco/transform-points displacement) + (cond-> points + (some? displacement) + (gco/transform-points displacement) - (some? resize-origin) - (gco/transform-points resize-origin (gmt/scale-matrix resize-vector)) + (some? resize-origin) + (gco/transform-points resize-origin (gmt/scale-matrix resize-vector)) - (some? resize-origin-2) - (gco/transform-points resize-origin-2 (gmt/scale-matrix resize-vector-2)) + (some? resize-origin-2) + (gco/transform-points resize-origin-2 (gmt/scale-matrix resize-vector-2)) - (some? displacement-after) - (gco/transform-points displacement-after))))) + (some? displacement-after) + (gco/transform-points displacement-after)))))) (defn transform-selrect [selrect modifiers] diff --git a/common/src/app/common/pages/migrations.cljc b/common/src/app/common/pages/migrations.cljc index 79c9de1c8..6ff873c8e 100644 --- a/common/src/app/common/pages/migrations.cljc +++ b/common/src/app/common/pages/migrations.cljc @@ -102,13 +102,7 @@ (fix-frames-selrects) (and (empty? (:points object)) (not= (:id object) uuid/zero)) - (fix-empty-points) - - ;; Setup an empty transformation to re-calculate selrects - ;; and points data - :always - (-> (assoc :modifiers {:displacement (gmt/matrix)}) - (gsh/transform-shape)))) + (fix-empty-points))) (update-page [page] (update page :objects d/update-vals update-object))] diff --git a/common/src/app/common/types/modifiers.cljc b/common/src/app/common/types/modifiers.cljc new file mode 100644 index 000000000..963bcd74f --- /dev/null +++ b/common/src/app/common/types/modifiers.cljc @@ -0,0 +1,256 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) UXBOX Labs SL + +(ns app.common.types.modifiers + (:require + [app.common.data :as d] + [app.common.geom.matrix :as gmt] + [app.common.geom.point :as gpt] + [app.common.geom.shapes.common :as gco] + [app.common.spec :as us])) + +;; --- Modifiers + +;; The `modifiers` structure contains a list of transformations to +;; do make to a shape, in this order: +;; +;; - resize-origin (gpt/point) + resize-vector (gpt/point)q +;; apply a scale vector to all points of the shapes, starting +;; from the origin point. +;; +;; - resize-origin-2 + resize-vector-2 +;; same as the previous one, for cases in that we need to make +;; two vectors from different origin points. +;; +;; - displacement (gmt/matrix) +;; apply a translation matrix to the shape +;; +;; - rotation (gmt/matrix) +;; apply a rotation matrix to the shape +;; +;; - resize-transform (gmt/matrix) + resize-transform-inverse (gmt/matrix) +;; a copy of the rotation matrix currently applied to the shape; +;; this is needed temporarily to apply the resize vectors. +;; +;; - resize-scale-text (bool) +;; tells if the resize vectors must be applied to text shapes +;; or not. + +(defn move + ([x y] + (move (gpt/point x y))) + + ([vector] + {:v2 [{:type :move :vector vector}]})) + +(defn resize + [vector origin] + {:v2 [{:type :resize :vector vector :origin origin}]}) + +(defn add-move + ([object x y] + (add-move object (gpt/point x y))) + + ([object vector] + (assoc-in + object + [:modifiers :displacement] + (gmt/translate-matrix (:x vector) (:y vector))))) + +(defn add-resize + [object vector origin] + (-> object + (assoc-in [:modifiers :resize-vector] vector) + (assoc-in [:modifiers :resize-origin] origin))) + +(defn empty-modifiers? [modifiers] + (empty? (dissoc modifiers :ignore-geometry?))) + +(defn resize-modifiers + [shape attr value] + (us/assert map? shape) + (us/assert #{:width :height} attr) + (us/assert number? value) + (let [{:keys [proportion proportion-lock]} shape + size (select-keys (:selrect shape) [:width :height]) + new-size (if-not proportion-lock + (assoc size attr value) + (if (= attr :width) + (-> size + (assoc :width value) + (assoc :height (/ value proportion))) + (-> size + (assoc :height value) + (assoc :width (* value proportion))))) + width (:width new-size) + height (:height new-size) + + shape-transform (:transform shape) + shape-transform-inv (:transform-inverse shape) + shape-center (gco/center-shape shape) + {sr-width :width sr-height :height} (:selrect shape) + + origin (cond-> (gpt/point (:selrect shape)) + (some? shape-transform) + (gmt/transform-point-center shape-center shape-transform)) + + scalev (gpt/divide (gpt/point width height) + (gpt/point sr-width sr-height))] + {:resize-vector scalev + :resize-origin origin + :resize-transform shape-transform + :resize-transform-inverse shape-transform-inv})) + +(defn change-orientation-modifiers + [shape orientation] + (us/assert map? shape) + (us/verify #{:horiz :vert} orientation) + (let [width (:width shape) + height (:height shape) + new-width (if (= orientation :horiz) (max width height) (min width height)) + new-height (if (= orientation :horiz) (min width height) (max width height)) + + shape-transform (:transform shape) + shape-transform-inv (:transform-inverse shape) + shape-center (gco/center-shape shape) + {sr-width :width sr-height :height} (:selrect shape) + + origin (cond-> (gpt/point (:selrect shape)) + (some? shape-transform) + (gmt/transform-point-center shape-center shape-transform)) + + scalev (gpt/divide (gpt/point new-width new-height) + (gpt/point sr-width sr-height))] + {:resize-vector scalev + :resize-origin origin + :resize-transform shape-transform + :resize-transform-inverse shape-transform-inv})) + +(defn rotation-modifiers + [shape center angle] + (let [shape-center (gco/center-shape shape) + rotation (-> (gmt/matrix) + (gmt/rotate angle center) + (gmt/rotate (- angle) shape-center))] + + {:v2 [{:type :rotation + :center shape-center + :rotation angle} + + {:type :move + :vector (gpt/transform (gpt/point 1 1) rotation)}]} + #_{:rotation angle + :displacement displacement})) + +(defn merge-modifiers + [objects modifiers] + + (let [set-modifier + (fn [objects [id modifiers]] + (-> objects + (d/update-when id merge modifiers)))] + (->> modifiers + (reduce set-modifier objects)))) + +(defn modifiers-v2->transform + [modifiers] + (letfn [(apply-modifier [matrix {:keys [type vector rotation center origin transform transform-inverse] :as modifier}] + (case type + :move + (gmt/multiply (gmt/translate-matrix vector) matrix) + + ;;:transform + ;;(gmt/multiply transform matrix) + + :resize + (gmt/multiply + (-> (gmt/matrix) + (gmt/translate origin) + (cond-> (some? transform) + (gmt/multiply transform)) + (gmt/scale vector) + (cond-> (some? transform-inverse) + (gmt/multiply transform-inverse)) + (gmt/translate (gpt/negate origin))) + matrix) + + :rotation + ;; TODO LAYOUT: Comprobar que pasa si no hay centro + (gmt/multiply + (-> (gmt/matrix) + (gmt/translate center) + (gmt/multiply (gmt/rotate-matrix rotation)) + (gmt/translate (gpt/negate center))) + matrix)))] + (->> modifiers + (reduce apply-modifier (gmt/matrix))))) + +(defn- normalize-scale + "We normalize the scale so it's not too close to 0" + [scale] + (cond + (and (< scale 0) (> scale -0.01)) -0.01 + (and (>= scale 0) (< scale 0.01)) 0.01 + :else scale)) + +(defn modifiers->transform + ([modifiers] + (modifiers->transform nil modifiers)) + + ([center modifiers] + (if (some? (:v2 modifiers)) + (modifiers-v2->transform (:v2 modifiers)) + (let [displacement (:displacement modifiers) + displacement-after (:displacement-after modifiers) + resize-v1 (:resize-vector modifiers) + resize-v2 (:resize-vector-2 modifiers) + origin-1 (:resize-origin modifiers (gpt/point)) + origin-2 (:resize-origin-2 modifiers (gpt/point)) + + ;; Normalize x/y vector coordinates because scale by 0 is infinite + resize-1 (when (some? resize-v1) + (gpt/point (normalize-scale (:x resize-v1)) + (normalize-scale (:y resize-v1)))) + + resize-2 (when (some? resize-v2) + (gpt/point (normalize-scale (:x resize-v2)) + (normalize-scale (:y resize-v2)))) + + resize-transform (:resize-transform modifiers) + resize-transform-inverse (:resize-transform-inverse modifiers) + + rt-modif (:rotation modifiers)] + + (cond-> (gmt/matrix) + (some? displacement-after) + (gmt/multiply displacement-after) + + (some? resize-1) + (-> (gmt/translate origin-1) + (cond-> (some? resize-transform) + (gmt/multiply resize-transform)) + (gmt/scale resize-1) + (cond-> (some? resize-transform-inverse) + (gmt/multiply resize-transform-inverse)) + (gmt/translate (gpt/negate origin-1))) + + (some? resize-2) + (-> (gmt/translate origin-2) + (cond-> (some? resize-transform) + (gmt/multiply resize-transform)) + (gmt/scale resize-2) + (cond-> (some? resize-transform-inverse) + (gmt/multiply resize-transform-inverse)) + (gmt/translate (gpt/negate origin-2))) + + (some? displacement) + (gmt/multiply displacement) + + (some? rt-modif) + (-> (gmt/translate center) + (gmt/multiply (gmt/rotate-matrix rt-modif)) + (gmt/translate (gpt/negate center)))))) + )) diff --git a/frontend/src/app/main/data/workspace/comments.cljs b/frontend/src/app/main/data/workspace/comments.cljs index c87150b31..7fddf1c78 100644 --- a/frontend/src/app/main/data/workspace/comments.cljs +++ b/frontend/src/app/main/data/workspace/comments.cljs @@ -159,8 +159,8 @@ build-move-event (fn [comment-thread] (let [frame (get objects (:frame-id comment-thread)) - frame' (-> (merge frame (get object-modifiers (:frame-id comment-thread))) - (gsh/transform-shape)) + modifiers (get object-modifiers (:frame-id comment-thread)) + frame' (gsh/transform-shape frame modifiers) moved (gpt/to-vec (gpt/point (:x frame) (:y frame)) (gpt/point (:x frame') (:y frame'))) position (get-in threads-position-map [(:id comment-thread) :position]) diff --git a/frontend/src/app/main/data/workspace/drawing/box.cljs b/frontend/src/app/main/data/workspace/drawing/box.cljs index de2a290ac..dc9e86762 100644 --- a/frontend/src/app/main/data/workspace/drawing/box.cljs +++ b/frontend/src/app/main/data/workspace/drawing/box.cljs @@ -10,6 +10,7 @@ [app.common.geom.shapes :as gsh] [app.common.math :as mth] [app.common.pages.helpers :as cph] + [app.common.types.modifiers :as ctm] [app.common.types.shape :as cts] [app.common.types.shape-tree :as ctst] [app.common.uuid :as uuid] @@ -37,9 +38,7 @@ scalev)] (-> shape (assoc :click-draw? false) - (assoc-in [:modifiers :resize-vector] scalev) - (assoc-in [:modifiers :resize-origin] (gpt/point x y)) - (assoc-in [:modifiers :resize-rotation] 0)))) + (gsh/transform-shape (ctm/resize scalev (gpt/point x y)))))) (defn update-drawing [state point lock?] (update-in state [:workspace-drawing :object] resize-shape point lock?)) diff --git a/frontend/src/app/main/data/workspace/drawing/common.cljs b/frontend/src/app/main/data/workspace/drawing/common.cljs index 1742bfd05..c13f76e70 100644 --- a/frontend/src/app/main/data/workspace/drawing/common.cljs +++ b/frontend/src/app/main/data/workspace/drawing/common.cljs @@ -6,10 +6,10 @@ (ns app.main.data.workspace.drawing.common (:require - [app.common.geom.matrix :as gmt] [app.common.geom.shapes :as gsh] [app.common.math :as mth] [app.common.pages.helpers :as cph] + [app.common.types.modifiers :as ctm] [app.common.types.shape :as cts] [app.main.data.workspace.shapes :as dwsh] [app.main.data.workspace.state-helpers :as wsh] @@ -51,8 +51,8 @@ (and click-draw? (not text?)) (-> (assoc :width min-side :height min-side) - (assoc-in [:modifiers :displacement] - (gmt/translate-matrix (- (/ min-side 2)) (- (/ min-side 2))))) + (gsh/transform-shape (ctm/move (- (/ min-side 2)) (- (/ min-side 2)))) + #_(ctm/add-move (- (/ min-side 2)) (- (/ min-side 2)))) (and click-draw? text?) (assoc :height 17 :width 4 :grow-type :auto-width) @@ -61,8 +61,7 @@ (cts/setup-rect-selrect) :always - (-> (gsh/transform-shape) - (dissoc :initialized? :click-draw?)))] + (dissoc :initialized? :click-draw?))] ;; Add & select the created shape to the workspace (rx/concat (if (= :text (:type shape)) diff --git a/frontend/src/app/main/data/workspace/guides.cljs b/frontend/src/app/main/data/workspace/guides.cljs index 35bae09d3..0ef6e5a0b 100644 --- a/frontend/src/app/main/data/workspace/guides.cljs +++ b/frontend/src/app/main/data/workspace/guides.cljs @@ -79,8 +79,7 @@ build-move-event (fn [guide] (let [frame (get objects (:frame-id guide)) - frame' (-> (merge frame (get object-modifiers (:frame-id guide))) - (gsh/transform-shape)) + frame' (gsh/transform-shape (get object-modifiers (:frame-id guide))) moved (gpt/to-vec (gpt/point (:x frame) (:y frame)) (gpt/point (:x frame') (:y frame'))) diff --git a/frontend/src/app/main/data/workspace/shape_layout.cljs b/frontend/src/app/main/data/workspace/shape_layout.cljs index 710995c9b..cffd33827 100644 --- a/frontend/src/app/main/data/workspace/shape_layout.cljs +++ b/frontend/src/app/main/data/workspace/shape_layout.cljs @@ -55,7 +55,7 @@ (dwt/apply-modifiers)) (rx/empty)))))) -;; TODO: Remove constraints from children +;; TODO LAYOUT: Remove constraints from children (defn create-layout [ids type] (ptk/reify ::create-layout diff --git a/frontend/src/app/main/data/workspace/state_helpers.cljs b/frontend/src/app/main/data/workspace/state_helpers.cljs index c2f68bd62..c56931cf1 100644 --- a/frontend/src/app/main/data/workspace/state_helpers.cljs +++ b/frontend/src/app/main/data/workspace/state_helpers.cljs @@ -8,9 +8,9 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] - [app.common.geom.shapes :as gsh] [app.common.pages.helpers :as cph] - [app.common.path.commands :as upc])) + [app.common.path.commands :as upc] + [app.common.types.modifiers :as ctm])) (defn lookup-page ([state] @@ -137,5 +137,6 @@ children (select-keys objects children-ids)] (as-> children $ - (gsh/merge-modifiers $ modifiers) + ;; TODO LAYOUT: REVIEW THIS + (ctm/merge-modifiers $ modifiers) (d/mapm (set-content-modifiers state) $)))) diff --git a/frontend/src/app/main/data/workspace/texts.cljs b/frontend/src/app/main/data/workspace/texts.cljs index 653b03abc..1c9f5f147 100644 --- a/frontend/src/app/main/data/workspace/texts.cljs +++ b/frontend/src/app/main/data/workspace/texts.cljs @@ -13,6 +13,7 @@ [app.common.math :as mth] [app.common.pages.helpers :as cph] [app.common.text :as txt] + [app.common.types.modifiers :as ctm] [app.common.uuid :as uuid] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.common :as dwc] @@ -319,17 +320,16 @@ (letfn [(update-fn [shape] (let [{:keys [selrect grow-type]} shape {shape-width :width shape-height :height} selrect - modifier-width (gsh/resize-modifiers shape :width new-width) - modifier-height (gsh/resize-modifiers shape :height new-height)] + modifier-width (ctm/resize-modifiers shape :width new-width) + modifier-height (ctm/resize-modifiers shape :height new-height)] + ;; TODO LAYOUT: MEZCLAR ESTOS EN UN UNICO MODIFIER (cond-> shape (and (not-changed? shape-width new-width) (= grow-type :auto-width)) - (-> (assoc :modifiers modifier-width) - (gsh/transform-shape)) + (gsh/transform-shape modifier-width) (and (not-changed? shape-height new-height) (or (= grow-type :auto-height) (= grow-type :auto-width))) - (-> (assoc :modifiers modifier-height) - (gsh/transform-shape)))))] + (gsh/transform-shape modifier-height))))] (rx/of (dch/update-shapes [id] update-fn {:reg-objects? true :save-undo? false})))))) @@ -346,18 +346,17 @@ (defn apply-text-modifier [shape {:keys [width height position-data]}] - (let [modifier-width (when width (gsh/resize-modifiers shape :width width)) - modifier-height (when height (gsh/resize-modifiers shape :height height)) + (let [modifier-width (when width (ctm/resize-modifiers shape :width width)) + modifier-height (when height (ctm/resize-modifiers shape :height height)) + ;; TODO LAYOUT: MEZCLAR LOS DOS EN UN UNICO MODIFIER new-shape (cond-> shape (some? modifier-width) - (-> (assoc :modifiers modifier-width) - (gsh/transform-shape)) + (gsh/transform-shape modifier-width) (some? modifier-height) - (-> (assoc :modifiers modifier-height) - (gsh/transform-shape)) + (gsh/transform-shape modifier-height) (some? position-data) (assoc :position-data position-data)) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 0842f1885..9d8c186d5 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -16,6 +16,7 @@ [app.common.pages.common :as cpc] [app.common.pages.helpers :as cph] [app.common.spec :as us] + [app.common.types.modifiers :as ctm] [app.common.types.shape-tree :as ctst] [app.main.data.workspace.changes :as dch] [app.main.data.workspace.collapse :as dwc] @@ -154,14 +155,14 @@ ids (->> shapes (remove #(get % :blocked false)) - (mapcat #(cph/get-children objects (:id %))) - (concat shapes) + #_(mapcat #(cph/get-children objects (:id %))) + #_(concat shapes) (filter #((cpc/editable-attrs (:type %)) :rotation)) (map :id)) get-modifier (fn [shape] - (gsh/rotation-modifiers shape center angle)) + (ctm/rotation-modifiers shape center angle)) modif-tree (gsh/set-objects-modifiers ids objects get-modifier false false)] @@ -193,7 +194,7 @@ (let [objects (wsh/lookup-page-objects state) object-modifiers (get state :workspace-modifiers) - ids (keys object-modifiers) + ids (or (keys object-modifiers) []) ids-with-children (into (vec ids) (mapcat #(cph/get-children-ids objects %)) ids) shapes (map (d/getf objects) ids) @@ -209,11 +210,10 @@ (dch/update-shapes ids (fn [shape] - (let [modif (get object-modifiers (:id shape)) + (let [modif (get-in object-modifiers [(:id shape) :modifiers]) text-shape? (cph/text-shape? shape)] (-> shape - (merge modif) - (gsh/transform-shape) + (gsh/transform-shape modif) (cond-> text-shape? (update-grow-type shape))))) {:reg-objects? true @@ -295,7 +295,7 @@ (let [children (map (d/getf objects) (:shapes shape)) shape-id (:id shape) - transformed-shape (gsh/transform-shape (merge shape (get modif-tree shape-id))) + transformed-shape (gsh/transform-shape shape (get modif-tree shape-id)) [root transformed-root ignore-geometry?] (check-delta shape root transformed-shape transformed-root objects modif-tree) @@ -331,10 +331,10 @@ rotation (or rotation 0) - initial (gsh/transform-point-center initial shape-center shape-transform-inverse) + initial (gmt/transform-point-center initial shape-center shape-transform-inverse) initial (fix-init-point initial handler shape) - point (gsh/transform-point-center (if (= rotation 0) point-snap point) + point (gmt/transform-point-center (if (= rotation 0) point-snap point) shape-center shape-transform-inverse) shapev (-> (gpt/point width height)) @@ -381,14 +381,28 @@ (gpt/transform shape-transform))) resize-origin - (cond-> (gsh/transform-point-center handler-origin shape-center shape-transform) + (cond-> (gmt/transform-point-center handler-origin shape-center shape-transform) (some? displacement) - (gpt/add displacement)) - - displacement (when (some? displacement) - (gmt/translate-matrix displacement))] + (gpt/add displacement))] (rx/of (set-modifiers ids + {:v2 (-> [] + (cond-> displacement + (conj {:type :move + :vector displacement})) + (conj {:type :resize + :vector scalev + :origin resize-origin + :transform shape-transform + :transform-inverse shape-transform-inverse})) + ;;:displacement displacement + ;;:resize-vector scalev + ;;:resize-origin resize-origin + ;;:resize-transform shape-transform + ;;:resize-scale-text scale-text + ;;:resize-transform-inverse shape-transform-inverse + })) + #_(rx/of (set-modifiers ids {:displacement displacement :resize-vector scalev :resize-origin resize-origin @@ -444,7 +458,7 @@ snap-pixel? (and (contains? (:workspace-layout state) :snap-pixel-grid) (int? value)) get-modifier - (fn [shape] (gsh/resize-modifiers shape attr value)) + (fn [shape] (ctm/resize-modifiers shape attr value)) modif-tree (gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)] @@ -468,7 +482,7 @@ snap-pixel? (contains? (get state :workspace-layout) :snap-pixel-grid) get-modifier - (fn [shape] (gsh/change-orientation-modifiers shape orientation)) + (fn [shape] (ctm/change-orientation-modifiers shape orientation)) modif-tree (gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)] @@ -655,7 +669,10 @@ (rx/with-latest vector snap-delta) ;; We try to use the previous snap so we don't have to wait for the result of the new (rx/map snap/correct-snap-point) - (rx/map #(hash-map :displacement (gmt/translate-matrix %))) + + #_(rx/map #(hash-map :displacement (gmt/translate-matrix %))) + (rx/map #(array-map :v2 [{:type :move :vector %}])) + (rx/map (partial set-modifiers ids)) (rx/take-until stopper)) @@ -704,7 +721,7 @@ (rx/merge (->> move-events (rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0)) - (rx/map #(hash-map :displacement (gmt/translate-matrix %))) + (rx/map #(ctm/move %)) (rx/map (partial set-modifiers selected)) (rx/take-until stopper)) (rx/of (move-selected direction shift?))) @@ -735,11 +752,11 @@ cpos (gpt/point (:x bbox) (:y bbox)) pos (gpt/point (or (:x position) (:x bbox)) (or (:y position) (:y bbox))) - delta (gpt/subtract pos cpos) - displ (gmt/translate-matrix delta)] + delta (gpt/subtract pos cpos)] - (rx/of (set-modifiers [id] {:displacement displ} false true) - (apply-modifiers [id])))))) + (rx/of + (set-modifiers [id] (ctm/move delta)) + (apply-modifiers [id])))))) (defn- calculate-frame-for-move [ids] @@ -787,11 +804,16 @@ (let [objects (wsh/lookup-page-objects state) selected (wsh/lookup-selected state {:omit-blocked? true}) shapes (map #(get objects %) selected) - selrect (gsh/selection-rect (->> shapes (map gsh/transform-shape))) + selrect (gsh/selection-rect shapes) origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2)))] (rx/of (set-modifiers selected - {:resize-vector (gpt/point -1.0 1.0) + {:v2 [{:type :resize + :vector (gpt/point -1.0 1.0) + :origin origin} + {:type :move + :vector (gpt/point (:width selrect) 0)}]} + #_{:resize-vector (gpt/point -1.0 1.0) :resize-origin origin :displacement (gmt/translate-matrix (gpt/point (- (:width selrect)) 0))} true) @@ -804,11 +826,16 @@ (let [objects (wsh/lookup-page-objects state) selected (wsh/lookup-selected state {:omit-blocked? true}) shapes (map #(get objects %) selected) - selrect (gsh/selection-rect (->> shapes (map gsh/transform-shape))) + selrect (gsh/selection-rect shapes) origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect))] (rx/of (set-modifiers selected - {:resize-vector (gpt/point 1.0 -1.0) + {:v2 [{:type :resize + :vector (gpt/point 1.0 -1.0) + :origin origin} + {:type :move + :vector (gpt/point 0 (:height selrect))}]} + #_{:resize-vector (gpt/point 1.0 -1.0) :resize-origin origin :displacement (gmt/translate-matrix (gpt/point 0 (- (:height selrect))))} true) diff --git a/frontend/src/app/main/render.cljs b/frontend/src/app/main/render.cljs index c750538dc..77fa6f5a1 100644 --- a/frontend/src/app/main/render.cljs +++ b/frontend/src/app/main/render.cljs @@ -15,12 +15,12 @@ ["react-dom/server" :as rds] [app.common.colors :as clr] [app.common.data.macros :as dm] - [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] [app.common.geom.shapes.bounds :as gsb] [app.common.math :as mth] [app.common.pages.helpers :as cph] + [app.common.types.modifiers :as ctm] [app.common.types.shape-tree :as ctst] [app.config :as cfg] [app.main.fonts :as fonts] @@ -82,7 +82,8 @@ (let [render-thumbnails? (mf/use-ctx muc/render-thumbnails) childs (mapv #(get objects %) (:shapes shape)) - shape (gsh/transform-shape shape)] + ;;shape (gsh/transform-shape shape) + ] (if (and render-thumbnails? (some? (:thumbnail shape))) [:& frame/frame-thumbnail {:shape shape :bounds (:children-bounds shape)}] [:& frame-shape {:shape shape :childs childs}]))))) @@ -135,7 +136,7 @@ bool-wrapper (mf/use-memo (mf/deps objects) #(bool-wrapper-factory objects)) frame-wrapper (mf/use-memo (mf/deps objects) #(frame-wrapper-factory objects))] (when (and shape (not (:hidden shape))) - (let [shape (gsh/transform-shape shape) + (let [;;shape (gsh/transform-shape shape) opts #js {:shape shape} svg-raw? (= :svg-raw (:type shape))] (if-not svg-raw? @@ -167,7 +168,8 @@ (let [shapes (cph/get-immediate-children objects) srect (gsh/selection-rect shapes) object (merge object (select-keys srect [:x :y :width :height])) - object (gsh/transform-shape object)] + ;; object (gsh/transform-shape object) + ] (assoc object :fill-color "#f0f0f0"))) (defn adapt-objects-for-shape @@ -180,14 +182,12 @@ ;; Replace the previous object with the new one objects (assoc objects object-id object) - modifier (-> (gpt/point (:x object) (:y object)) - (gpt/negate) - (gmt/translate-matrix)) + vector (-> (gpt/point (:x object) (:y object)) + (gpt/negate)) mod-ids (cons object-id (cph/get-children-ids objects object-id)) - updt-fn #(-> %1 - (assoc-in [%2 :modifiers :displacement] modifier) - (update %2 gsh/transform-shape))] + + updt-fn #(update %1 %2 gsh/transform-shape (ctm/move vector))] (reduce updt-fn objects mod-ids))) @@ -247,24 +247,21 @@ bounds2 (gsb/get-object-bounds objects (dissoc frame :shadow :blur)) delta-bounds (gpt/point (:x bounds) (:y bounds)) - - modifier (gmt/translate-matrix (gpt/negate delta-bounds)) + vector (gpt/negate delta-bounds) children-ids (cph/get-children-ids objects frame-id) objects - (mf/with-memo [frame-id objects modifier] - (let [update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)] + (mf/with-memo [frame-id objects vector] + (let [update-fn #(update-in %1 %2 ctm/add-move vector)] (->> children-ids (into [frame-id]) (reduce update-fn objects)))) frame - (mf/with-memo [modifier] - (-> frame - (assoc-in [:modifiers :displacement] modifier) - (gsh/transform-shape))) + (mf/with-memo [vector] + (gsh/transform-shape frame (ctm/move vector))) frame (cond-> frame @@ -305,22 +302,21 @@ (let [group-id (:id group) include-metadata? (mf/use-ctx export/include-metadata-ctx) - modifier + vector (mf/use-memo (mf/deps (:x group) (:y group)) (fn [] (-> (gpt/point (:x group) (:y group)) - (gpt/negate) - (gmt/translate-matrix)))) + (gpt/negate)))) objects (mf/use-memo - (mf/deps modifier objects group-id) + (mf/deps vector objects group-id) (fn [] (let [modifier-ids (cons group-id (cph/get-children-ids objects group-id)) - update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier) + update-fn #(update %1 %2 ctm/add-move vector) modifiers (reduce update-fn {} modifier-ids)] - (gsh/merge-modifiers objects modifiers)))) + (ctm/merge-modifiers objects modifiers)))) group (get objects group-id) width (* (:width group) zoom) diff --git a/frontend/src/app/main/ui/shapes/bool.cljs b/frontend/src/app/main/ui/shapes/bool.cljs index 94a76d893..2c00a9684 100644 --- a/frontend/src/app/main/ui/shapes/bool.cljs +++ b/frontend/src/app/main/ui/shapes/bool.cljs @@ -6,7 +6,6 @@ (ns app.main.ui.shapes.bool (:require - [app.common.data :as d] [app.common.data.macros :as dm] [app.common.geom.shapes :as gsh] [app.main.ui.hooks :refer [use-equal-memo]] @@ -15,6 +14,7 @@ [app.util.object :as obj] [rumext.v2 :as mf])) +;; TODO LAYOUT: REVIEW DYNAMIC CHANGES IN BOOLEANS (defn bool-shape [shape-wrapper] (mf/fnc bool-shape @@ -35,7 +35,7 @@ (some? childs) (->> childs - (d/mapm #(gsh/transform-shape %2)) + #_(d/mapm #(gsh/transform-shape %2)) (gsh/calc-bool-content shape)))))] [:* diff --git a/frontend/src/app/main/ui/shapes/mask.cljs b/frontend/src/app/main/ui/shapes/mask.cljs index 493c43691..d0685a5f5 100644 --- a/frontend/src/app/main/ui/shapes/mask.cljs +++ b/frontend/src/app/main/ui/shapes/mask.cljs @@ -7,6 +7,7 @@ (ns app.main.ui.shapes.mask (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.geom.shapes :as gsh] [app.main.ui.context :as muc] [cuerdas.core :as str] @@ -50,9 +51,7 @@ render-id (mf/use-ctx muc/render-id) svg-text? (and (= :text (:type mask)) (some? (:position-data mask))) - mask-bb (-> (gsh/transform-shape mask) - (:points)) - + mask-bb (:points mask) mask-bb-rect (gsh/points->rect mask-bb)] [:defs [:filter {:id (filter-id render-id mask)} @@ -68,7 +67,7 @@ [:clipPath {:class "mask-clip-path" :id (clip-id render-id mask)} [:polyline {:points (->> mask-bb - (map #(str (:x %) "," (:y %))) + (map #(dm/str (:x %) "," (:y %))) (str/join " "))}]] ;; When te shape is a text we pass to the shape the info and disable the filter. diff --git a/frontend/src/app/main/ui/viewer/handoff/render.cljs b/frontend/src/app/main/ui/viewer/handoff/render.cljs index 0567bf654..0fc20987e 100644 --- a/frontend/src/app/main/ui/viewer/handoff/render.cljs +++ b/frontend/src/app/main/ui/viewer/handoff/render.cljs @@ -88,7 +88,7 @@ [props] (let [shape (unchecked-get props "shape") childs (mapv #(get objects %) (:shapes shape)) - shape (gsh/transform-shape shape) + ;;shape (gsh/transform-shape shape) props (-> (obj/create) (obj/merge! props) @@ -171,8 +171,7 @@ (mf/use-memo (mf/deps objects) #(svg-raw-container-factory objects))] (when (and shape (not (:hidden shape))) - (let [shape (-> (gsh/transform-shape shape) - (gsh/translate-to-frame frame)) + (let [shape (gsh/translate-to-frame shape frame) opts #js {:shape shape :frame frame}] (case (:type shape) diff --git a/frontend/src/app/main/ui/viewer/interactions.cljs b/frontend/src/app/main/ui/viewer/interactions.cljs index fafb5cf53..72d822828 100644 --- a/frontend/src/app/main/ui/viewer/interactions.cljs +++ b/frontend/src/app/main/ui/viewer/interactions.cljs @@ -8,9 +8,9 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] - [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.pages.helpers :as cph] + [app.common.types.modifiers :as ctm] [app.common.types.page :as ctp] [app.common.uuid :as uuid] [app.main.data.comments :as dcm] @@ -31,11 +31,10 @@ [frame size objects] (let [ frame-id (:id frame) - modifier (-> (gpt/point (:x size) (:y size)) - (gpt/negate) - (gmt/translate-matrix)) + vector (-> (gpt/point (:x size) (:y size)) + (gpt/negate)) - update-fn #(d/update-when %1 %2 assoc-in [:modifiers :displacement] modifier)] + update-fn #(d/update-when %1 %2 ctm/add-move vector)] (->> (cph/get-children-ids objects frame-id) (into [frame-id]) diff --git a/frontend/src/app/main/ui/viewer/shapes.cljs b/frontend/src/app/main/ui/viewer/shapes.cljs index b884653ba..2b2522078 100644 --- a/frontend/src/app/main/ui/viewer/shapes.cljs +++ b/frontend/src/app/main/ui/viewer/shapes.cljs @@ -350,7 +350,7 @@ [props] (let [shape (obj/get props "shape") childs (mapv #(get objects %) (:shapes shape)) - shape (gsh/transform-shape shape) + ;;shape (gsh/transform-shape shape) props (obj/merge! #js {} props #js {:shape shape :childs childs @@ -429,7 +429,8 @@ (mf/with-memo [objects] (svg-raw-container-factory objects))] (when (and shape (not (:hidden shape))) - (let [shape (-> (gsh/transform-shape shape) + (let [shape (-> shape + #_(gsh/transform-shape) (gsh/translate-to-frame frame)) opts #js {:shape shape diff --git a/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs b/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs index 2f4207e14..565cca9d5 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame/dynamic_modifiers.cljs @@ -11,6 +11,7 @@ [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] + [app.common.types.modifiers :as ctm] [app.main.store :as st] [app.main.ui.workspace.viewport.utils :as vwu] [app.util.dom :as dom] @@ -184,6 +185,7 @@ text? (= type :text) transform-text? (and text? (and (nil? (:resize-vector modifiers)) (nil? (:resize-vector-2 modifiers))))] + ;; TODO LAYOUT: Adapt to new modifiers (doseq [node nodes] (cond ;; Text shapes need special treatment because their resize only change @@ -197,7 +199,7 @@ (dom/class? node "text-container") (let [modifiers (dissoc modifiers :displacement :rotation)] - (when (not (gsh/empty-modifiers? modifiers)) + (when (not (ctm/empty-modifiers? modifiers)) (let [mtx (-> shape (assoc :modifiers modifiers) (gsh/transform-shape) @@ -260,12 +262,15 @@ (d/mapm (fn [id {modifiers :modifiers}] (let [shape (get objects id) center (gsh/center-shape shape) + + ;; TODO LAYOUT: Adapt to new modifiers modifiers (cond-> modifiers ;; For texts we only use the displacement because ;; resize needs to recalculate the text layout (= :text (:type shape)) - (select-keys [:displacement :rotation]))] - (gsh/modifiers->transform center modifiers))) + (select-keys [:displacement :rotation])) + ] + (ctm/modifiers->transform center modifiers))) modifiers)))) shapes diff --git a/frontend/src/app/main/ui/workspace/shapes/text.cljs b/frontend/src/app/main/ui/workspace/shapes/text.cljs index 53ed5d9ac..b51432b5b 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text.cljs @@ -58,7 +58,7 @@ :height height :style {:fill "none" :stroke "red"}}] - ;; Text baselineazo + ;; Text baseline [:line {:x1 (mth/round x) :y1 (mth/round (- (:y data) (:height data))) :x2 (mth/round (+ x width)) diff --git a/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts_html.cljs b/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts_html.cljs index 6ee6b3ddc..e104b64fa 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts_html.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts_html.cljs @@ -13,6 +13,7 @@ [app.common.math :as mth] [app.common.pages.helpers :as cph] [app.common.text :as txt] + [app.common.types.modifiers :as ctm] [app.main.data.workspace.texts :as dwt] [app.main.fonts :as fonts] [app.main.refs :as refs] @@ -33,6 +34,7 @@ (with-meta (meta (:position-data shape)))) (dissoc :position-data :transform :transform-inverse))) +;; TODO LAYOUT: Adapt to new modifiers (defn strip-modifier [modifier] (if (or (some? (dm/get-in modifier [:modifiers :resize-vector])) @@ -43,9 +45,9 @@ (defn process-shape [modifiers {:keys [id] :as shape}] (let [modifier (-> (get modifiers id) strip-modifier) shape (cond-> shape - (not (gsh/empty-modifiers? (:modifiers modifier))) + (not (ctm/empty-modifiers? (:modifiers modifier))) (-> (assoc :grow-type :fixed) - (merge modifier) gsh/transform-shape))] + (gsh/transform-shape modifier)))] (-> shape (cond-> (nil? (:position-data shape)) (assoc :migrate true)) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index 50ea9fa1e..99f65f0fe 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs @@ -7,7 +7,7 @@ (ns app.main.ui.workspace.sidebar.options (:require [app.common.data :as d] - [app.common.geom.shapes :as gsh] + [app.common.types.modifiers :as ctm] [app.main.data.workspace :as udw] [app.main.refs :as refs] [app.main.store :as st] @@ -64,7 +64,7 @@ shared-libs (mf/deref refs/workspace-libraries) modifiers (mf/deref refs/workspace-modifiers) objects-modified (mf/with-memo [base-objects modifiers] - (gsh/merge-modifiers base-objects modifiers)) + (ctm/merge-modifiers base-objects modifiers)) selected-shapes (into [] (keep (d/getf objects-modified)) selected)] [:div.tool-window [:div.tool-window-content diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 3cf07759b..f5044bd0d 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -79,8 +79,7 @@ modifiers (mf/deref refs/workspace-modifiers) objects-modified (mf/with-memo [base-objects modifiers] - (gsh/merge-modifiers base-objects modifiers)) - + (gsh/apply-objects-modifiers base-objects modifiers)) background (get options :background clr/canvas) ;; STATE @@ -203,7 +202,7 @@ {:key (dm/str "texts-" page-id) :page-id page-id :objects objects - :modifiers modifiers + ;;:modifiers modifiers :edition edition}]]]] (when show-comments? @@ -336,10 +335,9 @@ (when show-prototypes? [:& widgets/frame-flows {:flows (:flows options) - :objects base-objects + :objects objects-modified :selected selected :zoom zoom - :modifiers modifiers :on-frame-enter on-frame-enter :on-frame-leave on-frame-leave :on-frame-select on-frame-select}]) @@ -348,8 +346,7 @@ [:& drawarea/draw-area {:shape drawing-obj :zoom zoom - :tool drawing-tool - :modifiers modifiers}]) + :tool drawing-tool}]) (when show-grids? [:& frame-grid/frame-grid @@ -371,9 +368,8 @@ :zoom zoom :page-id page-id :selected selected - :objects base-objects - :focus focus - :modifiers modifiers}]) + :objects objects-modified + :focus focus}]) (when show-snap-distance? [:& snap-distances/snap-distances @@ -416,7 +412,6 @@ {:zoom zoom :vbox vbox :hover-frame frame-parent - :modifiers modifiers :disabled-guides? disabled-guides?}]) (when show-selection-handlers? diff --git a/frontend/src/app/main/ui/workspace/viewport/drawarea.cljs b/frontend/src/app/main/ui/workspace/viewport/drawarea.cljs index 8d31ae5ac..356af918e 100644 --- a/frontend/src/app/main/ui/workspace/viewport/drawarea.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/drawarea.cljs @@ -7,7 +7,6 @@ (ns app.main.ui.workspace.viewport.drawarea "Drawing components." (:require - [app.common.geom.shapes :as gsh] [app.common.math :as mth] [app.main.ui.shapes.path :refer [path-shape]] [app.main.ui.workspace.shapes :as shapes] @@ -22,7 +21,7 @@ [:g.draw-area [:g {:style {:pointer-events "none"}} - [:& shapes/shape-wrapper {:shape (gsh/transform-shape shape)}]] + [:& shapes/shape-wrapper {:shape shape}]] (case tool :path [:& path-editor {:shape shape :zoom zoom}] @@ -31,7 +30,7 @@ (mf/defc generic-draw-area [{:keys [shape zoom]}] - (let [{:keys [x y width height]} (:selrect (gsh/transform-shape shape))] + (let [{:keys [x y width height]} (:selrect shape)] (when (and x y (not (mth/nan? x)) (not (mth/nan? y))) diff --git a/frontend/src/app/main/ui/workspace/viewport/guides.cljs b/frontend/src/app/main/ui/workspace/viewport/guides.cljs index efefcaf7a..5d158ee22 100644 --- a/frontend/src/app/main/ui/workspace/viewport/guides.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/guides.cljs @@ -278,7 +278,7 @@ frame]} (use-guide handle-change-position get-hover-frame zoom guide) base-frame (or frame hover-frame) - frame (gsh/transform-shape (merge base-frame frame-modifier)) + frame (gsh/transform-shape base-frame frame-modifier) move-vec (gpt/to-vec (gpt/point (:x base-frame) (:y base-frame)) (gpt/point (:x frame) (:y frame))) diff --git a/frontend/src/app/main/ui/workspace/viewport/interactions.cljs b/frontend/src/app/main/ui/workspace/viewport/interactions.cljs index 4ba7555ba..7ecc5989a 100644 --- a/frontend/src/app/main/ui/workspace/viewport/interactions.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/interactions.cljs @@ -9,7 +9,6 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] - [app.common.geom.shapes :as gsh] [app.common.pages.helpers :as cph] [app.common.types.shape.interactions :as ctsi] [app.main.data.workspace :as dw] @@ -254,13 +253,11 @@ (mf/defc interactions [{:keys [current-transform objects zoom selected hover-disabled?] :as props}] (let [active-shapes (into [] - (comp (filter #(seq (:interactions %))) - (map gsh/transform-shape)) + (comp (filter #(seq (:interactions %)))) (vals objects)) selected-shapes (into [] - (comp (map (d/getf objects)) - (map gsh/transform-shape)) + (map (d/getf objects)) selected) {:keys [editing-interaction-index diff --git a/frontend/src/app/main/ui/workspace/viewport/outline.cljs b/frontend/src/app/main/ui/workspace/viewport/outline.cljs index a8fd6c2df..416f71625 100644 --- a/frontend/src/app/main/ui/workspace/viewport/outline.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/outline.cljs @@ -72,7 +72,7 @@ "var(--color-primary)" "var(--color-component-highlight)")] (for [shape shapes] [:& outline {:key (str "outline-" (:id shape)) - :shape (gsh/transform-shape shape) + :shape shape :zoom zoom :color color}]))) diff --git a/frontend/src/app/main/ui/workspace/viewport/selection.cljs b/frontend/src/app/main/ui/workspace/viewport/selection.cljs index 65d1958e4..b42fbbc36 100644 --- a/frontend/src/app/main/ui/workspace/viewport/selection.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/selection.cljs @@ -341,7 +341,7 @@ (let [shape (mf/use-memo (mf/deps shapes) #(->> shapes - (map gsh/transform-shape) + #_(map gsh/transform-shape) (gsh/selection-rect) (cts/setup-shape))) on-resize @@ -369,7 +369,7 @@ (let [shape (mf/use-memo (mf/deps shapes) #(->> shapes - (map gsh/transform-shape) + #_(map gsh/transform-shape) (gsh/selection-rect) (cts/setup-shape)))] @@ -384,7 +384,7 @@ (mf/defc single-handlers [{:keys [shape zoom color disable-handlers] :as props}] (let [shape-id (:id shape) - shape (gsh/transform-shape shape) + ;;shape (gsh/transform-shape shape) on-resize (fn [current-position _initial-position event] @@ -408,14 +408,13 @@ (mf/defc single-selection [{:keys [shape zoom color disable-handlers on-move-selected on-context-menu] :as props}] - (let [shape (gsh/transform-shape shape)] - [:& controls-selection - {:shape shape - :zoom zoom - :color color - :disable-handlers disable-handlers - :on-move-selected on-move-selected - :on-context-menu on-context-menu}])) + [:& controls-selection + {:shape shape + :zoom zoom + :color color + :disable-handlers disable-handlers + :on-move-selected on-move-selected + :on-context-menu on-context-menu}]) (mf/defc selection-area {::mf/wrap [mf/memo]} diff --git a/frontend/src/app/main/ui/workspace/viewport/snap_points.cljs b/frontend/src/app/main/ui/workspace/viewport/snap_points.cljs index 1ef1bf79c..8b8892ea9 100644 --- a/frontend/src/app/main/ui/workspace/viewport/snap_points.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/snap_points.cljs @@ -50,20 +50,14 @@ :opacity line-opacity}]) (defn get-snap - [coord {:keys [shapes page-id remove-snap? zoom modifiers]}] - (let [shapes-sr - (->> shapes - ;; Merge modifiers into shapes - (map #(merge % (get modifiers (:id %)))) - ;; Create the bounding rectangle for the shapes - (gsh/selection-rect)) + [coord {:keys [shapes page-id remove-snap? zoom]}] + (let [bounds (gsh/selection-rect shapes) + frame-id (snap/snap-frame-id shapes)] - frame-id (snap/snap-frame-id shapes)] - - (->> (rx/of shapes-sr) + (->> (rx/of bounds) (rx/flat-map - (fn [selrect] - (->> (sp/selrect-snap-points selrect) + (fn [bounds] + (->> (sp/selrect-snap-points bounds) (map #(vector frame-id %))))) (rx/flat-map @@ -159,7 +153,7 @@ (mf/defc snap-points {::mf/wrap [mf/memo]} - [{:keys [layout zoom objects selected page-id drawing modifiers focus] :as props}] + [{:keys [layout zoom objects selected page-id drawing focus] :as props}] (us/assert set? selected) (let [shapes (into [] (keep (d/getf objects)) selected) @@ -182,6 +176,5 @@ [:& snap-feedback {:shapes shapes :page-id page-id :remove-snap? remove-snap? - :zoom zoom - :modifiers modifiers}])) + :zoom zoom}])) diff --git a/frontend/src/app/main/ui/workspace/viewport/utils.cljs b/frontend/src/app/main/ui/workspace/viewport/utils.cljs index 3c36704cc..40b54f43c 100644 --- a/frontend/src/app/main/ui/workspace/viewport/utils.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/utils.cljs @@ -53,9 +53,7 @@ (defn text-transform [{:keys [x y]} zoom] (let [inv-zoom (/ 1 zoom)] - (str - "scale(" inv-zoom ", " inv-zoom ") " - "translate(" (* zoom x) ", " (* zoom y) ")"))) + (dm/fmt "scale(%, %) translate(%, %)" inv-zoom inv-zoom (* zoom x) (* zoom y)))) (defn title-transform [frame zoom] (let [frame-transform (gsh/transform-str frame {:no-flip true}) diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs index 42596402e..9da2e1673 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs @@ -9,7 +9,6 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.common.geom.point :as gpt] - [app.common.geom.shapes :as gsh] [app.common.types.shape-tree :as ctt] [app.common.uuid :as uuid] [app.main.data.workspace :as dw] @@ -182,8 +181,8 @@ :on-frame-select on-frame-select}]))])) (mf/defc frame-flow - [{:keys [flow frame modifiers selected? zoom on-frame-enter on-frame-leave on-frame-select]}] - (let [{:keys [x y]} (gsh/transform-shape frame) + [{:keys [flow frame selected? zoom on-frame-enter on-frame-leave on-frame-select]}] + (let [{:keys [x y]} frame flow-pos (gpt/point x (- y (/ 35 zoom))) on-mouse-down @@ -217,9 +216,7 @@ :y -15 :width 100000 :height 24 - :transform (str (when (and selected? modifiers) - (str (:displacement modifiers) " " )) - (vwu/text-transform flow-pos zoom))} + :transform (vwu/text-transform flow-pos zoom)} [:div.flow-badge {:class (dom/classnames :selected selected?)} [:div.content {:on-mouse-down on-mouse-down :on-double-click on-double-click @@ -234,7 +231,6 @@ (let [flows (unchecked-get props "flows") objects (unchecked-get props "objects") zoom (unchecked-get props "zoom") - modifiers (unchecked-get props "modifiers") selected (or (unchecked-get props "selected") #{}) on-frame-enter (unchecked-get props "on-frame-enter") @@ -248,7 +244,6 @@ :frame frame :selected? (contains? selected (:id frame)) :zoom zoom - :modifiers modifiers :on-frame-enter on-frame-enter :on-frame-leave on-frame-leave :on-frame-select on-frame-select}]))])) diff --git a/frontend/src/app/util/geom/snap_points.cljs b/frontend/src/app/util/geom/snap_points.cljs index ea2084c87..a6120d50f 100644 --- a/frontend/src/app/util/geom/snap_points.cljs +++ b/frontend/src/app/util/geom/snap_points.cljs @@ -29,10 +29,9 @@ (defn shape-snap-points [{:keys [hidden blocked] :as shape}] (when (and (not blocked) (not hidden)) - (let [shape (gsh/transform-shape shape)] - (case (:type shape) - :frame (-> shape :points gsh/points->selrect frame-snap-points) - (into #{(gsh/center-shape shape)} (:points shape)))))) + (case (:type shape) + :frame (-> shape :points gsh/points->selrect frame-snap-points) + (into #{(gsh/center-shape shape)} (:points shape))))) (defn guide-snap-points [guide frame]