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

🐛 Fixes problems with transforms

This commit is contained in:
alonso.torres 2020-11-19 16:45:39 +01:00
parent b1c786077b
commit 55b71a111b
6 changed files with 68 additions and 65 deletions

View file

@ -157,7 +157,8 @@
rotation of each shape. Mainly used for multiple selection." rotation of each shape. Mainly used for multiple selection."
[shapes] [shapes]
(->> shapes (->> shapes
(map :selrect) (gtr/transform-shape)
(map (comp gpr/points->selrect :points))
(gpr/join-selrects))) (gpr/join-selrects)))
(defn translate-to-frame (defn translate-to-frame
@ -288,15 +289,9 @@
(defn center-rect [rect] (gco/center-rect rect)) (defn center-rect [rect] (gco/center-rect rect))
(defn rect->selrect [rect] (gpr/rect->selrect rect)) (defn rect->selrect [rect] (gpr/rect->selrect rect))
(defn rect->points [rect] (gpr/rect->points 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 points->selrect [points] (gpr/points->selrect points)) (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-shape [shape] (gtr/transform-shape shape))
(defn transform-matrix [shape] (gtr/transform-matrix shape)) (defn transform-matrix [shape] (gtr/transform-matrix shape))
(defn transform-point-center [point center transform] (gtr/transform-point-center point center transform)) (defn transform-point-center [point center transform] (gtr/transform-point-center point center transform))

View file

@ -108,6 +108,8 @@
resize-transform-inverse (:resize-transform-inverse modifiers (gmt/matrix)) resize-transform-inverse (:resize-transform-inverse modifiers (gmt/matrix))
rt-modif (or (:rotation modifiers) 0) rt-modif (or (:rotation modifiers) 0)
center (gpt/transform center ds-modifier)
transform (-> (gmt/matrix) transform (-> (gmt/matrix)
;; Applies the current resize transformation ;; Applies the current resize transformation
@ -120,7 +122,6 @@
;; Applies the stacked transformations ;; Applies the stacked transformations
(gmt/translate center) (gmt/translate center)
(gmt/multiply (gmt/rotate-matrix rt-modif)) (gmt/multiply (gmt/rotate-matrix rt-modif))
#_(gmt/multiply current-transform)
(gmt/translate (gpt/negate center)) (gmt/translate (gpt/negate center))
;; Displacement ;; Displacement
@ -186,7 +187,7 @@
stretch-matrix (gmt/multiply stretch-matrix (gmt/skew-matrix skew-angle 0)) stretch-matrix (gmt/multiply stretch-matrix (gmt/skew-matrix skew-angle 0))
h1 (calculate-height points-temp) 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 (/ h1 h2)
h3 (if (mth/nan? h3) 1 h3) 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/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 ;; This is the inverse to be able to remove the transformation
stretch-matrix-inverse (-> (gmt/matrix) stretch-matrix-inverse (-> (gmt/matrix)
(gmt/scale (gpt/point 1 h3)) (gmt/scale (gpt/point 1 (/ 1 h3)))
(gmt/skew (- skew-angle) 0) (gmt/skew (- skew-angle) 0)
(gmt/rotate (- rotation-angle)))] (gmt/rotate (- rotation-angle)))]
[stretch-matrix stretch-matrix-inverse])) [stretch-matrix stretch-matrix-inverse]))
@ -217,17 +213,15 @@
(defn apply-transform-path (defn apply-transform-path
[shape transform] [shape transform]
(let [content (gpa/transform-content (:content 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) rotation (mod (+ (:rotation shape 0)
(or (get-in shape [:modifiers :rotation]) 0)) (or (get-in shape [:modifiers :rotation]) 0))
360) 360)]
selrect (gpa/content->selrect content)]
(assoc shape (assoc shape
:content content :content content
:points points :points points
:selrect selrect :selrect selrect)))
;;:rotation rotation
)))
(defn apply-transform-curve (defn apply-transform-curve
[shape transform] [shape transform]
@ -255,22 +249,19 @@
(:height points-temp-dim)) (:height points-temp-dim))
rect-points (gpr/rect->points rect-shape) 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] (calculate-adjust-matrix points-temp rect-points (:flip-x shape) (:flip-y shape))]
;;[matrix matrix-inverse] [(gmt/matrix) (gmt/matrix)] (as-> shape $
(merge $ rect-shape)
new-shape (as-> shape $ (update $ :x #(mth/precision % 0))
(merge $ rect-shape) (update $ :y #(mth/precision % 0))
(update $ :x #(mth/precision % 0)) (update $ :width #(mth/precision % 0))
(update $ :y #(mth/precision % 0)) (update $ :height #(mth/precision % 0))
(update $ :width #(mth/precision % 0)) (update $ :transform #(gmt/multiply (or % (gmt/matrix)) matrix))
(update $ :height #(mth/precision % 0)) (update $ :transform-inverse #(gmt/multiply matrix-inverse (or % (gmt/matrix))))
(update $ :transform #(gmt/multiply (or % (gmt/matrix)) matrix)) (assoc $ :points (into [] points))
(update $ :transform-inverse #(gmt/multiply matrix-inverse (or % (gmt/matrix)))) (assoc $ :selrect (gpr/rect->selrect rect-shape))
(assoc $ :points (into [] points)) (update $ :rotation #(mod (+ (or % 0)
(assoc $ :selrect (gpr/rect->selrect rect-shape)) (or (get-in $ [:modifiers :rotation]) 0)) 360)))))
(update $ :rotation #(mod (+ (or % 0)
(or (get-in $ [:modifiers :rotation]) 0)) 360)))]
new-shape))
(defn apply-transform [shape transform] (defn apply-transform [shape transform]
(let [apply-transform-fn (let [apply-transform-fn
@ -281,9 +272,11 @@
(apply-transform-fn shape transform))) (apply-transform-fn shape transform)))
(defn set-flip [shape modifiers] (defn set-flip [shape modifiers]
(cond-> shape (let [rx (get-in modifiers [:resize-vector :x])
(< (get-in modifiers [:resize-vector :x]) 0) (update :flip-x not) ry (get-in modifiers [:resize-vector :y])]
(< (get-in modifiers [:resize-vector :y]) 0) (update :flip-y not))) (cond-> shape
(and rx (< rx 0)) (update :flip-x not)
(and ry (< ry 0)) (update :flip-y not))))
(defn transform-shape [shape] (defn transform-shape [shape]
(let [center (gco/center-shape shape)] (let [center (gco/center-shape shape)]

View file

@ -24,7 +24,7 @@
(defn finite? (defn finite?
[v] [v]
#?(:cljs (and (not (nil? v)) (js/isFinite v)) #?(:cljs (and (not (nil? v)) (js/isFinite v))
:clj (Double/isFinite v))) :clj (and (not (nil? v)) (Double/isFinite v))))
(defn abs (defn abs
[v] [v]

View file

@ -798,10 +798,10 @@
;; Rotate the group shape change the data and rotate back again ;; Rotate the group shape change the data and rotate back again
(-> group (-> group
(assoc-in [:modifiers :rotation] (- (:rotation group 0))) (assoc :selrect selrect)
(geom/transform-shape) (assoc :points (geom/rect->points selrect))
(merge (select-keys selrect [:x :y :width :height])) (merge (select-keys selrect [:x :y :width :height]))
(assoc-in [:modifiers :rotation] (:rotation group)) (assoc-in [:modifiers :rotation] (:rotation group 0))
(geom/transform-shape))))] (geom/transform-shape))))]
(d/update-in-when data [:pages-index page-id :objects] reg-objects))) (d/update-in-when data [:pages-index page-id :objects] reg-objects)))

