diff --git a/common/src/app/common/data.cljc b/common/src/app/common/data.cljc index 47f49be84..bd0b6044c 100644 --- a/common/src/app/common/data.cljc +++ b/common/src/app/common/data.cljc @@ -157,7 +157,7 @@ "Return a map without the keys provided in the `keys` parameter." [data keys] - (when data + (when (and (some? data) (map? data)) (persistent! (reduce #(dissoc! %1 %2) (transient data) keys)))) diff --git a/common/src/app/common/geom/shapes.cljc b/common/src/app/common/geom/shapes.cljc index 619901d17..aa6dccf81 100644 --- a/common/src/app/common/geom/shapes.cljc +++ b/common/src/app/common/geom/shapes.cljc @@ -56,8 +56,7 @@ rotation of each shape. Mainly used for multiple selection." [shapes] (->> shapes - (gtr/transform-shape) - (map (comp gpr/points->selrect :points)) + (map (comp gpr/points->selrect :points gtr/transform-shape)) (gpr/join-selrects))) (defn translate-to-frame diff --git a/common/src/app/common/geom/shapes/transforms.cljc b/common/src/app/common/geom/shapes/transforms.cljc index d84f7aec4..3c84bd457 100644 --- a/common/src/app/common/geom/shapes/transforms.cljc +++ b/common/src/app/common/geom/shapes/transforms.cljc @@ -154,11 +154,12 @@ (defn transform-point-center "Transform a point around the shape center" [point center matrix] - (gpt/transform - point - (gmt/multiply (gmt/translate-matrix center) - matrix - (gmt/translate-matrix (gpt/negate center))))) + (when point + (gpt/transform + point + (gmt/multiply (gmt/translate-matrix center) + matrix + (gmt/translate-matrix (gpt/negate center)))))) (defn transform-rect "Transform a rectangles and changes its attributes" @@ -343,6 +344,10 @@ ;; tells if the resize vectors must be applied to text shapes ;; or not. +(defn empty-modifiers? [modifiers] + (or (nil? modifiers) + (empty? (d/without-keys modifiers [:ignore-geometry?])))) + (defn resize-modifiers [shape attr value] (us/assert map? shape) @@ -464,7 +469,7 @@ modifiers (dissoc modifiers :displacement)] (-> shape (assoc :modifiers modifiers) - (cond-> (empty? modifiers) + (cond-> (empty-modifiers? modifiers) (dissoc :modifiers)))) shape))) @@ -492,13 +497,12 @@ ([shape {:keys [round-coords?] :or {round-coords? true}}] - - (if (and (contains? shape :modifiers) (empty? (:modifiers shape))) + (if (and (contains? shape :modifiers) (empty-modifiers? (:modifiers shape))) (dissoc shape :modifiers) (let [shape (apply-displacement shape) center (gco/center-shape shape) modifiers (:modifiers shape)] - (if (and modifiers center) + (if (and (not (empty-modifiers? modifiers)) center) (let [transform (modifiers->transform center modifiers)] (-> shape (set-flip modifiers) @@ -508,31 +512,43 @@ shape))))) (defn calc-transformed-parent-rect - [parent parent-modifiers] - (:selrect parent) - ;; FIXME: Improve performance - (let [parent-rect (:selrect parent) - parent-displacement (-> (gpt/point 0 0) - (gpt/transform (get parent-modifiers :displacement (gmt/matrix))) - (gpt/transform (:resize-transform-inverse parent-modifiers (gmt/matrix))) - (gmt/translate-matrix)) - parent-origin (-> (:resize-origin parent-modifiers) - ((d/nilf transform-point-center) - (gco/center-shape parent) - (:resize-transform-inverse parent-modifiers (gmt/matrix)))) - parent-origin-2 (-> (:resize-origin-2 parent-modifiers) - ((d/nilf transform-point-center) - (gco/center-shape parent) - (:resize-transform-inverse parent-modifiers (gmt/matrix)))) - parent-vector (get parent-modifiers :resize-vector (gpt/point 1 1)) - parent-vector-2 (get parent-modifiers :resize-vector-2 (gpt/point 1 1))] + [{:keys [selrect] :as shape} {:keys [displacement resize-transform-inverse resize-vector resize-origin resize-vector-2 resize-origin-2]}] - (-> parent-rect + (let [resize-transform-inverse (or resize-transform-inverse (gmt/matrix)) + + displacement + (when (some? displacement) + (-> (gpt/point 0 0) + (gpt/transform displacement) + (gpt/transform resize-transform-inverse) + (gmt/translate-matrix))) + + resize-origin + (when (some? resize-origin) + (transform-point-center resize-origin (gco/center-shape shape) resize-transform-inverse)) + + resize-origin-2 + (when (some? resize-origin-2) + (transform-point-center resize-origin-2 (gco/center-shape shape) resize-transform-inverse))] + + (if (and (nil? displacement) (nil? resize-origin) (nil? resize-origin-2)) + selrect + + (cond-> selrect + :always (gpr/rect->points) - (gco/transform-points parent-displacement) - (gco/transform-points parent-origin (gmt/scale-matrix parent-vector)) - (gco/transform-points parent-origin-2 (gmt/scale-matrix parent-vector-2)) - (gpr/points->selrect)))) + + (some? displacement) + (gco/transform-points displacement) + + (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)) + + :always + (gpr/points->selrect))))) (defn calc-child-modifiers "Given the modifiers to apply to the parent, calculate the corresponding diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 75172fbfe..cd2daa332 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -248,8 +248,12 @@ (cond-> modif-tree (not (empty? (d/without-keys child-modifiers [:ignore-geometry?]))) - (set-modifiers-new* - objects child child-modifiers root transformed-root ignore-constraints)))) + (set-modifiers-recursive objects + child + child-modifiers + root + transformed-root + ignore-constraints)))) modif-tree (-> modif-tree diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs index 3894d5a35..e15e1b978 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs @@ -153,7 +153,7 @@ (defn empty-map [keys] (into {} (map #(hash-map % nil)) keys)) -(defn get-attrs +(defn get-attrs* "Given a `type` of options that we want to extract and the shapes to extract them from returns a list of tuples [id, values] with the extracted properties for the shapes that applies (some of them ignore some attributes)" @@ -182,11 +182,13 @@ (select-keys txt/default-text-attrs attrs) (attrs/get-attrs-multi (txt/node-seq content) attrs))))] :children (let [children (->> (:shapes shape []) (map #(get objects %))) - [new-ids new-values] (get-attrs children objects attr-type)] + [new-ids new-values] (get-attrs* children objects attr-type)] [(into ids new-ids) (merge-attrs values new-values)]) [])))] (reduce extract-attrs [[] []] shapes))) +(def get-attrs (memoize get-attrs*)) + (mf/defc options {::mf/wrap [#(mf/memo' % (mf/check-props ["shapes" "shapes-with-children"]))] ::mf/wrap-props false}