mirror of
https://github.com/penpot/penpot.git
synced 2025-04-01 17:41:50 -05:00
✨ Improve transforms performance
This commit is contained in:
parent
694d90d485
commit
69bb4654c9
20 changed files with 402 additions and 247 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
(ns app.common.attrs
|
||||
(:require
|
||||
[app.common.geom.shapes.transforms :as gst]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
[app.common.math :as mth]))
|
||||
|
||||
(defn- get-attr
|
||||
|
@ -24,7 +24,7 @@
|
|||
value
|
||||
(if-let [points (:points obj)]
|
||||
(if (not= points :multiple)
|
||||
(let [rect (gst/selection-rect [obj])]
|
||||
(let [rect (gtr/selection-rect [obj])]
|
||||
(if (= attr :ox) (:x rect) (:y rect)))
|
||||
:multiple)
|
||||
(get obj attr ::unset)))
|
||||
|
|
|
@ -91,27 +91,34 @@
|
|||
|
||||
(defn multiply
|
||||
([^Matrix m1 ^Matrix m2]
|
||||
(let [m1a (.-a m1)
|
||||
m1b (.-b m1)
|
||||
m1c (.-c m1)
|
||||
m1d (.-d m1)
|
||||
m1e (.-e m1)
|
||||
m1f (.-f m1)
|
||||
(cond
|
||||
;; nil matrixes are equivalent to unit-matrix
|
||||
(and (nil? m1) (nil? m2)) (matrix)
|
||||
(nil? m1) m2
|
||||
(nil? m2) m1
|
||||
|
||||
m2a (.-a m2)
|
||||
m2b (.-b m2)
|
||||
m2c (.-c m2)
|
||||
m2d (.-d m2)
|
||||
m2e (.-e m2)
|
||||
m2f (.-f m2)]
|
||||
:else
|
||||
(let [m1a (.-a m1)
|
||||
m1b (.-b m1)
|
||||
m1c (.-c m1)
|
||||
m1d (.-d m1)
|
||||
m1e (.-e m1)
|
||||
m1f (.-f m1)
|
||||
|
||||
(Matrix.
|
||||
(+ (* m1a m2a) (* m1c m2b))
|
||||
(+ (* m1b m2a) (* m1d m2b))
|
||||
(+ (* m1a m2c) (* m1c m2d))
|
||||
(+ (* m1b m2c) (* m1d m2d))
|
||||
(+ (* m1a m2e) (* m1c m2f) m1e)
|
||||
(+ (* m1b m2e) (* m1d m2f) m1f))))
|
||||
m2a (.-a m2)
|
||||
m2b (.-b m2)
|
||||
m2c (.-c m2)
|
||||
m2d (.-d m2)
|
||||
m2e (.-e m2)
|
||||
m2f (.-f m2)]
|
||||
|
||||
(Matrix.
|
||||
(+ (* m1a m2a) (* m1c m2b))
|
||||
(+ (* m1b m2a) (* m1d m2b))
|
||||
(+ (* m1a m2c) (* m1c m2d))
|
||||
(+ (* m1b m2c) (* m1d m2d))
|
||||
(+ (* m1a m2e) (* m1c m2f) m1e)
|
||||
(+ (* m1b m2e) (* m1d m2f) m1f)))))
|
||||
|
||||
([m1 m2 & others]
|
||||
(reduce multiply (multiply m1 m2) others)))
|
||||
|
|
|
@ -189,6 +189,10 @@
|
|||
(defn angle-sign [v1 v2]
|
||||
(if (> (* (:y v1) (:x v2)) (* (:x v1) (:y v2))) -1 1))
|
||||
|
||||
(defn signed-angle-with-other
|
||||
[v1 v2]
|
||||
(* (angle-sign v1 v2) (angle-with-other v1 v2)))
|
||||
|
||||
(defn update-angle
|
||||
"Update the angle of the point."
|
||||
[p angle]
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
[app.common.geom.shapes.common :as gco]
|
||||
[app.common.geom.shapes.constraints :as gct]
|
||||
[app.common.geom.shapes.corners :as gsc]
|
||||
[app.common.geom.shapes.intersect :as gin]
|
||||
[app.common.geom.shapes.intersect :as gsi]
|
||||
[app.common.geom.shapes.modifiers :as gsm]
|
||||
[app.common.geom.shapes.path :as gsp]
|
||||
[app.common.geom.shapes.rect :as gpr]
|
||||
|
@ -178,8 +178,6 @@
|
|||
(dm/export gtr/transform-bounds)
|
||||
(dm/export gtr/move-position-data)
|
||||
(dm/export gtr/apply-objects-modifiers)
|
||||
(dm/export gtr/parent-coords-rect)
|
||||
(dm/export gtr/parent-coords-points)
|
||||
|
||||
;; Constratins
|
||||
(dm/export gct/calc-child-modifiers)
|
||||
|
@ -190,10 +188,10 @@
|
|||
(dm/export gsp/open-path?)
|
||||
|
||||
;; Intersection
|
||||
(dm/export gin/overlaps?)
|
||||
(dm/export gin/has-point?)
|
||||
(dm/export gin/has-point-rect?)
|
||||
(dm/export gin/rect-contains-shape?)
|
||||
(dm/export gsi/overlaps?)
|
||||
(dm/export gsi/has-point?)
|
||||
(dm/export gsi/has-point-rect?)
|
||||
(dm/export gsi/rect-contains-shape?)
|
||||
|
||||
;; Bool
|
||||
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
|
||||
(ns app.common.geom.shapes.constraints
|
||||
(:require
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
[app.common.geom.shapes.intersect :as gsi]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.geom.shapes.rect :as gre]
|
||||
[app.common.geom.shapes.transforms :as gst]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
@ -184,7 +183,7 @@
|
|||
(ctm/move-modifiers (displacement end-before end-after))))
|
||||
|
||||
(defmethod constraint-modifier :fixed
|
||||
[_ axis child-points-before parent-points-before child-points-after parent-points-after transformed-parent]
|
||||
[_ axis child-points-before parent-points-before child-points-after parent-points-after {:keys [transform transform-inverse]} modifiers]
|
||||
(let [;; Same as constraint end
|
||||
end-before (end-vector axis child-points-before parent-points-before)
|
||||
end-after (end-vector axis child-points-after parent-points-after)
|
||||
|
@ -203,11 +202,16 @@
|
|||
;; displacement (so its left+top position is constant)
|
||||
scale (/ (gpt/length after-vec) (gpt/length before-vec))
|
||||
|
||||
resize-origin (first child-points-after)
|
||||
{:keys [transform transform-inverse]} transformed-parent]
|
||||
resize-origin (gpo/origin child-points-after)
|
||||
|
||||
modif-transform (ctm/modifiers->transform modifiers)
|
||||
modif-transform-inverse (gmt/inverse modif-transform)
|
||||
resize-transform (gmt/multiply modif-transform transform)
|
||||
resize-transform-inverse (gmt/multiply transform-inverse modif-transform-inverse)
|
||||
|
||||
resize-vector (get-scale axis scale)]
|
||||
(-> (ctm/empty)
|
||||
(ctm/resize (get-scale axis scale) resize-origin transform transform-inverse)
|
||||
(ctm/resize resize-vector resize-origin resize-transform resize-transform-inverse)
|
||||
(ctm/move disp-start))))
|
||||
|
||||
(defmethod constraint-modifier :center
|
||||
|
@ -245,37 +249,36 @@
|
|||
:top
|
||||
:scale)))
|
||||
|
||||
(defn bounding-box-parent-transform
|
||||
"Returns a bounding box for the child in the same coordinate system
|
||||
as the parent.
|
||||
Returns a points array"
|
||||
[child parent]
|
||||
(-> child
|
||||
:points
|
||||
(gco/transform-points (:transform-inverse parent))
|
||||
(gre/points->rect)
|
||||
(gre/rect->points) ;; Restore to points so we can transform them
|
||||
(gco/transform-points (:transform parent))))
|
||||
|
||||
(defn normalize-modifiers
|
||||
"Before aplying constraints we need to remove the deformation caused by the resizing of the parent"
|
||||
[constraints-h constraints-v modifiers child parent transformed-child {:keys [transform transform-inverse] :as transformed-parent}]
|
||||
[constraints-h constraints-v modifiers child {:keys [transform transform-inverse] :as parent} transformed-child-bounds transformed-parent-bounds]
|
||||
|
||||
(let [child-bb-before (gst/parent-coords-rect child parent)
|
||||
child-bb-after (gst/parent-coords-rect transformed-child transformed-parent)
|
||||
scale-x (/ (:width child-bb-before) (:width child-bb-after))
|
||||
scale-y (/ (:height child-bb-before) (:height child-bb-after))
|
||||
resize-origin (-> transformed-parent :points gpo/origin)]
|
||||
(let [child-bb-before (gpo/parent-coords-bounds (:points child) (:points parent))
|
||||
child-bb-after (gpo/parent-coords-bounds transformed-child-bounds transformed-parent-bounds)
|
||||
|
||||
(cond-> modifiers
|
||||
(not= :scale constraints-h)
|
||||
(ctm/resize (gpt/point scale-x 1) resize-origin transform transform-inverse)
|
||||
scale-x (if (= :scale constraints-h)
|
||||
1
|
||||
(/ (gpo/width-points child-bb-before) (gpo/width-points child-bb-after)))
|
||||
|
||||
(not= :scale constraints-v)
|
||||
(ctm/resize (gpt/point 1 scale-y) resize-origin transform transform-inverse))))
|
||||
scale-y (if (= :scale constraints-v)
|
||||
1
|
||||
(/ (gpo/height-points child-bb-before) (gpo/height-points child-bb-after)))
|
||||
|
||||
resize-vector (gpt/point scale-x scale-y)
|
||||
modif-transform (ctm/modifiers->transform modifiers)
|
||||
modif-transform-inverse (gmt/inverse modif-transform)
|
||||
resize-transform (gmt/multiply modif-transform transform)
|
||||
resize-transform-inverse (gmt/multiply transform-inverse modif-transform-inverse)
|
||||
resize-origin (gpo/origin transformed-child-bounds)]
|
||||
(-> modifiers
|
||||
(ctm/resize
|
||||
resize-vector
|
||||
resize-origin
|
||||
resize-transform
|
||||
resize-transform-inverse))))
|
||||
|
||||
(defn calc-child-modifiers
|
||||
[parent child modifiers ignore-constraints transformed-parent]
|
||||
[parent child modifiers ignore-constraints parent-bounds transformed-parent-bounds]
|
||||
|
||||
(let [modifiers (ctm/select-child-modifiers modifiers)
|
||||
|
||||
|
@ -292,26 +295,24 @@
|
|||
(if (and (= :scale constraints-h) (= :scale constraints-v))
|
||||
modifiers
|
||||
|
||||
(let [transformed-child (gst/transform-shape child (ctm/select-child-modifiers modifiers))
|
||||
modifiers (normalize-modifiers constraints-h constraints-v modifiers child parent transformed-child transformed-parent)
|
||||
(let [child-bounds (:points child)
|
||||
modifiers (ctm/select-child-modifiers modifiers)
|
||||
transformed-child-bounds (gtr/transform-bounds child-bounds modifiers)
|
||||
modifiers (normalize-modifiers constraints-h constraints-v modifiers child parent transformed-child-bounds transformed-parent-bounds)
|
||||
transformed-child-bounds (gtr/transform-bounds child-bounds modifiers)
|
||||
|
||||
transformed-child (gst/transform-shape child modifiers)
|
||||
|
||||
parent-points-before (bounding-box-parent-transform parent parent)
|
||||
child-points-before (bounding-box-parent-transform child parent)
|
||||
parent-points-after (bounding-box-parent-transform transformed-parent transformed-parent)
|
||||
child-points-after (bounding-box-parent-transform transformed-child transformed-parent)
|
||||
child-points-before (gpo/parent-coords-bounds child-bounds parent-bounds)
|
||||
child-points-after (gpo/parent-coords-bounds transformed-child-bounds transformed-parent-bounds)
|
||||
|
||||
modifiers-h (constraint-modifier (constraints-h const->type+axis) :x
|
||||
child-points-before parent-points-before
|
||||
child-points-after parent-points-after
|
||||
transformed-parent)
|
||||
child-points-before parent-bounds
|
||||
child-points-after transformed-parent-bounds
|
||||
parent modifiers)
|
||||
|
||||
modifiers-v (constraint-modifier (constraints-v const->type+axis) :y
|
||||
child-points-before parent-points-before
|
||||
child-points-after parent-points-after
|
||||
transformed-parent)]
|
||||
|
||||
child-points-before parent-bounds
|
||||
child-points-after transformed-parent-bounds
|
||||
parent modifiers)]
|
||||
(-> modifiers
|
||||
(ctm/add-modifiers modifiers-h)
|
||||
(ctm/add-modifiers modifiers-v))))))
|
||||
|
|
|
@ -10,25 +10,24 @@
|
|||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
[app.common.geom.shapes.flex-layout.lines :as fli]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.geom.shapes.rect :as gsr]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.shape.layout :as ctl]))
|
||||
|
||||
(defn drop-child-areas
|
||||
[{:keys [transform-inverse] :as frame} parent-rect child index reverse? prev-x prev-y last?]
|
||||
[frame parent-rect child-bounds index reverse? prev-x prev-y last?]
|
||||
|
||||
(let [col? (ctl/col? frame)
|
||||
row? (ctl/row? frame)
|
||||
[layout-gap-row layout-gap-col] (ctl/gaps frame)
|
||||
|
||||
start-p (-> child :points first)
|
||||
center (gco/center-shape frame)
|
||||
start-p (gmt/transform-point-center start-p center transform-inverse)
|
||||
start-p (gpo/origin child-bounds)
|
||||
|
||||
box-x (:x start-p)
|
||||
box-y (:y start-p)
|
||||
box-width (-> child :selrect :width)
|
||||
box-height (-> child :selrect :height)
|
||||
box-width (gpo/width-points child-bounds)
|
||||
box-height (gpo/height-points child-bounds)
|
||||
|
||||
x (if col? (:x parent-rect) prev-x)
|
||||
y (if row? (:y parent-rect) prev-y)
|
||||
|
@ -148,47 +147,45 @@
|
|||
from-idx 0
|
||||
prev-line-x (:x frame)
|
||||
prev-line-y (:y frame)
|
||||
lines (seq lines)]
|
||||
|
||||
current-line (first lines)
|
||||
lines (rest lines)]
|
||||
|
||||
(if (nil? current-line)
|
||||
(if (empty? lines)
|
||||
areas
|
||||
|
||||
(let [line-area (drop-line-area frame current-line prev-line-x prev-line-y (nil? (first lines)))
|
||||
(let [current-line (first lines)
|
||||
line-area (drop-line-area frame current-line prev-line-x prev-line-y (empty? (rest lines)))
|
||||
children (subvec children from-idx (+ from-idx (:num-children current-line)))
|
||||
|
||||
next-areas
|
||||
(loop [areas areas
|
||||
prev-child-x (:x line-area)
|
||||
prev-child-y (:y line-area)
|
||||
[index child] (first children)
|
||||
children (rest children)]
|
||||
children (seq children)]
|
||||
|
||||
(if (nil? child)
|
||||
(if (empty? children)
|
||||
areas
|
||||
|
||||
(let [[child-area child-area-start child-area-end]
|
||||
(drop-child-areas frame line-area child index (not reverse?) prev-child-x prev-child-y (nil? (first children)))]
|
||||
(let [[index [child-bounds _]] (first children)
|
||||
[child-area child-area-start child-area-end]
|
||||
(drop-child-areas frame line-area child-bounds index (not reverse?) prev-child-x prev-child-y (empty? (rest children)))]
|
||||
(recur (conj areas child-area-start child-area-end)
|
||||
(+ (:x child-area) (:width child-area))
|
||||
(+ (:y child-area) (:height child-area))
|
||||
(first children)
|
||||
(rest children)))))]
|
||||
|
||||
(recur next-areas
|
||||
(+ from-idx (:num-children current-line))
|
||||
(+ (:x line-area) (:width line-area))
|
||||
(+ (:y line-area) (:height line-area))
|
||||
(first lines)
|
||||
(rest lines)))))))
|
||||
|
||||
(defn get-drop-index
|
||||
[frame-id objects position]
|
||||
(let [frame (get objects frame-id)
|
||||
position (gmt/transform-point-center position (gco/center-shape frame) (:transform-inverse frame))
|
||||
children (cph/get-immediate-children objects frame-id)
|
||||
layout-data (fli/calc-layout-data frame children)
|
||||
children (->> (cph/get-immediate-children objects frame-id)
|
||||
(map #(vector (gpo/parent-coords-bounds (:points %) (:points frame)) %)))
|
||||
layout-data (fli/calc-layout-data frame children (:points frame))
|
||||
drop-areas (layout-drop-areas frame layout-data children)
|
||||
area (d/seek #(gsr/contains-point? % position) drop-areas)]
|
||||
(:index area)))
|
||||
|
|
|
@ -9,21 +9,20 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.geom.shapes.flex-layout.positions :as flp]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.geom.shapes.transforms :as gst]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.shape.layout :as ctl]))
|
||||
|
||||
(def conjv (fnil conj []))
|
||||
|
||||
(defn layout-bounds
|
||||
[{:keys [layout-padding layout-padding-type] :as shape}]
|
||||
[{:keys [layout-padding layout-padding-type] :as shape} shape-bounds]
|
||||
(let [;; Add padding to the bounds
|
||||
{pad-top :p1 pad-right :p2 pad-bottom :p3 pad-left :p4} layout-padding
|
||||
[pad-top pad-right pad-bottom pad-left]
|
||||
(if (= layout-padding-type :multiple)
|
||||
[pad-top pad-right pad-bottom pad-left]
|
||||
[pad-top pad-top pad-top pad-top])]
|
||||
(gpo/pad-points (:points shape) pad-top pad-right pad-bottom pad-left)))
|
||||
(gpo/pad-points shape-bounds pad-top pad-right pad-bottom pad-left)))
|
||||
|
||||
(defn init-layout-lines
|
||||
"Calculates the lines basic data and accumulated values. The positions will be calculated in a different operation"
|
||||
|
@ -43,18 +42,17 @@
|
|||
|
||||
(loop [line-data nil
|
||||
result []
|
||||
child (first children)
|
||||
children (rest children)]
|
||||
children (seq children)]
|
||||
|
||||
(if (nil? child)
|
||||
(if (empty? children)
|
||||
(cond-> result (some? line-data) (conj line-data))
|
||||
|
||||
(let [{:keys [line-min-width line-min-height
|
||||
(let [[child-bounds child] (first children)
|
||||
{:keys [line-min-width line-min-height
|
||||
line-max-width line-max-height
|
||||
num-children
|
||||
children-data]} line-data
|
||||
|
||||
child-bounds (gst/parent-coords-points child shape)
|
||||
child-width (gpo/width-points child-bounds)
|
||||
child-height (gpo/height-points child-bounds)
|
||||
child-min-width (ctl/child-min-width child)
|
||||
|
@ -98,7 +96,6 @@
|
|||
:num-children (inc num-children)
|
||||
:children-data (conjv children-data child-data)}
|
||||
result
|
||||
(first children)
|
||||
(rest children))
|
||||
|
||||
(recur {:line-min-width next-min-width
|
||||
|
@ -108,7 +105,6 @@
|
|||
:num-children 1
|
||||
:children-data [child-data]}
|
||||
(cond-> result (some? line-data) (conj line-data))
|
||||
(first children)
|
||||
(rest children))))))))
|
||||
|
||||
(defn add-space-to-items
|
||||
|
@ -300,9 +296,9 @@
|
|||
|
||||
(defn calc-layout-data
|
||||
"Digest the layout data to pass it to the constrains"
|
||||
[shape children]
|
||||
[shape children shape-bounds]
|
||||
|
||||
(let [layout-bounds (layout-bounds shape)
|
||||
(let [layout-bounds (layout-bounds shape shape-bounds)
|
||||
reverse? (ctl/reverse? shape)
|
||||
children (cond->> children (not reverse?) reverse)
|
||||
|
||||
|
@ -310,10 +306,10 @@
|
|||
layout-lines
|
||||
(->> (init-layout-lines shape children layout-bounds)
|
||||
(add-lines-positions shape layout-bounds)
|
||||
(into []
|
||||
(comp (map (partial add-line-spacing shape layout-bounds))
|
||||
(map (partial add-children-resizes shape)))))]
|
||||
(into [] (comp (map (partial add-line-spacing shape layout-bounds))
|
||||
(map (partial add-children-resizes shape)))))]
|
||||
|
||||
{:layout-lines layout-lines
|
||||
:layout-bounds layout-bounds
|
||||
:reverse? reverse?}))
|
||||
|
||||
|
|
|
@ -6,27 +6,43 @@
|
|||
|
||||
(ns app.common.geom.shapes.flex-layout.modifiers
|
||||
(:require
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.flex-layout.positions :as fpo]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.geom.shapes.transforms :as gst]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.shape.layout :as ctl]))
|
||||
|
||||
(defn normalize-child-modifiers
|
||||
"Apply the modifiers and then normalized them against the parent coordinates"
|
||||
[modifiers parent child {:keys [transform transform-inverse] :as transformed-parent}]
|
||||
[modifiers {:keys [transform transform-inverse] :as parent} child transformed-parent-bounds]
|
||||
|
||||
(let [child-bounds (:points child)
|
||||
parent-bounds (:points parent)
|
||||
|
||||
transformed-child-bounds (gtr/transform-bounds child-bounds modifiers)
|
||||
|
||||
child-bb-before (gpo/parent-coords-bounds child-bounds parent-bounds)
|
||||
child-bb-after (gpo/parent-coords-bounds transformed-child-bounds transformed-parent-bounds)
|
||||
|
||||
scale-x (/ (gpo/width-points child-bb-before) (gpo/width-points child-bb-after))
|
||||
scale-y (/ (gpo/height-points child-bb-before) (gpo/height-points child-bb-after))
|
||||
|
||||
resize-vector (gpt/point scale-x scale-y)
|
||||
modif-transform (ctm/modifiers->transform modifiers)
|
||||
modif-transform-inverse (gmt/inverse modif-transform)
|
||||
resize-transform (gmt/multiply modif-transform transform)
|
||||
resize-transform-inverse (gmt/multiply transform-inverse modif-transform-inverse)
|
||||
resize-origin (gpo/origin transformed-child-bounds)]
|
||||
|
||||
(let [transformed-child (gst/transform-shape child modifiers)
|
||||
child-bb-before (gst/parent-coords-rect child parent)
|
||||
child-bb-after (gst/parent-coords-rect transformed-child transformed-parent)
|
||||
scale-x (/ (:width child-bb-before) (:width child-bb-after))
|
||||
scale-y (/ (:height child-bb-before) (:height child-bb-after))
|
||||
resize-origin (-> transformed-parent :points gpo/origin)
|
||||
resize-vector (gpt/point scale-x scale-y)]
|
||||
(-> modifiers
|
||||
(ctm/select-child-modifiers)
|
||||
(ctm/resize resize-vector resize-origin transform transform-inverse))))
|
||||
(ctm/resize
|
||||
resize-vector
|
||||
resize-origin
|
||||
resize-transform
|
||||
resize-transform-inverse))))
|
||||
|
||||
(defn calc-fill-width-data
|
||||
"Calculates the size and modifiers for the width of an auto-fill child"
|
||||
|
@ -74,10 +90,8 @@
|
|||
|
||||
(defn layout-child-modifiers
|
||||
"Calculates the modifiers for the layout"
|
||||
[parent child layout-line]
|
||||
(let [child-bounds (gst/parent-coords-points child parent)
|
||||
|
||||
child-origin (gpo/origin child-bounds)
|
||||
[parent child child-bounds layout-line]
|
||||
(let [child-origin (gpo/origin child-bounds)
|
||||
child-width (gpo/width-points child-bounds)
|
||||
child-height (gpo/height-points child-bounds)
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@
|
|||
"Calculates the position for the current shape given the layout-data context"
|
||||
[parent child
|
||||
child-width child-height
|
||||
{:keys [start-p layout-gap-row layout-gap-col margin-x margin-y line-height line-width] :as layout-data}]
|
||||
{:keys [start-p layout-gap-row layout-gap-col margin-x margin-y line-height line-width layout-bounds] :as layout-data}]
|
||||
|
||||
(let [row? (ctl/row? parent)
|
||||
col? (ctl/col? parent)
|
||||
|
@ -193,9 +193,8 @@
|
|||
|
||||
[margin-top margin-right margin-bottom margin-left] (ctl/child-margins child)
|
||||
|
||||
points (:points parent)
|
||||
hv (partial gpo/start-hv points)
|
||||
vv (partial gpo/start-vv points)
|
||||
hv (partial gpo/start-hv layout-bounds)
|
||||
vv (partial gpo/start-vv layout-bounds)
|
||||
|
||||
corner-p
|
||||
(cond-> start-p
|
||||
|
@ -247,13 +246,13 @@
|
|||
(gpt/add (vv margin-y)))
|
||||
|
||||
;; Fix position when layout is flipped
|
||||
corner-p
|
||||
(cond-> corner-p
|
||||
(:flip-x parent)
|
||||
(gpt/add (hv child-width))
|
||||
|
||||
(:flip-y parent)
|
||||
(gpt/add (vv child-height)))
|
||||
;;corner-p
|
||||
;;(cond-> corner-p
|
||||
;; (:flip-x parent)
|
||||
;; (gpt/add (hv child-width))
|
||||
;;
|
||||
;; (:flip-y parent)
|
||||
;; (gpt/add (vv child-height)))
|
||||
|
||||
next-p
|
||||
(cond-> start-p
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
[app.common.geom.shapes.constraints :as gct]
|
||||
[app.common.geom.shapes.flex-layout :as gcl]
|
||||
[app.common.geom.shapes.pixel-precision :as gpp]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
|
@ -91,12 +92,12 @@
|
|||
|
||||
(defn- set-children-modifiers
|
||||
"Propagates the modifiers from a parent too its children applying constraints if necesary"
|
||||
[modif-tree objects parent transformed-parent ignore-constraints]
|
||||
[modif-tree objects parent transformed-parent-bounds ignore-constraints]
|
||||
(let [children (:shapes parent)
|
||||
modifiers (dm/get-in modif-tree [(:id parent) :modifiers])]
|
||||
|
||||
;; Move modifiers don't need to calculate constraints
|
||||
(if (ctm/only-move? modifiers)
|
||||
;; Move modifiers don't need to calculate constraints
|
||||
(loop [modif-tree modif-tree
|
||||
children (seq children)]
|
||||
(if-let [current (first children)]
|
||||
|
@ -105,49 +106,65 @@
|
|||
modif-tree))
|
||||
|
||||
;; Check the constraints, then resize
|
||||
(let [parent (gtr/transform-shape parent (ctm/select-parent-modifiers modifiers))]
|
||||
(let [parent-bounds (gtr/transform-bounds (:points parent) (ctm/select-parent-modifiers modifiers))]
|
||||
(loop [modif-tree modif-tree
|
||||
children (seq children)]
|
||||
(if-let [current (first children)]
|
||||
(let [child-modifiers (gct/calc-child-modifiers parent (get objects current) modifiers ignore-constraints transformed-parent)]
|
||||
(if (empty? children)
|
||||
modif-tree
|
||||
(let [child-id (first children)
|
||||
child (get objects child-id)
|
||||
child-modifiers (gct/calc-child-modifiers parent child modifiers ignore-constraints parent-bounds @transformed-parent-bounds)]
|
||||
(recur (cond-> modif-tree
|
||||
(not (ctm/empty? child-modifiers))
|
||||
(update-in [current :modifiers] ctm/add-modifiers child-modifiers))
|
||||
(rest children)))
|
||||
modif-tree))))))
|
||||
(update-in [child-id :modifiers] ctm/add-modifiers child-modifiers))
|
||||
(rest children)))))))))
|
||||
|
||||
(defn- process-layout-children
|
||||
[modif-tree objects parent transformed-parent]
|
||||
[modif-tree objects parent transformed-parent-bounds]
|
||||
(letfn [(process-child [modif-tree child]
|
||||
(let [modifiers (dm/get-in modif-tree [(:id parent) :modifiers])
|
||||
child-modifiers (-> modifiers
|
||||
(ctm/select-child-geometry-modifiers)
|
||||
(gcl/normalize-child-modifiers parent child transformed-parent))]
|
||||
(gcl/normalize-child-modifiers parent child @transformed-parent-bounds))]
|
||||
(cond-> modif-tree
|
||||
(not (ctm/empty? child-modifiers))
|
||||
(update-in [(:id child) :modifiers] ctm/add-modifiers child-modifiers))))]
|
||||
(let [children (map (d/getf objects) (:shapes transformed-parent))]
|
||||
(let [children (map (d/getf objects) (:shapes parent))]
|
||||
(reduce process-child modif-tree children))))
|
||||
|
||||
|
||||
(defn get-bounds
|
||||
[objects modif-tree shape]
|
||||
|
||||
(let [modifiers (-> (dm/get-in modif-tree [(:id shape) :modifiers])
|
||||
(ctm/select-geometry))
|
||||
|
||||
children (cph/get-immediate-children objects (:id shape))
|
||||
bounds (cond
|
||||
(cph/group-shape? shape)
|
||||
(let [children-bounds (->> children (mapv (partial get-bounds objects modif-tree)))]
|
||||
(gtr/group-bounds shape children-bounds))
|
||||
|
||||
(cph/mask-shape? shape)
|
||||
(get-bounds objects modif-tree (-> children first))
|
||||
|
||||
:else
|
||||
(:points shape))]
|
||||
|
||||
(gtr/transform-bounds bounds modifiers)))
|
||||
|
||||
|
||||
(defn- set-layout-modifiers
|
||||
[modif-tree objects parent]
|
||||
[modif-tree objects parent transformed-parent-bounds]
|
||||
|
||||
(letfn [(apply-modifiers [modif-tree child]
|
||||
(let [modifiers (-> (dm/get-in modif-tree [(:id child) :modifiers])
|
||||
(ctm/select-geometry))]
|
||||
(cond
|
||||
(cph/group-like-shape? child)
|
||||
(gtr/apply-group-modifiers child objects modif-tree)
|
||||
(letfn [(apply-modifiers [child]
|
||||
[(-> (get-bounds objects modif-tree child)
|
||||
(gpo/parent-coords-bounds @transformed-parent-bounds))
|
||||
child])
|
||||
|
||||
(some? modifiers)
|
||||
(gtr/transform-shape child modifiers)
|
||||
|
||||
:else
|
||||
child)))
|
||||
|
||||
(set-child-modifiers [parent [layout-line modif-tree] child]
|
||||
(set-child-modifiers [[layout-line modif-tree] [child-bounds child]]
|
||||
(let [[modifiers layout-line]
|
||||
(gcl/layout-child-modifiers parent child layout-line)
|
||||
(gcl/layout-child-modifiers parent child child-bounds layout-line)
|
||||
|
||||
modif-tree
|
||||
(cond-> modif-tree
|
||||
|
@ -156,13 +173,12 @@
|
|||
|
||||
[layout-line modif-tree]))]
|
||||
|
||||
(let [children (map (d/getf objects) (:shapes parent))
|
||||
children (->> children (map (partial apply-modifiers modif-tree)))
|
||||
layout-data (gcl/calc-layout-data parent children)
|
||||
(let [children (->> (:shapes parent)
|
||||
(map (comp apply-modifiers (d/getf objects))))
|
||||
layout-data (gcl/calc-layout-data parent children @transformed-parent-bounds)
|
||||
children (into [] (cond-> children (not (:reverse? layout-data)) reverse))
|
||||
max-idx (dec (count children))
|
||||
layout-lines (:layout-lines layout-data)]
|
||||
|
||||
(loop [modif-tree modif-tree
|
||||
layout-line (first layout-lines)
|
||||
pending (rest layout-lines)
|
||||
|
@ -172,7 +188,7 @@
|
|||
children (subvec children from-idx to-idx)
|
||||
|
||||
[_ modif-tree]
|
||||
(reduce (partial set-child-modifiers parent) [layout-line modif-tree] children)]
|
||||
(reduce set-child-modifiers [layout-line modif-tree] children)]
|
||||
(recur modif-tree (first pending) (rest pending) to-idx))
|
||||
|
||||
modif-tree)))))
|
||||
|
@ -195,11 +211,9 @@
|
|||
(ctm/resize-parent (gpt/point 1 scale-height) origin (:transform parent) (:transform-inverse parent)))))]
|
||||
|
||||
(let [children (->> parent :shapes (map (d/getf objects)))
|
||||
|
||||
{auto-width :width auto-height :height}
|
||||
(when (and (d/not-empty? children) (or (ctl/auto-height? parent) (ctl/auto-width? parent)))
|
||||
(gcl/layout-content-bounds parent children))]
|
||||
|
||||
(cond-> (ctm/empty)
|
||||
(and (some? auto-width) (ctl/auto-width? parent))
|
||||
(set-parent-auto-width auto-width)
|
||||
|
@ -214,11 +228,12 @@
|
|||
root? (= uuid/zero parent-id)
|
||||
modifiers (-> (dm/get-in modif-tree [parent-id :modifiers])
|
||||
(ctm/select-geometry))
|
||||
transformed-parent (gtr/transform-shape parent modifiers)
|
||||
|
||||
transformed-parent-bounds (delay (gtr/transform-bounds (:points parent) modifiers))
|
||||
|
||||
has-modifiers? (ctm/child-modifiers? modifiers)
|
||||
layout? (ctl/layout? parent)
|
||||
auto? (or (ctl/auto-height? transformed-parent) (ctl/auto-width? transformed-parent))
|
||||
auto? (or (ctl/auto-height? parent) (ctl/auto-width? parent))
|
||||
parent? (or (cph/group-like-shape? parent) (cph/frame-shape? parent))
|
||||
|
||||
;; If the current child is inside the layout we ignore the constraints
|
||||
|
@ -226,11 +241,11 @@
|
|||
|
||||
[(cond-> modif-tree
|
||||
(and (not layout?) has-modifiers? parent? (not root?))
|
||||
(set-children-modifiers objects parent transformed-parent (or ignore-constraints inside-layout?))
|
||||
(set-children-modifiers objects parent transformed-parent-bounds (or ignore-constraints inside-layout?))
|
||||
|
||||
layout?
|
||||
(-> (process-layout-children objects parent transformed-parent)
|
||||
(set-layout-modifiers objects transformed-parent)))
|
||||
(-> (process-layout-children objects parent transformed-parent-bounds)
|
||||
(set-layout-modifiers objects parent transformed-parent-bounds)))
|
||||
|
||||
;; Auto-width/height can change the positions in the parent so we need to recalculate
|
||||
(cond-> autolayouts auto? (conj (:id parent)))]))
|
||||
|
@ -247,21 +262,21 @@
|
|||
[objects tree-seq modif-tree]
|
||||
|
||||
(letfn [(apply-shape [objects {:keys [id] :as shape}]
|
||||
(if (cph/group-shape? shape)
|
||||
(let [children (cph/get-children objects id)]
|
||||
(assoc objects id
|
||||
(cond
|
||||
(cph/mask-shape? shape)
|
||||
(gtr/update-mask-selrect shape children)
|
||||
(let [modifiers (get-in modif-tree [id :modifiers])
|
||||
object
|
||||
(cond
|
||||
(cph/mask-shape? shape)
|
||||
(gtr/update-mask-selrect shape (cph/get-children objects id))
|
||||
|
||||
:else
|
||||
(gtr/update-group-selrect shape children))))
|
||||
(cph/group-shape? shape)
|
||||
(gtr/update-group-selrect shape (cph/get-children objects id))
|
||||
|
||||
(let [modifiers (get-in modif-tree [id :modifiers])
|
||||
object (cond-> shape
|
||||
(some? modifiers)
|
||||
(gtr/transform-shape modifiers))]
|
||||
(assoc objects id object))))]
|
||||
(some? modifiers)
|
||||
(gtr/transform-shape shape modifiers)
|
||||
|
||||
:else
|
||||
shape)]
|
||||
(assoc objects id object)))]
|
||||
|
||||
(reduce apply-shape objects (reverse tree-seq))))
|
||||
|
||||
|
|
|
@ -9,15 +9,15 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.geom.shapes.rect :as gpr]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.modifiers :as ctm]))
|
||||
|
||||
(defn size-pixel-precision
|
||||
[modifiers {:keys [points transform transform-inverse] :as shape}]
|
||||
[modifiers {:keys [transform transform-inverse] :as shape} points]
|
||||
(let [origin (gpo/origin points)
|
||||
curr-width (gpo/width-points points)
|
||||
curr-height (gpo/height-points points)
|
||||
|
@ -36,7 +36,7 @@
|
|||
(ctm/resize scalev origin transform transform-inverse))))
|
||||
|
||||
(defn position-pixel-precision
|
||||
[modifiers {:keys [points]}]
|
||||
[modifiers _ points]
|
||||
(let [bounds (gpr/points->rect points)
|
||||
corner (gpt/point bounds)
|
||||
target-corner (gpt/round corner)
|
||||
|
@ -47,24 +47,28 @@
|
|||
(defn set-pixel-precision
|
||||
"Adjust modifiers so they adjust to the pixel grid"
|
||||
[modifiers shape]
|
||||
(let [move? (ctm/only-move? modifiers)]
|
||||
(cond-> modifiers
|
||||
(not move?)
|
||||
(size-pixel-precision shape)
|
||||
(let [points (-> shape :points (gco/transform-points (ctm/modifiers->transform modifiers)))
|
||||
has-resize? (not (ctm/only-move? modifiers))
|
||||
|
||||
:always
|
||||
(position-pixel-precision shape))))
|
||||
[modifiers points]
|
||||
(let [modifiers
|
||||
(cond-> modifiers
|
||||
has-resize? (size-pixel-precision shape points))
|
||||
|
||||
points
|
||||
(cond-> (:points shape)
|
||||
has-resize? (gco/transform-points (ctm/modifiers->transform modifiers)))]
|
||||
[modifiers points])]
|
||||
(position-pixel-precision modifiers shape points)))
|
||||
|
||||
(defn adjust-pixel-precision
|
||||
[modif-tree objects]
|
||||
(let [update-modifiers
|
||||
(fn [modif-tree shape]
|
||||
(let [modifiers (dm/get-in modif-tree [(:id shape) :modifiers])]
|
||||
(if-not (ctm/has-geometry? modifiers)
|
||||
modif-tree
|
||||
(let [shape (gtr/transform-shape shape modifiers)]
|
||||
(-> modif-tree
|
||||
(update-in [(:id shape) :modifiers] set-pixel-precision shape))))))]
|
||||
(cond-> modif-tree
|
||||
(ctm/has-geometry? modifiers)
|
||||
(update-in [(:id shape) :modifiers] set-pixel-precision shape))))]
|
||||
|
||||
(->> (keys modif-tree)
|
||||
(map (d/getf objects))
|
||||
|
|
|
@ -6,12 +6,21 @@
|
|||
|
||||
(ns app.common.geom.shapes.points
|
||||
(:require
|
||||
[app.common.geom.point :as gpt]))
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.intersect :as gsi]))
|
||||
|
||||
(defn origin
|
||||
[points]
|
||||
(nth points 0))
|
||||
|
||||
(defn hv
|
||||
[[p0 p1 _ _]]
|
||||
(gpt/to-vec p0 p1))
|
||||
|
||||
(defn vv
|
||||
[[p0 _ _ p3]]
|
||||
(gpt/to-vec p0 p3))
|
||||
|
||||
(defn start-hv
|
||||
"Horizontal vector from the origin with a magnitude `val`"
|
||||
[[p0 p1 _ _] val]
|
||||
|
@ -60,3 +69,46 @@
|
|||
(-> p1 (gpt/add right-v) (gpt/add top-v))
|
||||
(-> p2 (gpt/add right-v) (gpt/add bottom-v))
|
||||
(-> p3 (gpt/add left-v) (gpt/add bottom-v))])))
|
||||
|
||||
|
||||
|
||||
#_(defn parent-coords-rect
|
||||
[child-bounds parent-bounds]
|
||||
#_(-> child-bounds
|
||||
(gco/transform-points (:transform-inverse parent))
|
||||
(gpr/points->rect)))
|
||||
|
||||
(defn closest-first
|
||||
"Reorders the points so the closest to the line start-end is the first"
|
||||
[[a b c d] start end]
|
||||
|
||||
(let [da (gpt/point-line-distance a start end)
|
||||
db (gpt/point-line-distance b start end)
|
||||
dc (gpt/point-line-distance c start end)
|
||||
dd (gpt/point-line-distance d start end)]
|
||||
|
||||
(cond
|
||||
(and (<= da db) (<= da dc) (<= da dd))
|
||||
[a b c d]
|
||||
|
||||
(and (<= db da) (<= db dc) (<= db dd))
|
||||
[b c d a]
|
||||
|
||||
(and (<= dc da) (<= dc db) (<= dc dd))
|
||||
[c d a b]
|
||||
|
||||
:else
|
||||
[d a b c])))
|
||||
|
||||
(defn parent-coords-bounds
|
||||
[bounds [p1 p2 _ p4]]
|
||||
|
||||
(let [[b1 b2 b3 b4] (closest-first bounds p1 p2)
|
||||
hv (gpt/to-vec p1 p2)
|
||||
vv (gpt/to-vec p1 p4)
|
||||
|
||||
i1 (gsi/line-line-intersect b1 (gpt/add hv b1) b4 (gpt/add b4 vv))
|
||||
i2 (gsi/line-line-intersect b1 (gpt/add hv b1) b2 (gpt/add b2 vv))
|
||||
i3 (gsi/line-line-intersect b3 (gpt/add hv b3) b2 (gpt/add b2 vv))
|
||||
i4 (gsi/line-line-intersect b3 (gpt/add hv b3) b4 (gpt/add b4 vv))]
|
||||
[i1 i2 i3 i4]))
|
||||
|
|
|
@ -369,6 +369,16 @@
|
|||
(update :width + (:width deltas))
|
||||
(update :height + (:height deltas)))))))
|
||||
|
||||
(defn group-bounds
|
||||
[group children-bounds]
|
||||
(let [shape-center (gco/center-shape group)
|
||||
points (flatten children-bounds)
|
||||
points (if (empty? points) (:points group) points)]
|
||||
(-> points
|
||||
(gco/transform-points shape-center (:transform-inverse group (gmt/matrix)))
|
||||
(gpr/squared-points)
|
||||
(gco/transform-points shape-center (:transform group (gmt/matrix))))))
|
||||
|
||||
(defn update-group-selrect
|
||||
[group children]
|
||||
(let [shape-center (gco/center-shape group)
|
||||
|
@ -541,19 +551,3 @@
|
|||
|
||||
:else
|
||||
group))))
|
||||
|
||||
(defn parent-coords-rect
|
||||
[child parent]
|
||||
(-> child
|
||||
:points
|
||||
(gco/transform-points (:transform-inverse parent))
|
||||
(gpr/points->rect)))
|
||||
|
||||
(defn parent-coords-points
|
||||
[child parent]
|
||||
(-> child
|
||||
:points
|
||||
(gco/transform-points (:transform-inverse parent))
|
||||
(gpr/points->rect)
|
||||
(gpr/rect->points)
|
||||
(gco/transform-points (:transform parent))))
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(:refer-clojure :exclude [empty empty?])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
|
@ -50,7 +51,6 @@
|
|||
(or (not (mth/almost-zero? (- (:x vector) 1)))
|
||||
(not (mth/almost-zero? (- (:y vector) 1)))))
|
||||
|
||||
|
||||
(defn- mergeable-move?
|
||||
[op1 op2]
|
||||
(and (= :move (:type op1))
|
||||
|
@ -106,6 +106,13 @@
|
|||
(conj item)))
|
||||
(conj operations op)))))
|
||||
|
||||
(defn valid-vector?
|
||||
[{:keys [x y]}]
|
||||
(and (some? x)
|
||||
(some? y)
|
||||
(not (mth/nan? x))
|
||||
(not (mth/nan? y))))
|
||||
|
||||
;; Public builder API
|
||||
|
||||
(defn empty []
|
||||
|
@ -116,12 +123,14 @@
|
|||
(move-parent modifiers (gpt/point x y)))
|
||||
|
||||
([modifiers vector]
|
||||
(assert (valid-vector? vector) (dm/str "Invalid move vector: " (:x vector) "," (:y vector)))
|
||||
(cond-> modifiers
|
||||
(move-vec? vector)
|
||||
(update :geometry-parent conjv {:type :move :vector vector}))))
|
||||
(update :geometry-parent maybe-add-move {:type :move :vector vector}))))
|
||||
|
||||
(defn resize-parent
|
||||
([modifiers vector origin]
|
||||
(assert (valid-vector? vector) (dm/str "Invalid move vector: " (:x vector) "," (:y vector)))
|
||||
(cond-> modifiers
|
||||
(resize-vec? vector)
|
||||
(update :geometry-parent maybe-add-resize {:type :resize
|
||||
|
@ -129,6 +138,7 @@
|
|||
:origin origin})))
|
||||
|
||||
([modifiers vector origin transform transform-inverse]
|
||||
(assert (valid-vector? vector) (dm/str "Invalid move vector: " (:x vector) "," (:y vector)))
|
||||
(cond-> modifiers
|
||||
(resize-vec? vector)
|
||||
(update :geometry-parent maybe-add-resize {:type :resize
|
||||
|
@ -141,12 +151,14 @@
|
|||
(move modifiers (gpt/point x y)))
|
||||
|
||||
([modifiers vector]
|
||||
(assert (valid-vector? vector) (dm/str "Invalid move vector: " (:x vector) "," (:y vector)))
|
||||
(cond-> modifiers
|
||||
(move-vec? vector)
|
||||
(update :geometry-child maybe-add-move {:type :move :vector vector}))))
|
||||
|
||||
(defn resize
|
||||
([modifiers vector origin]
|
||||
(assert (valid-vector? vector) (dm/str "Invalid move vector: " (:x vector) "," (:y vector)))
|
||||
(cond-> modifiers
|
||||
(resize-vec? vector)
|
||||
(update :geometry-child maybe-add-resize {:type :resize
|
||||
|
@ -154,6 +166,7 @@
|
|||
:origin origin})))
|
||||
|
||||
([modifiers vector origin transform transform-inverse]
|
||||
(assert (valid-vector? vector) (dm/str "Invalid move vector: " (:x vector) "," (:y vector)))
|
||||
(cond-> modifiers
|
||||
(resize-vec? vector)
|
||||
(update :geometry-child maybe-add-resize {:type :resize
|
||||
|
@ -355,8 +368,9 @@
|
|||
(defn only-move?
|
||||
"Returns true if there are only move operations"
|
||||
[{:keys [geometry-child geometry-parent]}]
|
||||
(and (every? #(= :move (:type %)) geometry-child)
|
||||
(every? #(= :move (:type %)) geometry-parent)))
|
||||
(let [move-op? #(= :move (:type %))]
|
||||
(and (every? move-op? geometry-child)
|
||||
(every? move-op? geometry-parent))))
|
||||
|
||||
(defn has-geometry?
|
||||
[{:keys [geometry-parent geometry-child]}]
|
||||
|
@ -418,16 +432,19 @@
|
|||
(gmt/multiply (gmt/translate-matrix vector) matrix)
|
||||
|
||||
:resize
|
||||
(gmt/multiply
|
||||
(-> (gmt/matrix)
|
||||
(gmt/translate origin)
|
||||
(cond-> (some? transform)
|
||||
(gmt/multiply transform))
|
||||
(gmt/scale vector)
|
||||
(cond-> (some? transform-inverse)
|
||||
(gmt/multiply transform-inverse))
|
||||
(gmt/translate (gpt/negate origin)))
|
||||
matrix)
|
||||
(let [origin (cond-> origin
|
||||
(or (some? transform-inverse)(some? transform))
|
||||
(gpt/transform transform-inverse))]
|
||||
(gmt/multiply
|
||||
(-> (gmt/matrix)
|
||||
(cond-> (some? transform)
|
||||
(gmt/multiply transform))
|
||||
(gmt/translate origin)
|
||||
(gmt/scale vector)
|
||||
(gmt/translate (gpt/negate origin))
|
||||
(cond-> (some? transform-inverse)
|
||||
(gmt/multiply transform-inverse)))
|
||||
matrix))
|
||||
|
||||
:rotation
|
||||
(gmt/multiply
|
||||
|
|
|
@ -12,9 +12,8 @@
|
|||
[app.common.files.features :as ffeat]
|
||||
[app.common.geom.align :as gal]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.proportions :as gpr]
|
||||
[app.common.geom.proportions :as gpp]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.rect :as gpsr]
|
||||
[app.common.logging :as log]
|
||||
[app.common.pages.changes-builder :as pcb]
|
||||
[app.common.pages.helpers :as cph]
|
||||
|
@ -937,7 +936,7 @@
|
|||
(if-not lock
|
||||
(assoc shape :proportion-lock false)
|
||||
(-> (assoc shape :proportion-lock true)
|
||||
(gpr/assign-proportions))))]
|
||||
(gpp/assign-proportions))))]
|
||||
(rx/of (dch/update-shapes [id] assign-proportions))))))
|
||||
|
||||
(defn toggle-proportion-lock
|
||||
|
@ -1776,10 +1775,10 @@
|
|||
media (vals (:media file-data'))
|
||||
|
||||
media-points
|
||||
(map #(assoc % :points (gpsr/rect->points {:x 0
|
||||
:y 0
|
||||
:width (:width %)
|
||||
:height (:height %)}))
|
||||
(map #(assoc % :points (gsh/rect->points {:x 0
|
||||
:y 0
|
||||
:width (:width %)
|
||||
:height (:height %)}))
|
||||
media)
|
||||
|
||||
shape-grid
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.proportions :as gpr]
|
||||
[app.common.geom.proportions :as gpp]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.changes-builder :as pcb]
|
||||
[app.common.pages.helpers :as cph]
|
||||
|
@ -69,7 +69,7 @@
|
|||
(get-shape-layer-position objects selected-non-frames attrs)]
|
||||
|
||||
(-> (merge default-attrs attrs)
|
||||
(gpr/setup-proportions)
|
||||
(gpp/setup-proportions)
|
||||
(assoc :frame-id frame-id
|
||||
:parent-id parent-id
|
||||
:index index))))
|
||||
|
|
|
@ -146,8 +146,8 @@
|
|||
(fn [id]
|
||||
(let [new-shape (get text-shapes id)
|
||||
old-shape (get prev-text-shapes id)
|
||||
old-modifiers (get prev-modifiers id)
|
||||
new-modifiers (get modifiers id)
|
||||
old-modifiers (ctm/select-geometry (get prev-modifiers id))
|
||||
new-modifiers (ctm/select-geometry (get modifiers id))
|
||||
|
||||
remote? (some? (-> new-shape meta :session-id)) ]
|
||||
|
||||
|
@ -155,10 +155,9 @@
|
|||
(not (identical? old-shape new-shape))
|
||||
(not= (dissoc old-shape :migrate)
|
||||
(dissoc new-shape :migrate)))
|
||||
|
||||
(and (not= new-modifiers old-modifiers)
|
||||
(or (nil? new-modifiers)
|
||||
(nil? old-modifiers)
|
||||
(not (ctm/only-move? new-modifiers))
|
||||
(or (not (ctm/only-move? new-modifiers))
|
||||
(not (ctm/only-move? old-modifiers))))
|
||||
|
||||
;; When the position data is nil we force to recalculate
|
||||
|
|
|
@ -429,6 +429,12 @@
|
|||
:hover-top-frame-id @hover-top-frame-id
|
||||
:zoom zoom}])
|
||||
|
||||
(when (debug? :parent-bounds)
|
||||
[:& wvd/debug-parent-bounds {:selected-shapes selected-shapes
|
||||
:objects objects-modified
|
||||
:hover-top-frame-id @hover-top-frame-id
|
||||
:zoom zoom}])
|
||||
|
||||
(when show-selection-handlers?
|
||||
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}
|
||||
[:defs
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.uuid :as uuid]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
@ -76,7 +77,7 @@
|
|||
col? (ctl/col? shape)
|
||||
|
||||
children (cph/get-immediate-children objects (:id shape))
|
||||
layout-data (gsl/calc-layout-data shape children)
|
||||
layout-data (gsl/calc-layout-data shape children (:points shape))
|
||||
|
||||
layout-bounds (:layout-bounds layout-data)
|
||||
xv #(gpo/start-hv layout-bounds %)
|
||||
|
@ -112,8 +113,9 @@
|
|||
shape (or selected-frame (get objects hover-top-frame-id))]
|
||||
|
||||
(when (and shape (:layout shape))
|
||||
(let [children (cph/get-immediate-children objects (:id shape))
|
||||
layout-data (gsl/calc-layout-data shape children)
|
||||
(let [children (->> (cph/get-immediate-children objects (:id shape))
|
||||
(map #(vector (gpo/parent-coords-bounds (:points %) (:points shape)) %)))
|
||||
layout-data (gsl/calc-layout-data shape children (:points shape))
|
||||
drop-areas (gsl/layout-drop-areas shape layout-data children)]
|
||||
[:g.debug-layout {:pointer-events "none"
|
||||
:transform (gsh/transform-str shape)}
|
||||
|
@ -135,3 +137,51 @@
|
|||
:alignment-baseline "hanging"
|
||||
:fill "black"}
|
||||
(:index drop-area)]])]))))
|
||||
|
||||
(mf/defc shape-parent-bound
|
||||
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape" "parent"]))]
|
||||
::mf/wrap-props false}
|
||||
[props]
|
||||
|
||||
(let [shape (unchecked-get props "shape")
|
||||
parent (unchecked-get props "parent")
|
||||
zoom (unchecked-get props "zoom")
|
||||
[i1 i2 i3 i4] (gpo/parent-coords-bounds (:points shape) (:points parent))]
|
||||
[:*
|
||||
[:polygon {:points (->> [i1 i2 i3 i4] (map #(dm/fmt "%,%" (:x %) (:y %))) (str/join ","))
|
||||
:style {:fill "none" :stroke "red" :stroke-width (/ 1 zoom)}}]
|
||||
|
||||
[:line {:x1 (:x i1)
|
||||
:y1 (:y i1)
|
||||
:x2 (:x i2)
|
||||
:y2 (:y i2)
|
||||
:style {:stroke "green" :stroke-width (/ 1 zoom)}}]
|
||||
[:line {:x1 (:x i1)
|
||||
:y1 (:y i1)
|
||||
:x2 (:x i4)
|
||||
:y2 (:y i4)
|
||||
:style {:stroke "blue" :stroke-width (/ 1 zoom)}}]]))
|
||||
|
||||
(mf/defc debug-parent-bounds
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
||||
(let [objects (unchecked-get props "objects")
|
||||
zoom (unchecked-get props "objects")
|
||||
selected-shapes (unchecked-get props "selected-shapes")
|
||||
hover-top-frame-id (unchecked-get props "hover-top-frame-id")
|
||||
|
||||
selected-frame
|
||||
(when (and (= (count selected-shapes) 1) (= :frame (-> selected-shapes first :type)))
|
||||
(first selected-shapes))
|
||||
|
||||
parent (or selected-frame (get objects hover-top-frame-id))]
|
||||
|
||||
(when (and (some? parent) (not= uuid/zero (:id parent)))
|
||||
(let [children (cph/get-immediate-children objects (:id parent))]
|
||||
[:g.debug-parent-bounds {:pointer-events "none"}
|
||||
(for [[idx child] (d/enumerate children)]
|
||||
[:> shape-parent-bound {:key (dm/str "bound-" idx)
|
||||
:zoom zoom
|
||||
:shape child
|
||||
:parent parent}])]))))
|
||||
|
|
|
@ -76,6 +76,9 @@
|
|||
|
||||
;; Makes the pixel grid red so its more visibile
|
||||
:pixel-grid
|
||||
|
||||
;; Show the bounds relative to the parent
|
||||
:parent-bounds
|
||||
})
|
||||
|
||||
;; These events are excluded when we activate the :events flag
|
||||
|
|
Loading…
Add table
Reference in a new issue