diff --git a/common/app/common/geom/shapes.cljc b/common/app/common/geom/shapes.cljc index cfe5314022..d61bd6689f 100644 --- a/common/app/common/geom/shapes.cljc +++ b/common/app/common/geom/shapes.cljc @@ -157,7 +157,8 @@ rotation of each shape. Mainly used for multiple selection." [shapes] (->> shapes - (map :selrect) + (gtr/transform-shape) + (map (comp gpr/points->selrect :points)) (gpr/join-selrects))) (defn translate-to-frame @@ -288,15 +289,9 @@ (defn center-rect [rect] (gco/center-rect rect)) (defn rect->selrect [rect] (gpr/rect->selrect rect)) - -#_(def shape->rect-shape gpr/shape->rect-shape) -#_(def fix-invalid-rect-values gtr/fix-invalid-rect-values) -#_(def rect->rect-shape gpr/rect->rect-shape) +(defn rect->points [rect] (gpr/rect->points rect)) (defn points->selrect [points] (gpr/points->selrect points)) -#_(def transform-shape-point gtr/transform-shape-point) -#_(def update-path-selrect gtr/update-path-selrect) -#_(def transform gtr/transform) (defn transform-shape [shape] (gtr/transform-shape shape)) (defn transform-matrix [shape] (gtr/transform-matrix shape)) (defn transform-point-center [point center transform] (gtr/transform-point-center point center transform)) diff --git a/common/app/common/geom/shapes/transforms.cljc b/common/app/common/geom/shapes/transforms.cljc index d2ff83aec9..5e2806bcb9 100644 --- a/common/app/common/geom/shapes/transforms.cljc +++ b/common/app/common/geom/shapes/transforms.cljc @@ -108,6 +108,8 @@ resize-transform-inverse (:resize-transform-inverse modifiers (gmt/matrix)) rt-modif (or (:rotation modifiers) 0) + center (gpt/transform center ds-modifier) + transform (-> (gmt/matrix) ;; Applies the current resize transformation @@ -120,7 +122,6 @@ ;; Applies the stacked transformations (gmt/translate center) (gmt/multiply (gmt/rotate-matrix rt-modif)) - #_(gmt/multiply current-transform) (gmt/translate (gpt/negate center)) ;; Displacement @@ -186,7 +187,7 @@ stretch-matrix (gmt/multiply stretch-matrix (gmt/skew-matrix skew-angle 0)) h1 (calculate-height points-temp) - h2 (calculate-height (transform-points points-temp center stretch-matrix)) + h2 (calculate-height (transform-points points-rec center stretch-matrix)) h3 (/ h1 h2) h3 (if (mth/nan? h3) 1 h3) @@ -200,15 +201,10 @@ stretch-matrix (gmt/multiply (gmt/rotate-matrix rotation-angle) stretch-matrix) - stretch-matrix (-> (gmt/matrix) - (gmt/rotate rotation-angle) - (gmt/skew skew-angle 0) - (gmt/scale (gpt/point 1 h3))) - ;; This is the inverse to be able to remove the transformation stretch-matrix-inverse (-> (gmt/matrix) - (gmt/scale (gpt/point 1 h3)) + (gmt/scale (gpt/point 1 (/ 1 h3))) (gmt/skew (- skew-angle) 0) (gmt/rotate (- rotation-angle)))] [stretch-matrix stretch-matrix-inverse])) @@ -217,17 +213,15 @@ (defn apply-transform-path [shape transform] (let [content (gpa/transform-content (:content shape) transform) - points (gpa/content->points content) + selrect (gpa/content->selrect content) + points (gpr/rect->points selrect) rotation (mod (+ (:rotation shape 0) (or (get-in shape [:modifiers :rotation]) 0)) - 360) - selrect (gpa/content->selrect content)] + 360)] (assoc shape :content content :points points - :selrect selrect - ;;:rotation rotation - ))) + :selrect selrect))) (defn apply-transform-curve [shape transform] @@ -255,22 +249,19 @@ (:height points-temp-dim)) rect-points (gpr/rect->points rect-shape) - [matrix matrix-inverse] (calculate-adjust-matrix points-temp rect-points (:flip-x shape) (:flip-y shape)) - ;;[matrix matrix-inverse] [(gmt/matrix) (gmt/matrix)] - - new-shape (as-> shape $ - (merge $ rect-shape) - (update $ :x #(mth/precision % 0)) - (update $ :y #(mth/precision % 0)) - (update $ :width #(mth/precision % 0)) - (update $ :height #(mth/precision % 0)) - (update $ :transform #(gmt/multiply (or % (gmt/matrix)) matrix)) - (update $ :transform-inverse #(gmt/multiply matrix-inverse (or % (gmt/matrix)))) - (assoc $ :points (into [] points)) - (assoc $ :selrect (gpr/rect->selrect rect-shape)) - (update $ :rotation #(mod (+ (or % 0) - (or (get-in $ [:modifiers :rotation]) 0)) 360)))] - new-shape)) + [matrix matrix-inverse] (calculate-adjust-matrix points-temp rect-points (:flip-x shape) (:flip-y shape))] + (as-> shape $ + (merge $ rect-shape) + (update $ :x #(mth/precision % 0)) + (update $ :y #(mth/precision % 0)) + (update $ :width #(mth/precision % 0)) + (update $ :height #(mth/precision % 0)) + (update $ :transform #(gmt/multiply (or % (gmt/matrix)) matrix)) + (update $ :transform-inverse #(gmt/multiply matrix-inverse (or % (gmt/matrix)))) + (assoc $ :points (into [] points)) + (assoc $ :selrect (gpr/rect->selrect rect-shape)) + (update $ :rotation #(mod (+ (or % 0) + (or (get-in $ [:modifiers :rotation]) 0)) 360))))) (defn apply-transform [shape transform] (let [apply-transform-fn @@ -281,9 +272,11 @@ (apply-transform-fn shape transform))) (defn set-flip [shape modifiers] - (cond-> shape - (< (get-in modifiers [:resize-vector :x]) 0) (update :flip-x not) - (< (get-in modifiers [:resize-vector :y]) 0) (update :flip-y not))) + (let [rx (get-in modifiers [:resize-vector :x]) + ry (get-in modifiers [:resize-vector :y])] + (cond-> shape + (and rx (< rx 0)) (update :flip-x not) + (and ry (< ry 0)) (update :flip-y not)))) (defn transform-shape [shape] (let [center (gco/center-shape shape)] diff --git a/common/app/common/math.cljc b/common/app/common/math.cljc index f9baa33870..dd16c402e9 100644 --- a/common/app/common/math.cljc +++ b/common/app/common/math.cljc @@ -24,7 +24,7 @@ (defn finite? [v] #?(:cljs (and (not (nil? v)) (js/isFinite v)) - :clj (Double/isFinite v))) + :clj (and (not (nil? v)) (Double/isFinite v)))) (defn abs [v] diff --git a/common/app/common/pages.cljc b/common/app/common/pages.cljc index 491b1fc789..913128a0e2 100644 --- a/common/app/common/pages.cljc +++ b/common/app/common/pages.cljc @@ -798,10 +798,10 @@ ;; Rotate the group shape change the data and rotate back again (-> group - (assoc-in [:modifiers :rotation] (- (:rotation group 0))) - (geom/transform-shape) + (assoc :selrect selrect) + (assoc :points (geom/rect->points selrect)) (merge (select-keys selrect [:x :y :width :height])) - (assoc-in [:modifiers :rotation] (:rotation group)) + (assoc-in [:modifiers :rotation] (:rotation group 0)) (geom/transform-shape))))] (d/update-in-when data [:pages-index page-id :objects] reg-objects))) diff --git a/frontend/src/app/main/data/workspace/drawing/path.cljs b/frontend/src/app/main/data/workspace/drawing/path.cljs index 2ac40bf29c..8dec5b402a 100644 --- a/frontend/src/app/main/data/workspace/drawing/path.cljs +++ b/frontend/src/app/main/data/workspace/drawing/path.cljs @@ -47,6 +47,11 @@ (cd/seek (fn [{cmd :command}] (= cmd :move-to))) :params)) +(defn update-selrect [shape] + (let [selrect (gsh/content->selrect (:content shape)) + points (gsh/rect->points selrect)] + (assoc shape :points points :selrect selrect))) + (defn next-node "Calculates the next-node to be inserted." [shape position prev-point prev-handler] @@ -66,14 +71,10 @@ (defn append-node "Creates a new node in the path. Usualy used when drawing." [shape position prev-point prev-handler] - (let [command (next-node shape position prev-point prev-handler) - content (:content shape []) - content (conj content command)] + (let [command (next-node shape position prev-point prev-handler)] (-> shape - (assoc :content content) - (assoc :selrect (gsh/content->selrect content)) - ;; TODO: REMOVE POINTS - (assoc :points (gsh/content->points content))))) + (update :content (fnil conj []) command) + (update-selrect)))) (defn suffix-keyword [kw suffix] @@ -105,7 +106,7 @@ content (-> shape :content (update index update-command prefix prev-command))] (-> shape (assoc :content content) - (assoc :selrect (gsh/content->selrect content)))) + (update-selrect))) shape))] (cond-> shape @@ -132,11 +133,6 @@ ;; TODO: Enter now finish path but can finish drawing/editing as well (= enter-keycode (:key event))))) -(defn calculate-selrect [shape] - (assoc shape - :points (gsh/content->points (:content shape)) - :selrect (gsh/content->selrect (:content shape)))) - ;; EVENTS @@ -402,20 +398,30 @@ page-id (:current-page-id state) old-content (get-in state [:workspace-data :pages-index page-id :objects id :content]) old-selrect (get-in state [:workspace-data :pages-index page-id :objects id :selrect]) + old-points (get-in state [:workspace-data :pages-index page-id :objects id :points]) content-modifiers (get-in state [:workspace-local :edit-path id :content-modifiers]) new-content (gsp/apply-content-modifiers old-content content-modifiers) new-selrect (gsh/content->selrect new-content) + new-points (gsh/rect->points new-selrect) rch [{:type :mod-obj :id id :page-id page-id :operations [{:type :set :attr :content :val new-content} - {:type :set :attr :selrect :val new-selrect}]}] + {:type :set :attr :selrect :val new-selrect} + {:type :set :attr :points :val new-points}]} + {:type :reg-objects + :page-id page-id + :shapes [id]}] uch [{:type :mod-obj :id id :page-id page-id :operations [{:type :set :attr :content :val old-content} - {:type :set :attr :selrect :val old-selrect}]}]] + {:type :set :attr :selrect :val old-selrect} + {:type :set :attr :points :val old-points}]} + {:type :reg-objects + :page-id page-id + :shapes [id]}]] (rx/of (dwc/commit-changes rch uch {:commit-local? true}) (fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers))))))) @@ -428,20 +434,30 @@ page-id (:current-page-id state) old-content (get-in state [:workspace-local :edit-path id :old-content]) old-selrect (gsh/content->selrect old-content) + old-points (gsh/rect->points old-content) new-content (get-in state [:workspace-data :pages-index page-id :objects id :content]) new-selrect (get-in state [:workspace-data :pages-index page-id :objects id :selrect]) + new-points (get-in state [:workspace-data :pages-index page-id :objects id :points]) rch [{:type :mod-obj :id id :page-id page-id :operations [{:type :set :attr :content :val new-content} - {:type :set :attr :selrect :val new-selrect}]}] + {:type :set :attr :selrect :val new-selrect} + {:type :set :attr :points :val new-points}]} + {:type :reg-objects + :page-id page-id + :shapes [id]}] uch [{:type :mod-obj :id id :page-id page-id :operations [{:type :set :attr :content :val old-content} - {:type :set :attr :selrect :val old-selrect}]}]] + {:type :set :attr :selrect :val old-selrect} + {:type :set :attr :points :val old-points}]} + {:type :reg-objects + :page-id page-id + :shapes [id]}]] (rx/of (dwc/commit-changes rch uch {:commit-local? true})))))) diff --git a/frontend/src/app/main/ui/workspace/selection.cljs b/frontend/src/app/main/ui/workspace/selection.cljs index cdd1040910..90443b15ce 100644 --- a/frontend/src/app/main/ui/workspace/selection.cljs +++ b/frontend/src/app/main/ui/workspace/selection.cljs @@ -270,7 +270,7 @@ (mf/defc multiple-selection-handlers [{:keys [shapes selected zoom color show-distances] :as props}] - (let [shape (geom/setup {:type :rect} (geom/selection-rect shapes)) + (let [shape (geom/setup {:type :rect} (geom/selection-rect (->> shapes (map geom/transform-shape)))) shape-center (geom/center-shape shape) hover-id (-> (mf/deref refs/current-hover) first) @@ -315,7 +315,7 @@ hover-id (when-not (= shape-id hover-id) hover-id) hover-shape (mf/deref (refs/object-by-id hover-id)) - shape' (if (debug? :simple-selection) (geom/selection-rect [shape]) shape) + shape' (if (debug? :simple-selection) (geom/setup {:type :rect} (geom/selection-rect [shape])) shape) on-resize (fn [current-position initial-position event] (dom/stop-propagation event) (st/emit! (dw/start-resize current-position initial-position #{shape-id} shape'))) @@ -323,7 +323,6 @@ on-rotate #(do (dom/stop-propagation %) (st/emit! (dw/start-rotate [shape])))] - [:* [:& controls {:shape shape' :zoom zoom