0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-18 13:04:38 -05:00

Correct selrect calculation

This commit is contained in:
alonso.torres 2021-09-20 12:55:51 +02:00
parent 56e2db22eb
commit fcc7b6791e
7 changed files with 77 additions and 33 deletions

View file

@ -134,6 +134,7 @@
(d/export gco/center-rect) (d/export gco/center-rect)
(d/export gco/center-points) (d/export gco/center-points)
(d/export gco/make-centered-rect) (d/export gco/make-centered-rect)
(d/export gco/transform-points)
(d/export gpr/rect->selrect) (d/export gpr/rect->selrect)
(d/export gpr/rect->points) (d/export gpr/rect->points)
@ -146,7 +147,6 @@
(d/export gtr/transform-matrix) (d/export gtr/transform-matrix)
(d/export gtr/inverse-transform-matrix) (d/export gtr/inverse-transform-matrix)
(d/export gtr/transform-point-center) (d/export gtr/transform-point-center)
(d/export gtr/transform-points)
(d/export gtr/transform-rect) (d/export gtr/transform-rect)
(d/export gtr/calculate-adjust-matrix) (d/export gtr/calculate-adjust-matrix)
(d/export gtr/update-group-selrect) (d/export gtr/update-group-selrect)

View file

@ -7,19 +7,19 @@
(ns app.common.geom.shapes.bool (ns app.common.geom.shapes.bool
(:require (:require
[app.common.geom.shapes.path :as gsp] [app.common.geom.shapes.path :as gsp]
[app.common.geom.shapes.rect :as gpr]
[app.common.path.bool :as pb] [app.common.path.bool :as pb]
[app.common.path.shapes-to-path :as stp])) [app.common.path.shapes-to-path :as stp]))
(defn update-bool-selrect (defn update-bool-selrect
"Calculates the selrect+points for the boolean shape"
[shape children objects] [shape children objects]
(let [selrect (->> children (let [content (->> children
(map #(stp/convert-to-path % objects)) (map #(stp/convert-to-path % objects))
(mapv :content) (mapv :content)
(pb/content-bool (:bool-type shape)) (pb/content-bool (:bool-type shape)))
(gsp/content->selrect))
points (gpr/rect->points selrect)] [points selrect] (gsp/content->points+selrect shape content)]
(-> shape (-> shape
(assoc :selrect selrect) (assoc :selrect selrect)
(assoc :points points)))) (assoc :points points))))

View file

@ -7,6 +7,7 @@
(ns app.common.geom.shapes.common (ns app.common.geom.shapes.common
(:require (:require
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.matrix :as gmt]
[app.common.math :as mth])) [app.common.math :as mth]))
(defn center-rect (defn center-rect
@ -48,3 +49,14 @@
:y (- (:y center) (/ height 2.0)) :y (- (:y center) (/ height 2.0))
:width width :width width
:height height}) :height height})
(defn transform-points
([points matrix]
(transform-points points nil matrix))
([points center matrix]
(let [prev (if center (gmt/translate-matrix center) (gmt/matrix))
post (if center (gmt/translate-matrix (gpt/negate center)) (gmt/matrix))
tr-point (fn [point]
(gpt/transform point (gmt/multiply prev matrix post)))]
(mapv tr-point points))))

View file

@ -9,6 +9,7 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.matrix :as gmt] [app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes.common :as gsc]
[app.common.geom.shapes.rect :as gpr] [app.common.geom.shapes.rect :as gpr]
[app.common.math :as mth] [app.common.math :as mth]
[app.common.path.commands :as upc])) [app.common.path.commands :as upc]))
@ -756,3 +757,45 @@
[_ to-p h1' h2'] (subcurve-range from-p to-p h1 h2 t0 t1)] [_ to-p h1' h2'] (subcurve-range from-p to-p h1 h2 t0 t1)]
(upc/make-curve-to (-> to-p #_(gpt/round 2)) h1' h2')))))))) (upc/make-curve-to (-> to-p #_(gpt/round 2)) h1' h2'))))))))
(defn content-center
[content]
(-> content
content->selrect
gsc/center-selrect))
(defn content->points+selrect
"Given the content of a shape, calculate its points and selrect"
[shape content]
(let [{:keys [flip-x flip-y]} shape
transform
(cond-> (:transform shape (gmt/matrix))
flip-x (gmt/scale (gpt/point -1 1))
flip-y (gmt/scale (gpt/point 1 -1)))
transform-inverse
(cond-> (gmt/matrix)
flip-x (gmt/scale (gpt/point -1 1))
flip-y (gmt/scale (gpt/point 1 -1))
:always (gmt/multiply (:transform-inverse shape (gmt/matrix))))
center (or (gsc/center-shape shape)
(content-center content))
base-content (transform-content
content
(gmt/transform-in center transform-inverse))
;; Calculates the new selrect with points given the old center
points (-> (content->selrect base-content)
(gpr/rect->points)
(gsc/transform-points center transform))
points-center (gsc/center-points points)
;; Points is now the selrect but the center is different so we can create the selrect
;; through points
selrect (-> points
(gsc/transform-points points-center transform-inverse)
(gpr/points->selrect))]
[points selrect]))

View file

@ -161,23 +161,12 @@
matrix matrix
(gmt/translate-matrix (gpt/negate center))))) (gmt/translate-matrix (gpt/negate center)))))
(defn transform-points
([points matrix]
(transform-points points nil matrix))
([points center matrix]
(let [prev (if center (gmt/translate-matrix center) (gmt/matrix))
post (if center (gmt/translate-matrix (gpt/negate center)) (gmt/matrix))
tr-point (fn [point]
(gpt/transform point (gmt/multiply prev matrix post)))]
(mapv tr-point points))))
(defn transform-rect (defn transform-rect
"Transform a rectangles and changes its attributes" "Transform a rectangles and changes its attributes"
[rect matrix] [rect matrix]
(let [points (-> (gpr/rect->points rect) (let [points (-> (gpr/rect->points rect)
(transform-points matrix))] (gco/transform-points matrix))]
(gpr/points->rect points))) (gpr/points->rect points)))
(defn calculate-adjust-matrix (defn calculate-adjust-matrix
@ -201,12 +190,12 @@
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 (max 1 (calculate-height points-temp)) h1 (max 1 (calculate-height points-temp))
h2 (max 1 (calculate-height (transform-points points-rec center stretch-matrix))) h2 (max 1 (calculate-height (gco/transform-points points-rec center stretch-matrix)))
h3 (if-not (mth/almost-zero? h2) (/ h1 h2) 1) h3 (if-not (mth/almost-zero? h2) (/ h1 h2) 1)
h3 (if (mth/nan? h3) 1 h3) h3 (if (mth/nan? h3) 1 h3)
w1 (max 1 (calculate-width points-temp)) w1 (max 1 (calculate-width points-temp))
w2 (max 1 (calculate-width (transform-points points-rec center stretch-matrix))) w2 (max 1 (calculate-width (gco/transform-points points-rec center stretch-matrix)))
w3 (if-not (mth/almost-zero? w2) (/ w1 w2) 1) w3 (if-not (mth/almost-zero? w2) (/ w1 w2) 1)
w3 (if (mth/nan? w3) 1 w3) w3 (if (mth/nan? w3) 1 w3)
@ -214,7 +203,7 @@
rotation-angle (calculate-rotation rotation-angle (calculate-rotation
center center
(transform-points points-rec (gco/center-points points-rec) stretch-matrix) (gco/transform-points points-rec (gco/center-points points-rec) stretch-matrix)
points-temp points-temp
flip-x flip-x
flip-y) flip-y)
@ -233,13 +222,13 @@
its properties. We adjust de x,y,width,height and create a custom transform" its properties. We adjust de x,y,width,height and create a custom transform"
[shape transform round-coords?] [shape transform round-coords?]
;; ;;
(let [points (-> shape :points (transform-points transform)) (let [points (-> shape :points (gco/transform-points transform))
center (gco/center-points points) center (gco/center-points points)
;; Reverse the current transformation stack to get the base rectangle ;; Reverse the current transformation stack to get the base rectangle
tr-inverse (:transform-inverse shape (gmt/matrix)) tr-inverse (:transform-inverse shape (gmt/matrix))
points-temp (transform-points points center tr-inverse) points-temp (gco/transform-points points center tr-inverse)
points-temp-dim (calculate-dimensions points-temp) points-temp-dim (calculate-dimensions points-temp)
;; This rectangle is the new data for the current rectangle. We want to change our rectangle ;; This rectangle is the new data for the current rectangle. We want to change our rectangle
@ -305,12 +294,12 @@
points (->> children (mapcat :points)) points (->> children (mapcat :points))
;; Invert to get the points minus the transforms applied to the group ;; Invert to get the points minus the transforms applied to the group
base-points (transform-points points shape-center (:transform-inverse group (gmt/matrix))) base-points (gco/transform-points points shape-center (:transform-inverse group (gmt/matrix)))
;; Defines the new selection rect with its transformations ;; Defines the new selection rect with its transformations
new-points (-> (gpr/points->selrect base-points) new-points (-> (gpr/points->selrect base-points)
(gpr/rect->points) (gpr/rect->points)
(transform-points shape-center (:transform group (gmt/matrix)))) (gco/transform-points shape-center (:transform group (gmt/matrix))))
;; Calculte the new selrect ;; Calculte the new selrect
new-selrect (gpr/points->selrect base-points)] new-selrect (gpr/points->selrect base-points)]
@ -544,9 +533,9 @@
transformed-parent-rect (-> parent-rect transformed-parent-rect (-> parent-rect
(gpr/rect->points) (gpr/rect->points)
(transform-points parent-displacement) (gco/transform-points parent-displacement)
(transform-points parent-origin (gmt/scale-matrix parent-vector)) (gco/transform-points parent-origin (gmt/scale-matrix parent-vector))
(transform-points parent-origin-2 (gmt/scale-matrix parent-vector-2)) (gco/transform-points parent-origin-2 (gmt/scale-matrix parent-vector-2))
(gpr/points->selrect)) (gpr/points->selrect))
;; Calculate the modifiers in the horizontal and vertical directions ;; Calculate the modifiers in the horizontal and vertical directions

View file

@ -107,10 +107,10 @@
(ptk/reify ::bool-to-group (ptk/reify ::bool-to-group
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [objects (wsh/lookup-page-objects state)] (let [objects (wsh/lookup-page-objects state)
(let [change-to-group change-to-group
(fn [shape] (bool->group shape objects))] (fn [shape] (bool->group shape objects))]
(rx/of (dch/update-shapes [shape-id] change-to-group {:reg-objects? true}))))))) (rx/of (dch/update-shapes [shape-id] change-to-group {:reg-objects? true}))))))
(defn change-bool-type (defn change-bool-type

View file

@ -158,7 +158,7 @@
(defmethod impl/handler :selection/query (defmethod impl/handler :selection/query
[{:keys [page-id rect frame-id reverse? full-frame? include-frames? clip-children?] [{:keys [page-id rect frame-id reverse? full-frame? include-frames? clip-children?]
:or {reverse? false full-frame? false include-frames? false include-booleans? true include-groups? true} :as message}] :or {reverse? false full-frame? false include-frames? false clip-children? true} :as message}]
(when-let [index (get @state page-id)] (when-let [index (get @state page-id)]
(query-index index rect frame-id full-frame? include-frames? clip-children? reverse?))) (query-index index rect frame-id full-frame? include-frames? clip-children? reverse?)))