0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-13 00:01:51 -05:00

🐛 Fix align and distribute grouped objects

This commit is contained in:
Andrés Moya 2020-04-10 12:43:58 +02:00 committed by Alonso Torres
parent e9d60913d0
commit 43550af175
2 changed files with 21 additions and 10 deletions

View file

@ -1461,7 +1461,7 @@
objects (get-in state [:workspace-data page-id :objects]) objects (get-in state [:workspace-data page-id :objects])
selected (get-in state [:workspace-local :selected]) selected (get-in state [:workspace-local :selected])
moved-objs (if (= 1 (count selected)) moved-objs (if (= 1 (count selected))
[(align-object-to-frame objects (first selected) axis)] (align-object-to-frame objects (first selected) axis)
(align-objects-list objects selected axis)) (align-objects-list objects selected axis))
updated-objs (merge objects (d/index-by :id moved-objs))] updated-objs (merge objects (d/index-by :id moved-objs))]
(assoc-in state [:workspace-data page-id :objects] updated-objs))))) (assoc-in state [:workspace-data page-id :objects] updated-objs)))))
@ -1470,13 +1470,13 @@
[objects object-id axis] [objects object-id axis]
(let [object (get objects object-id) (let [object (get objects object-id)
frame (get objects (:frame-id object))] frame (get objects (:frame-id object))]
(geom/align-to-rect object frame axis))) (geom/align-to-rect object frame axis objects)))
(defn align-objects-list (defn align-objects-list
[objects selected axis] [objects selected axis]
(let [selected-objs (map #(get objects %) selected) (let [selected-objs (map #(get objects %) selected)
rect (geom/selection-rect selected-objs)] rect (geom/selection-rect selected-objs)]
(map #(geom/align-to-rect % rect axis) selected-objs))) (mapcat #(geom/align-to-rect % rect axis objects) selected-objs)))
(defn distribute-objects (defn distribute-objects
[axis] [axis]
@ -1489,7 +1489,7 @@
objects (get-in state [:workspace-data page-id :objects]) objects (get-in state [:workspace-data page-id :objects])
selected (get-in state [:workspace-local :selected]) selected (get-in state [:workspace-local :selected])
selected-objs (map #(get objects %) selected) selected-objs (map #(get objects %) selected)
moved-objs (geom/distribute-space selected-objs axis) moved-objs (geom/distribute-space selected-objs axis objects)
updated-objs (merge objects (d/index-by :id moved-objs))] updated-objs (merge objects (d/index-by :id moved-objs))]
(assoc-in state [:workspace-data page-id :objects] updated-objs))))) (assoc-in state [:workspace-data page-id :objects] updated-objs)))))

View file

@ -11,6 +11,7 @@
[uxbox.util.geom.matrix :as gmt] [uxbox.util.geom.matrix :as gmt]
[uxbox.util.geom.point :as gpt] [uxbox.util.geom.point :as gpt]
[uxbox.util.math :as mth] [uxbox.util.math :as mth]
[uxbox.main.data.helpers :as helpers]
[uxbox.main.store :as st])) [uxbox.main.store :as st]))
;; --- Relative Movement ;; --- Relative Movement
@ -61,6 +62,13 @@
(map #(update % :y + dy)))] (map #(update % :y + dy)))]
(assoc shape :segments (into [] xf segments)))) (assoc shape :segments (into [] xf segments))))
(defn recursive-move
"Move the shape and all its recursive children."
[shape dpoint objects]
(let [children-ids (helpers/get-children (:id shape) objects)
children (map #(get objects %) children-ids)]
(map #(move % dpoint) (cons shape children))))
;; --- Absolute Movement ;; --- Absolute Movement
(declare absolute-move-rect) (declare absolute-move-rect)
@ -608,13 +616,14 @@
"Move the shape so that it is aligned with the given rectangle "Move the shape so that it is aligned with the given rectangle
in the given axis. Take account the form of the shape and the in the given axis. Take account the form of the shape and the
possible rotation. What is aligned is the rectangle that wraps possible rotation. What is aligned is the rectangle that wraps
the shape with the given rectangle." the shape with the given rectangle. If the shape is a group,
[shape rect axis] move also all of its recursive children."
[shape rect axis objects]
(let [wrapper-rect (selection-rect [shape]) (let [wrapper-rect (selection-rect [shape])
align-pos (calc-align-pos wrapper-rect rect axis) align-pos (calc-align-pos wrapper-rect rect axis)
delta {:x (- (:x align-pos) (:x wrapper-rect)) delta {:x (- (:x align-pos) (:x wrapper-rect))
:y (- (:y align-pos) (:y wrapper-rect))}] :y (- (:y align-pos) (:y wrapper-rect))}]
(move shape delta))) (recursive-move shape delta objects)))
(defn calc-align-pos (defn calc-align-pos
[wrapper-rect rect axis] [wrapper-rect rect axis]
@ -651,8 +660,9 @@
"Distribute equally the space between shapes in the given axis. If "Distribute equally the space between shapes in the given axis. If
there is no space enough, it does nothing. It takes into account there is no space enough, it does nothing. It takes into account
the form of the shape and the rotation, what is distributed is the form of the shape and the rotation, what is distributed is
the wrapping recangles of the shapes." the wrapping recangles of the shapes. If any shape is a group,
[shapes axis] move also all of its recursive children."
[shapes axis objects]
(let [coord (if (= axis :horizontal) :x :y) (let [coord (if (= axis :horizontal) :x :y)
other-coord (if (= axis :horizontal) :y :x) other-coord (if (= axis :horizontal) :y :x)
size (if (= axis :horizontal) :width :height) size (if (= axis :horizontal) :width :height)
@ -685,7 +695,8 @@
new-pos new-pos
(conj deltas delta)))))] (conj deltas delta)))))]
(map #(move %1 {coord %2 other-coord 0}) sorted-shapes deltas))))) (mapcat #(recursive-move %1 {coord %2 other-coord 0} objects)
sorted-shapes deltas)))))
;; --- Helpers ;; --- Helpers