0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-23 23:18:48 -05:00

🐛 Fix synchronization of geometry changes

This commit is contained in:
Andrés Moya 2020-11-25 15:22:19 +01:00 committed by Andrey Antukh
parent 56861e8d01
commit 40240d294a
2 changed files with 48 additions and 49 deletions

View file

@ -294,8 +294,6 @@
:internal.shape/proportion-lock
:internal.shape/rx
:internal.shape/ry
:internal.shape/cx
:internal.shape/cy
:internal.shape/x
:internal.shape/y
:internal.shape/exports
@ -319,7 +317,7 @@
:fill-color-ref-file :fill-group
:fill-color-ref-id :fill-group
:fill-opacity :fill-group
:content :text-content-group
:content :content-group
:font-family :text-font-group
:font-size :text-font-group
:font-style :text-font-group
@ -334,11 +332,19 @@
:stroke-style :stroke-group
:stroke-width :stroke-group
:stroke-alignment :stroke-group
:width :size-group
:height :size-group
:proportion :size-group
:rx :radius-group
:ry :radius-group
:selrect :geometry-group
:points :geometry-group
:locked :geometry-group
:proportion :geometry-group
:proportion-lock :geometry-group
:rx :geometry-group
:ry :geometry-group
:x :geometry-group
:y :geometry-group
:width :geometry-group
:height :geometry-group
:transform :geometry-group
:transform-inverse :geometry-group
:masked-group? :mask-group})
;; shapes-group is handled differently
@ -1074,7 +1080,12 @@
group (get component-sync-attrs attr)]
(cond-> shape
(and shape-ref group (not ignore) (not= val (get shape attr)))
(and shape-ref group (not ignore) (not= val (get shape attr))
;; FIXME: it's difficult to tell if the geometry changes affect
;; an individual shape inside the component, or are for
;; the whole component (in which case we shouldn't set
;; touched). For the moment we disable geometry touched.
(not= group :geometry-group))
(update :touched cph/set-touched-group group)
(nil? val)

View file

@ -14,6 +14,7 @@
[app.common.data :as d]
[app.common.pages-helpers :as cph]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.common.pages :as cp]
[app.util.logging :as log]
[app.util.text :as ut]))
@ -50,7 +51,7 @@
(declare move-shape)
(declare change-touched)
(declare update-attrs)
(declare calc-new-pos)
(declare reposition-shape)
;; ---- Create a new component ----
@ -658,16 +659,13 @@
(cph/get-parents parent-shape (:objects container))))
update-new-shape (fn [new-shape original-shape]
(let [new-pos (calc-new-pos new-shape
original-shape
root-instance
root-master)]
(let [new-shape (reposition-shape new-shape
root-master
root-instance)]
(cond-> new-shape
true
(assoc :shape-ref (:id original-shape)
:frame-id (:frame-id parent-shape)
:x (:x new-pos)
:y (:y new-pos))
:frame-id (:frame-id parent-shape))
(:component-id original-shape)
(assoc :component-id (:component-id original-shape))
@ -736,13 +734,9 @@
(cph/get-parents component-parent-shape (:objects component))))
update-new-shape (fn [new-shape original-shape]
(let [new-pos (calc-new-pos new-shape
original-shape
root-master
root-instance)]
(assoc new-shape
:x (:x new-pos)
:y (:y new-pos))))
(reposition-shape new-shape
root-instance
root-master))
update-original-shape (fn [original-shape new-shape]
(if-not (:shape-ref original-shape)
@ -966,23 +960,17 @@
(if (cph/page? container) "[P] " "[C] ")
(:name dest-shape)))
(let [; The position attributes need a special sync algorith, because we do
; not synchronize the absolute position, but the position relative of
; the container shape of the component.
new-pos (calc-new-pos dest-shape origin-shape dest-root origin-root)
touched (get dest-shape :touched #{})]
(let [; To synchronize geometry attributes we need to make a prior
; operation, because coordinates are absolute, but we need to
; sync only the position relative to the origin of the component.
; We solve this by moving the origin shape so it is aligned with
; the dest root before syncing.
origin-shape (reposition-shape origin-shape origin-root dest-root)
touched (get dest-shape :touched #{})]
(loop [attrs (seq (keys (dissoc cp/component-sync-attrs :x :y)))
roperations (if (or (not= (:x new-pos) (:x dest-shape))
(not= (:y new-pos) (:y dest-shape)))
[{:type :set :attr :x :val (:x new-pos)}
{:type :set :attr :y :val (:y new-pos)}]
[])
uoperations (if (or (not= (:x new-pos) (:x dest-shape))
(not= (:y new-pos) (:y dest-shape)))
[{:type :set :attr :x :val (:x dest-shape)}
{:type :set :attr :y :val (:y dest-shape)}]
[])]
(loop [attrs (seq (keys cp/component-sync-attrs))
roperations []
uoperations []]
(let [attr (first attrs)]
(if (nil? attr)
@ -1042,13 +1030,13 @@
(conj roperations roperation)
(conj uoperations uoperation))))))))))
(defn- calc-new-pos
[dest-shape origin-shape dest-root origin-root]
(let [root-pos (gpt/point (:x dest-root) (:y dest-root))
origin-root-pos (gpt/point (:x origin-root) (:y origin-root))
origin-pos (gpt/point (:x origin-shape) (:y origin-shape))
delta (gpt/subtract origin-pos origin-root-pos)
shape-pos (gpt/point (:x dest-shape) (:y dest-shape))
new-pos (gpt/add root-pos delta)]
new-pos))
(defn- reposition-shape
[shape origin-root dest-root]
(let [shape-pos (fn [shape]
(gpt/point (get-in shape [:selrect :x])
(get-in shape [:selrect :y])))
origin-root-pos (shape-pos origin-root)
dest-root-pos (shape-pos dest-root)
delta (gpt/subtract dest-root-pos origin-root-pos)]
(geom/move shape delta)))