View file

@ -47,6 +47,11 @@
(cd/seek (fn [{cmd :command}] (= cmd :move-to))) (cd/seek (fn [{cmd :command}] (= cmd :move-to)))
:params)) :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 (defn next-node
"Calculates the next-node to be inserted." "Calculates the next-node to be inserted."
[shape position prev-point prev-handler] [shape position prev-point prev-handler]
@ -66,14 +71,10 @@
(defn append-node (defn append-node
"Creates a new node in the path. Usualy used when drawing." "Creates a new node in the path. Usualy used when drawing."
[shape position prev-point prev-handler] [shape position prev-point prev-handler]
(let [command (next-node shape position prev-point prev-handler) (let [command (next-node shape position prev-point prev-handler)]
content (:content shape [])
content (conj content command)]
(-> shape (-> shape
(assoc :content content) (update :content (fnil conj []) command)
(assoc :selrect (gsh/content->selrect content)) (update-selrect))))
;; TODO: REMOVE POINTS
(assoc :points (gsh/content->points content)))))
(defn suffix-keyword (defn suffix-keyword
[kw suffix] [kw suffix]
@ -105,7 +106,7 @@
content (-> shape :content (update index update-command prefix prev-command))] content (-> shape :content (update index update-command prefix prev-command))]
(-> shape (-> shape
(assoc :content content) (assoc :content content)
(assoc :selrect (gsh/content->selrect content)))) (update-selrect)))
shape))] shape))]
(cond-> shape (cond-> shape
@ -132,11 +133,6 @@
;; TODO: Enter now finish path but can finish drawing/editing as well ;; TODO: Enter now finish path but can finish drawing/editing as well
(= enter-keycode (:key event))))) (= enter-keycode (:key event)))))
(defn calculate-selrect [shape]
(assoc shape
:points (gsh/content->points (:content shape))
:selrect (gsh/content->selrect (:content shape))))
;; EVENTS ;; EVENTS
@ -402,20 +398,30 @@
page-id (:current-page-id state) page-id (:current-page-id state)
old-content (get-in state [:workspace-data :pages-index page-id :objects id :content]) 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-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]) content-modifiers (get-in state [:workspace-local :edit-path id :content-modifiers])
new-content (gsp/apply-content-modifiers old-content content-modifiers) new-content (gsp/apply-content-modifiers old-content content-modifiers)
new-selrect (gsh/content->selrect new-content) new-selrect (gsh/content->selrect new-content)
new-points (gsh/rect->points new-selrect)
rch [{:type :mod-obj rch [{:type :mod-obj
:id id :id id
:page-id page-id :page-id page-id
:operations [{:type :set :attr :content :val new-content} :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 uch [{:type :mod-obj
:id id :id id
:page-id page-id :page-id page-id
:operations [{:type :set :attr :content :val old-content} :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}) (rx/of (dwc/commit-changes rch uch {:commit-local? true})
(fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers))))))) (fn [state] (update-in state [:workspace-local :edit-path id] dissoc :content-modifiers)))))))
@ -428,20 +434,30 @@
page-id (:current-page-id state) page-id (:current-page-id state)
old-content (get-in state [:workspace-local :edit-path id :old-content]) old-content (get-in state [:workspace-local :edit-path id :old-content])
old-selrect (gsh/content->selrect 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-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-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 rch [{:type :mod-obj
:id id :id id
:page-id page-id :page-id page-id
:operations [{:type :set :attr :content :val new-content} :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 uch [{:type :mod-obj
:id id :id id
:page-id page-id :page-id page-id
:operations [{:type :set :attr :content :val old-content} :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})))))) (rx/of (dwc/commit-changes rch uch {:commit-local? true}))))))

View file

@ -270,7 +270,7 @@
(mf/defc multiple-selection-handlers (mf/defc multiple-selection-handlers
[{:keys [shapes selected zoom color show-distances] :as props}] [{: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) shape-center (geom/center-shape shape)
hover-id (-> (mf/deref refs/current-hover) first) hover-id (-> (mf/deref refs/current-hover) first)
@ -315,7 +315,7 @@
hover-id (when-not (= shape-id hover-id) hover-id) hover-id (when-not (= shape-id hover-id) hover-id)
hover-shape (mf/deref (refs/object-by-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] on-resize (fn [current-position initial-position event]
(dom/stop-propagation event) (dom/stop-propagation event)
(st/emit! (dw/start-resize current-position initial-position #{shape-id} shape'))) (st/emit! (dw/start-resize current-position initial-position #{shape-id} shape')))
@ -323,7 +323,6 @@
on-rotate on-rotate
#(do (dom/stop-propagation %) #(do (dom/stop-propagation %)
(st/emit! (dw/start-rotate [shape])))] (st/emit! (dw/start-rotate [shape])))]
[:* [:*
[:& controls {:shape shape' [:& controls {:shape shape'
:zoom zoom :zoom zoom