mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +02:00
✨ Improve algorithm for constraints calculation
This commit is contained in:
parent
ca4ce569e7
commit
3295685938
1 changed files with 59 additions and 86 deletions
|
@ -376,8 +376,7 @@
|
||||||
child-rect (:selrect child)
|
child-rect (:selrect child)
|
||||||
|
|
||||||
; If the modifiers include a resize vector, apply it to the parent,
|
; If the modifiers include a resize vector, apply it to the parent,
|
||||||
; and then calculate the displacement of the side opposite to the
|
; to check the difference and calculate child transformations.
|
||||||
; origin of the vector.
|
|
||||||
origin (-> (:resize-origin parent-modifiers)
|
origin (-> (:resize-origin parent-modifiers)
|
||||||
((d/nilf transform-point-center)
|
((d/nilf transform-point-center)
|
||||||
(gco/center-shape parent)
|
(gco/center-shape parent)
|
||||||
|
@ -390,78 +389,50 @@
|
||||||
(gmt/scale-matrix (get parent-modifiers :resize-vector (gpt/point 1 1))))
|
(gmt/scale-matrix (get parent-modifiers :resize-vector (gpt/point 1 1))))
|
||||||
(gpr/points->selrect))
|
(gpr/points->selrect))
|
||||||
|
|
||||||
orig-h (when origin
|
|
||||||
(cond
|
|
||||||
(mth/close? (:x origin) (:x1 parent-rect)) :left
|
|
||||||
(mth/close? (:x origin) (:x2 parent-rect)) :right
|
|
||||||
:else :middle))
|
|
||||||
|
|
||||||
orig-v (when origin
|
|
||||||
(cond
|
|
||||||
(mth/close? (:y origin) (:y1 parent-rect)) :top
|
|
||||||
(mth/close? (:y origin) (:y2 parent-rect)) :bottom
|
|
||||||
:else :middle))
|
|
||||||
|
|
||||||
delta-h (when orig-h
|
|
||||||
(cond (= orig-h :left)
|
|
||||||
(- (:x2 transformed-parent-rect) (:x2 parent-rect))
|
|
||||||
|
|
||||||
(= orig-h :right)
|
|
||||||
(- (:x1 transformed-parent-rect) (:x1 parent-rect))
|
|
||||||
|
|
||||||
:else 0))
|
|
||||||
|
|
||||||
delta-v (when orig-v
|
|
||||||
(cond (= orig-v :top)
|
|
||||||
(- (:y2 transformed-parent-rect) (:y2 parent-rect))
|
|
||||||
|
|
||||||
(= orig-v :bottom)
|
|
||||||
(- (:y1 transformed-parent-rect) (:y1 parent-rect))
|
|
||||||
|
|
||||||
:else 0))
|
|
||||||
|
|
||||||
;; Calculate the modifiers in the horizontal and vertical directions
|
;; Calculate the modifiers in the horizontal and vertical directions
|
||||||
;; depending on the constraints, and the origin of the resize vector.
|
;; depending on the child constraints.
|
||||||
constraints-h (get child :constraints-h (spec/default-constraints-h child))
|
constraints-h (get child :constraints-h (spec/default-constraints-h child))
|
||||||
constraints-v (get child :constraints-v (spec/default-constraints-v child))
|
constraints-v (get child :constraints-v (spec/default-constraints-v child))
|
||||||
|
|
||||||
modifiers-h (case constraints-h
|
modifiers-h (case constraints-h
|
||||||
:left
|
:left
|
||||||
(if (= orig-h :right)
|
(let [delta-left (- (:x1 transformed-parent-rect) (:x1 parent-rect))]
|
||||||
{:displacement (gpt/point delta-h 0)} ;; we convert to matrix below
|
(if-not (mth/almost-zero? delta-left)
|
||||||
{})
|
{:displacement (gpt/point delta-left 0)} ;; we convert to matrix below
|
||||||
|
{}))
|
||||||
|
|
||||||
:right
|
:right
|
||||||
(if (= orig-h :left)
|
(let [delta-right (- (:x2 transformed-parent-rect) (:x2 parent-rect))]
|
||||||
{:displacement (gpt/point delta-h 0)}
|
(if-not (mth/almost-zero? delta-right)
|
||||||
{})
|
{:displacement (gpt/point delta-right 0)}
|
||||||
|
{}))
|
||||||
|
|
||||||
:leftright
|
:leftright
|
||||||
(cond (= orig-h :left)
|
(let [delta-left (- (:x1 transformed-parent-rect) (:x1 parent-rect))
|
||||||
{:resize-origin (-> (gpt/point (:x1 child-rect) (:y1 child-rect))
|
delta-width (- (:width transformed-parent-rect) (:width parent-rect))]
|
||||||
(transform-point-center
|
(if (or (not (mth/almost-zero? delta-left))
|
||||||
(gco/center-shape child)
|
(not (mth/almost-zero? delta-width)))
|
||||||
(:transform child (gmt/matrix))))
|
{:displacement (gpt/point delta-left 0)
|
||||||
:resize-vector (gpt/point (/ (+ (:width child-rect) delta-h)
|
:resize-origin (-> (gpt/point (+ (:x1 child-rect) delta-left)
|
||||||
(:width child-rect))
|
(:y1 child-rect))
|
||||||
1)}
|
(transform-point-center
|
||||||
|
(gco/center-rect child-rect)
|
||||||
(= orig-h :right)
|
(:transform child (gmt/matrix))))
|
||||||
{:resize-origin (-> (gpt/point (:x2 child-rect) (:y1 child-rect))
|
:resize-vector (gpt/point (/ (+ (:width child-rect) delta-width)
|
||||||
(transform-point-center
|
(:width child-rect)) 1)}
|
||||||
(gco/center-shape child)
|
{}))
|
||||||
(:transform child (gmt/matrix))))
|
|
||||||
:resize-vector (gpt/point (/ (- (:width child-rect) delta-h)
|
|
||||||
(:width child-rect))
|
|
||||||
1)}
|
|
||||||
|
|
||||||
:else {})
|
|
||||||
|
|
||||||
:center
|
:center
|
||||||
{:displacement (gpt/point (/ delta-h 2) 0)}
|
(let [parent-center (gco/center-rect parent-rect)
|
||||||
|
transformed-parent-center (gco/center-rect transformed-parent-rect)
|
||||||
|
delta-center (- (:x transformed-parent-center) (:x parent-center))]
|
||||||
|
(if-not (mth/almost-zero? delta-center)
|
||||||
|
{:displacement (gpt/point delta-center 0)}
|
||||||
|
{}))
|
||||||
|
|
||||||
:scale
|
:scale
|
||||||
(if (:resize-origin parent-modifiers)
|
(if (and (:resize-vector parent-modifiers)
|
||||||
|
(not (mth/close? (:x (:resize-vector parent-modifiers)) 1)))
|
||||||
{:resize-origin (:resize-origin parent-modifiers)
|
{:resize-origin (:resize-origin parent-modifiers)
|
||||||
:resize-vector (gpt/point (:x (:resize-vector parent-modifiers)) 1)}
|
:resize-vector (gpt/point (:x (:resize-vector parent-modifiers)) 1)}
|
||||||
{})
|
{})
|
||||||
|
@ -470,41 +441,43 @@
|
||||||
|
|
||||||
modifiers-v (case constraints-v
|
modifiers-v (case constraints-v
|
||||||
:top
|
:top
|
||||||
(if (= orig-v :bottom)
|
(let [delta-top (- (:y1 transformed-parent-rect) (:y1 parent-rect))]
|
||||||
{:displacement (gpt/point 0 delta-v)}
|
(if-not (mth/almost-zero? delta-top)
|
||||||
{})
|
{:displacement (gpt/point 0 delta-top)} ;; we convert to matrix below
|
||||||
|
{}))
|
||||||
|
|
||||||
:bottom
|
:bottom
|
||||||
(if (= orig-v :top)
|
(let [delta-bottom (- (:y2 transformed-parent-rect) (:y2 parent-rect))]
|
||||||
{:displacement (gpt/point 0 delta-v)}
|
(if-not (mth/almost-zero? delta-bottom)
|
||||||
{})
|
{:displacement (gpt/point 0 delta-bottom)}
|
||||||
|
{}))
|
||||||
|
|
||||||
:topbottom
|
:topbottom
|
||||||
(cond (= orig-v :top)
|
(let [delta-top (- (:y1 transformed-parent-rect) (:y1 parent-rect))
|
||||||
{:resize-origin (-> (gpt/point (:x1 child-rect) (:y1 child-rect))
|
delta-height (- (:height transformed-parent-rect) (:height parent-rect))]
|
||||||
(transform-point-center
|
(if (or (not (mth/almost-zero? delta-top))
|
||||||
(gco/center-shape child)
|
(not (mth/almost-zero? delta-height)))
|
||||||
(:transform child (gmt/matrix))))
|
{:displacement (gpt/point 0 delta-top)
|
||||||
:resize-vector (gpt/point 1
|
:resize-origin (-> (gpt/point (:x1 child-rect)
|
||||||
(/ (+ (:height child-rect) delta-v)
|
(+ (:y1 child-rect) delta-top))
|
||||||
|
(transform-point-center
|
||||||
|
(gco/center-rect child-rect)
|
||||||
|
(:transform child (gmt/matrix))))
|
||||||
|
:resize-vector (gpt/point 1 (/ (+ (:height child-rect) delta-height)
|
||||||
(:height child-rect)))}
|
(:height child-rect)))}
|
||||||
|
{}))
|
||||||
(= orig-v :bottom)
|
|
||||||
{:resize-origin (-> (gpt/point (:x1 child-rect) (:y2 child-rect))
|
|
||||||
(transform-point-center
|
|
||||||
(gco/center-shape child)
|
|
||||||
(:transform child (gmt/matrix))))
|
|
||||||
:resize-vector (gpt/point 1
|
|
||||||
(/ (- (:height child-rect) delta-v)
|
|
||||||
(:height child-rect)))}
|
|
||||||
|
|
||||||
:else {})
|
|
||||||
|
|
||||||
:center
|
:center
|
||||||
{:displacement (gpt/point 0 (/ delta-v 2))}
|
(let [parent-center (gco/center-rect parent-rect)
|
||||||
|
transformed-parent-center (gco/center-rect transformed-parent-rect)
|
||||||
|
delta-center (- (:y transformed-parent-center) (:y parent-center))]
|
||||||
|
(if-not (mth/almost-zero? delta-center)
|
||||||
|
{:displacement (gpt/point 0 delta-center)}
|
||||||
|
{}))
|
||||||
|
|
||||||
:scale
|
:scale
|
||||||
(if (:resize-origin parent-modifiers)
|
(if (and (:resize-vector parent-modifiers)
|
||||||
|
(not (mth/close? (:y (:resize-vector parent-modifiers)) 1)))
|
||||||
{:resize-origin (:resize-origin parent-modifiers)
|
{:resize-origin (:resize-origin parent-modifiers)
|
||||||
:resize-vector (gpt/point 1 (:y (:resize-vector parent-modifiers)))}
|
:resize-vector (gpt/point 1 (:y (:resize-vector parent-modifiers)))}
|
||||||
{})
|
{})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue