diff --git a/common/app/common/geom/shapes.cljc b/common/app/common/geom/shapes.cljc index 5dbb6260e..628dc4322 100644 --- a/common/app/common/geom/shapes.cljc +++ b/common/app/common/geom/shapes.cljc @@ -266,6 +266,7 @@ (d/export gtr/transform-matrix) (d/export gtr/transform-point-center) (d/export gtr/transform-rect) +(d/export gtr/update-group-selrect) ;; PATHS (d/export gsp/content->points) diff --git a/common/app/common/geom/shapes/common.cljc b/common/app/common/geom/shapes/common.cljc index 49abc5943..98dcf1257 100644 --- a/common/app/common/geom/shapes/common.cljc +++ b/common/app/common/geom/shapes/common.cljc @@ -42,7 +42,7 @@ (defn center-shape "Calculate the center of the shape." [shape] - (center-rect (:selrect shape))) + (center-points (:points shape))) (defn make-centered-rect "Creates a rect given a center and a width and height" diff --git a/common/app/common/geom/shapes/transforms.cljc b/common/app/common/geom/shapes/transforms.cljc index 6248131a7..2def83afa 100644 --- a/common/app/common/geom/shapes/transforms.cljc +++ b/common/app/common/geom/shapes/transforms.cljc @@ -262,3 +262,26 @@ (apply-transform transform) (dissoc :modifiers))) shape))) + +(defn update-group-selrect [group children] + (let [shape-center (gco/center-shape group) + + ;; Points for every shape inside the group + points (->> children (mapcat :points)) + + ;; Invert to get the points minus the transforms applied to the group + base-points (transform-points points shape-center (:transform-inverse group)) + + ;; Defines the new selection rect with its transformations + new-points (-> (gpr/points->selrect base-points) + (gpr/rect->points) + (transform-points shape-center (:transform group))) + + ;; Calculte the new selrect + new-selrect (gpr/points->selrect base-points)] + + ;; Updates the shape and the applytransform-rect will update the other properties + (-> group + (assoc :selrect new-selrect) + (assoc :points new-points) + (apply-transform-rect (gmt/matrix))))) diff --git a/common/app/common/pages.cljc b/common/app/common/pages.cljc index a73d8d7f2..51720fab6 100644 --- a/common/app/common/pages.cljc +++ b/common/app/common/pages.cljc @@ -14,7 +14,7 @@ [app.common.data :as d] [app.common.pages-helpers :as cph] [app.common.exceptions :as ex] - [app.common.geom.shapes :as geom] + [app.common.geom.shapes :as gsh] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.spec :as us] @@ -840,7 +840,7 @@ (defn rotation-modifiers [center shape angle] - (let [displacement (let [shape-center (geom/center-shape shape)] + (let [displacement (let [shape-center (gsh/center-shape shape)] (-> (gmt/matrix) (gmt/rotate angle center) (gmt/rotate (- angle) shape-center)))] @@ -860,26 +860,11 @@ (distinct)) shapes))) (update-group [group objects] - (let [gcenter (geom/center-shape group) - gxfm (comp - (map #(get objects %)) - (map #(-> % - (assoc :modifiers - (rotation-modifiers gcenter % (- (:rotation group 0)))) - (geom/transform-shape)))) - inner-shapes (if (:masked-group? group) - [(first (:shapes group))] - (:shapes group)) - selrect (-> (into [] gxfm inner-shapes) - (geom/selection-rect))] - - ;; Rotate the group shape change the data and rotate back again - (-> group - (assoc :selrect selrect) - (assoc :points (geom/rect->points selrect)) - (merge (select-keys selrect [:x :y :width :height])) - (assoc-in [:modifiers :rotation] (:rotation group 0)) - (geom/transform-shape))))] + (let [children (->> (if (:masked-group? group) + [(first (:shapes group))] + (:shapes group)) + (map #(get objects %)))] + (gsh/update-group-selrect group children)))] (if page-id (d/update-in-when data [:pages-index page-id :objects] reg-objects) diff --git a/frontend/src/app/main/ui/workspace/shapes/bounding_box.cljs b/frontend/src/app/main/ui/workspace/shapes/bounding_box.cljs index 2a442bb25..10edd1b2b 100644 --- a/frontend/src/app/main/ui/workspace/shapes/bounding_box.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/bounding_box.cljs @@ -9,7 +9,7 @@ [cuerdas.core :as str] [rumext.alpha :as mf] [app.util.debug :as debug] - [app.common.geom.shapes :as geom] + [app.common.geom.shapes :as gsh] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.util.debug :refer [debug?]] @@ -35,16 +35,41 @@ :stroke-width "1px" :stroke-opacity 0.5}]])) +(mf/defc render-rect [{{:keys [x y width height]} :rect :keys [color]}] + [:rect {:x x + :y y + :width width + :height height + :style {:stroke color + :fill "transparent" + :stroke-width "1px" + :stroke-opacity 0.5 + :stroke-dasharray 4 + :pointer-events "none"}}]) + +(mf/defc render-rect-points [{:keys [points color]}] + (for [[p1 p2] (map vector points (concat (rest points) [(first points)]))] + [:line {:x1 (:x p1) + :y1 (:y p1) + :x2 (:x p2) + :y2 (:y p2) + :style {:stroke color + :stroke-width "1px"}}])) + (mf/defc bounding-box {::mf/wrap-props false} [props] (when (debug? :bounding-boxes) - (let [shape (unchecked-get props "shape") + (let [shape (-> (unchecked-get props "shape")) frame (unchecked-get props "frame") - selrect (-> shape :selrect) - shape-center (geom/center-shape shape) + selrect (gsh/points->selrect (-> shape :points)) + shape-center (gsh/center-shape shape) line-color (rdcolor #js {:seed (str (:id shape))}) - zoom (mf/deref refs/selected-zoom)] + zoom (mf/deref refs/selected-zoom) + childs-ref (mf/use-memo (mf/deps shape) #(refs/objects-by-id (:shapes shape))) + childs (->> (mf/deref childs-ref) + (map gsh/transform-shape))] + [:g.bounding-box [:text {:x (:x selrect) :y (- (:y selrect) 5) @@ -63,12 +88,8 @@ :zoom zoom :color line-color}]) - [:rect {:x (:x selrect) - :y (:y selrect) - :width (:width selrect) - :height (:height selrect) - :style {:stroke line-color - :fill "transparent" - :stroke-width "1px" - :stroke-opacity 0.5 - :pointer-events "none"}}]]))) + [:& render-rect-points {:rect selrect + :color line-color}] + + [:& render-rect {:rect selrect + :color line-color}]])))