Refactor frames

This commit is contained in:
alonso.torres 2022-10-04 18:12:08 +02:00
parent 8d9ed4f8af
commit bc890a0b33
7 changed files with 716 additions and 52 deletions

View file

@ -177,6 +177,8 @@
(dm/export gtr/move-position-data) (dm/export gtr/move-position-data)
(dm/export gtr/apply-transform) (dm/export gtr/apply-transform)
(dm/export gtr/apply-objects-modifiers) (dm/export gtr/apply-objects-modifiers)
(dm/export gtr/parent-coords-rect)
(dm/export gtr/parent-coords-points)
;; Constratins ;; Constratins
(dm/export gct/calc-child-modifiers) (dm/export gct/calc-child-modifiers)
@ -210,3 +212,4 @@
;; Modifiers ;; Modifiers
(dm/export gsm/set-objects-modifiers) (dm/export gsm/set-objects-modifiers)

View file

@ -261,18 +261,8 @@
"Before aplying constraints we need to remove the deformation caused by the resizing of the parent" "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 transformed-parent] [constraints-h constraints-v modifiers child parent transformed-child transformed-parent]
(let [child-bb-before (let [child-bb-before (gst/parent-coords-rect child parent)
(-> child child-bb-after (gst/parent-coords-rect transformed-child transformed-parent)
:points
(gco/transform-points (:transform-inverse parent))
(gre/points->rect))
child-bb-after
(-> transformed-child
:points
(gco/transform-points (:transform-inverse transformed-parent))
(gre/points->rect))
scale-x (/ (:width child-bb-before) (:width child-bb-after)) scale-x (/ (:width child-bb-before) (:width child-bb-after))
scale-y (/ (:height child-bb-before) (:height child-bb-after))] scale-y (/ (:height child-bb-before) (:height child-bb-after))]
@ -332,3 +322,5 @@
transformed-parent)] transformed-parent)]
(update modifiers :v2 d/concat-vec modifiers-h modifiers-v))))) (update modifiers :v2 d/concat-vec modifiers-h modifiers-v)))))

View file

@ -120,7 +120,7 @@
(cond-> layout-lines (some? line-data) (conj line-data)))) (cond-> layout-lines (some? line-data) (conj line-data))))
(defn calc-layout-lines-position (defn calc-layout-lines-position
[{:keys [layout-gap layout-type] :as shape} {:keys [x y width height]} layout-lines] [{:keys [layout-gap layout-type] :as shape} {:keys [x y width height] :as layout-bounds} layout-lines]
(letfn [(get-base-line (letfn [(get-base-line
[total-width total-height] [total-width total-height]
@ -414,8 +414,9 @@
(defn calc-layout-modifiers (defn calc-layout-modifiers
"Calculates the modifiers for the layout" "Calculates the modifiers for the layout"
[parent transform child layout-data] [parent child layout-data]
(let [child-bounds (-> child :points gre/points->selrect) (let [transform (:transform parent)
child-bounds (-> child :points gre/points->selrect)
fill-width (calc-fill-width-data child-bounds parent child layout-data) fill-width (calc-fill-width-data child-bounds parent child layout-data)
fill-height (calc-fill-height-data child-bounds parent child layout-data) fill-height (calc-fill-height-data child-bounds parent child layout-data)

View file

@ -0,0 +1,606 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) UXBOX Labs SL
(ns app.common.geom.shapes.layout-new
(:require
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.rect :as gre]
[app.common.geom.shapes.transforms :as gst]
))
;; :layout ;; true if active, false if not
;; :layout-dir ;; :right, :left, :top, :bottom
;; :layout-gap ;; number could be negative
;; :layout-type ;; :packed, :space-between, :space-around
;; :layout-wrap-type ;; :wrap, :no-wrap
;; :layout-padding-type ;; :simple, :multiple
;; :layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative
;; :layout-h-orientation ;; :top, :center, :bottom
;; :layout-v-orientation ;; :left, :center, :right
(defn col?
[{:keys [layout-dir]}]
(or (= :right layout-dir) (= :left layout-dir)))
(defn row?
[{:keys [layout-dir]}]
(or (= :top layout-dir) (= :bottom layout-dir)))
(defn h-start?
[{:keys [layout-h-orientation]}]
(= layout-h-orientation :left))
(defn h-center?
[{:keys [layout-h-orientation]}]
(= layout-h-orientation :center))
(defn h-end?
[{:keys [layout-h-orientation]}]
(= layout-h-orientation :right))
(defn v-start?
[{:keys [layout-v-orientation]}]
(= layout-v-orientation :top))
(defn v-center?
[{:keys [layout-v-orientation]}]
(= layout-v-orientation :center))
(defn v-end?
[{:keys [layout-v-orientation]}]
(= layout-v-orientation :bottom))
(defn add-padding [transformed-rect {:keys [layout-padding-type layout-padding]}]
(let [{:keys [p1 p2 p3 p4]} layout-padding
[p1 p2 p3 p4]
(if (= layout-padding-type :multiple)
[p1 p2 p3 p4]
[p1 p1 p1 p1])]
(-> transformed-rect
(update :y + p1)
(update :width - p2 p3)
(update :x + p3)
(update :height - p1 p4))))
;; FUNCTIONS TO WORK WITH POINTS SQUARES
(defn origin
[points]
(nth points 0))
(defn start-hv
"Horizontal vector from the origin with a magnitude `val`"
[[p0 p1 p2 p3] val]
(-> (gpt/to-vec p0 p1)
(gpt/unit)
(gpt/scale val)))
(defn end-hv
"Horizontal vector from the oposite to the origin in the x axis with a magnitude `val`"
[[p0 p1 p2 p3] val]
(-> (gpt/to-vec p1 p0)
(gpt/unit)
(gpt/scale val)))
(defn start-vv
"Vertical vector from the oposite to the origin in the x axis with a magnitude `val`"
[[p0 p1 p2 p3] val]
(-> (gpt/to-vec p0 p3)
(gpt/unit)
(gpt/scale val)))
(defn end-vv
"Vertical vector from the oposite to the origin in the x axis with a magnitude `val`"
[[p0 p1 p2 p3] val]
(-> (gpt/to-vec p3 p0)
(gpt/unit)
(gpt/scale val)))
;;(defn start-hp
;; [[p0 _ _ _ :as points] val]
;; (gpt/add p0 (start-hv points val)))
;;
;;(defn end-hp
;; "Horizontal Vector from the oposite to the origin in the x axis with a magnitude `val`"
;; [[_ p1 _ _ :as points] val]
;; (gpt/add p1 (end-hv points val)))
;;
;;(defn start-vp
;; "Vertical Vector from the oposite to the origin in the x axis with a magnitude `val`"
;; [[p0 _ _ _ :as points] val]
;; (gpt/add p0 (start-vv points val)))
;;
;;(defn end-vp
;; "Vertical Vector from the oposite to the origin in the x axis with a magnitude `val`"
;; [[_ _ p3 _ :as points] val]
;; (gpt/add p3 (end-vv points val)))
(defn width-points
[[p0 p1 p2 p3]]
(gpt/length (gpt/to-vec p0 p1)))
(defn height-points
[[p0 p1 p2 p3]]
(gpt/length (gpt/to-vec p0 p3)))
(defn pad-points
[[p0 p1 p2 p3 :as points] pad-top pad-right pad-bottom pad-left]
(let [top-v (start-vv points pad-top)
right-v (end-hv points pad-right)
bottom-v (end-vv points pad-bottom)
left-v (start-hv points pad-left)]
[(-> p0 (gpt/add left-v) (gpt/add top-v))
(-> 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 calc-layout-lines
[{:keys [layout-gap layout-wrap-type] :as parent} children layout-bounds]
(let [wrap? (= layout-wrap-type :wrap)
layout-width (width-points layout-bounds)
layout-height (height-points layout-bounds)
reduce-fn
(fn [[{:keys [line-width line-height num-children line-fill? child-fill? num-child-fill] :as line-data} result] child]
(let [child-bounds (gst/parent-coords-points child parent)
child-width (width-points child-bounds)
child-height (height-points child-bounds)
col? (col? parent)
row? (row? parent)
cur-child-fill?
(or (and col? (= :fill (:layout-h-behavior child)))
(and row? (= :fill (:layout-v-behavior child))))
cur-line-fill?
(or (and row? (= :fill (:layout-h-behavior child)))
(and col? (= :fill (:layout-v-behavior child))))
;; TODO LAYOUT: ADD MINWIDTH/HEIGHT
next-width (if (or (and col? cur-child-fill?)
(and row? cur-line-fill?))
0
child-width)
next-height (if (or (and row? cur-child-fill?)
(and col? cur-line-fill?))
0
child-height)
next-total-width (+ line-width next-width (* layout-gap num-children))
next-total-height (+ line-height next-height (* layout-gap num-children))]
(if (and (some? line-data)
(or (not wrap?)
(and col? (<= next-total-width layout-width))
(and row? (<= next-total-height layout-height))))
;; When :fill we add min width (0 by default)
[{:line-width (if col? (+ line-width next-width) (max line-width next-width))
:line-height (if row? (+ line-height next-height) (max line-height next-height))
:num-children (inc num-children)
:child-fill? (or cur-child-fill? child-fill?)
:line-fill? (or cur-line-fill? line-fill?)
:num-child-fill (cond-> num-child-fill cur-child-fill? inc)}
result]
[{:line-width next-width
:line-height next-height
:num-children 1
:child-fill? cur-child-fill?
:line-fill? cur-line-fill?
:num-child-fill (if cur-child-fill? 1 0)}
(cond-> result (some? line-data) (conj line-data))])))
[line-data layout-lines] (reduce reduce-fn [nil []] children)]
(cond-> layout-lines (some? line-data) (conj line-data))))
(defn calc-layout-lines-position
[{:keys [layout-gap layout-type] :as parent} layout-bounds layout-lines]
(let [layout-width (width-points layout-bounds)
layout-height (height-points layout-bounds)
row? (row? parent)
col? (col? parent)
h-center? (h-center? parent)
h-end? (h-end? parent)
v-center? (v-center? parent)
v-end? (v-end? parent)
space-between? (= :space-between layout-type)
space-around? (= :space-around layout-type)]
(letfn [(get-base-line
[total-width total-height]
(cond-> (origin layout-bounds)
(and row? h-center?)
(gpt/add (start-hv layout-bounds (/ (- layout-width total-width) 2)))
(and row? h-end?)
(gpt/add (start-hv layout-bounds (- layout-width total-width)))
(and col? v-center?)
(gpt/add (start-vv layout-bounds (/ (- layout-height total-height) 2)))
(and col? v-end?)
(gpt/add (start-vv layout-bounds (- layout-height total-height)))
))
(get-start-line
[{:keys [line-width line-height num-children child-fill?]} base-p]
(let [children-gap (* layout-gap (dec num-children))
;;line-width (if (and col? child-fill?)
;; (- layout-width (* layout-gap num-children))
;; line-width)
;;
;;line-height (if (and row? child-fill?)
;; (- layout-height (* layout-gap num-children))
;; line-height)
start-p
(cond-> base-p
;; X AXIS
(and col? h-center? (not space-between?) (not space-around?))
(-> (gpt/add (start-hv layout-bounds (/ layout-width 2)))
(gpt/subtract (start-hv layout-bounds (/ (+ line-width children-gap) 2))))
(and col? h-end? (not space-between?) (not space-around?))
(-> (gpt/add (start-hv layout-bounds layout-width))
(gpt/subtract (start-hv layout-bounds (+ line-width children-gap))))
(and row? h-center? (not space-between?) (not space-around?))
(gpt/add (start-hv layout-bounds (/ line-width 2)))
(and row? h-end? (not space-between?) (not space-around?))
(gpt/add (start-hv layout-bounds line-width))
;; Y AXIS
(and row? v-center? (not space-between?) (not space-around?))
(-> (gpt/add (start-vv layout-bounds (/ layout-height 2)))
(gpt/subtract (start-vv layout-bounds (/ (+ line-height children-gap) 2))))
(and row? v-end? (not space-between?) (not space-around?))
(-> (gpt/add (start-vv layout-bounds layout-height))
(gpt/subtract (start-vv layout-bounds (+ line-height children-gap))))
(and col? v-center? (not space-between?) (not space-around?))
(gpt/add (start-vv layout-bounds (/ line-height 2)))
(and col? v-end? (not space-between?) (not space-around?))
(gpt/add (start-vv layout-bounds line-height))
)
;;start-x
;;(cond
;; ;;(and (col? shape) child-fill?)
;; ;; TODO LAYOUT: Start has to take into account max-width
;; ;;x
;;
;; (or (and col? space-between?) (and col? space-around?))
;; x
;;
;; (and col? h-center?)
;; (- (+ x (/ width 2)) (/ (+ line-width children-gap) 2))
;;
;; (and col? h-end?)
;; (- (+ x width) (+ line-width children-gap))
;;
;; (and row? h-center?)
;; (+ base-x (/ line-width 2))
;;
;; (and row? h-end?)
;; (+ base-x line-width)
;;
;; row?
;; base-x
;;
;; :else
;; x)
;;start-y
;;(cond
;; ;; (and (row? shape) child-fill?)
;; ;; TODO LAYOUT: Start has to take into account max-width
;; ;; y
;;
;; (or (and (row? shape) (= :space-between layout-type))
;; (and (row? shape) (= :space-around layout-type)))
;; y
;;
;; (and (row? shape) (v-center? shape))
;; (- (+ y (/ height 2)) (/ (+ line-height children-gap) 2))
;;
;; (and (row? shape) (v-end? shape))
;; (- (+ y height) (+ line-height children-gap))
;;
;; (and (col? shape) (v-center? shape))
;; (+ base-y (/ line-height 2))
;;
;; (and (col? shape) (v-end? shape))
;; (+ base-y line-height)
;;
;; (col? shape)
;; base-y
;;
;; :else
;; y)
]
start-p))
(get-next-line
[{:keys [line-width line-height]} base-p]
(cond-> base-p
col?
(gpt/add (start-hv layout-bounds (+ line-width layout-gap)))
row?
(gpt/add (start-vv layout-bounds (+ line-height layout-gap)))
)
#_(let [next-x (if col? base-x (+ base-x line-width layout-gap))
next-y (if row? base-y (+ base-y line-height layout-gap))]
[next-x next-y]))
(add-lines [[total-width total-height] {:keys [line-width line-height]}]
[(+ total-width line-width)
(+ total-height line-height)])
(add-starts [[result base-p] layout-line]
(let [start-p (get-start-line layout-line base-p)
next-p (get-next-line layout-line base-p)]
[(conj result
(assoc layout-line :start-p start-p))
next-p]))]
(let [[total-width total-height] (->> layout-lines (reduce add-lines [0 0]))
total-width (+ total-width (* layout-gap (dec (count layout-lines))))
total-height (+ total-height (* layout-gap (dec (count layout-lines))))
vertical-fill-space (- layout-height total-height)
horizontal-fill-space (- layout-width total-width)
num-line-fill (count (->> layout-lines (filter :line-fill?)))
layout-lines
(->> layout-lines
(mapv #(cond-> %
(and col? (:line-fill? %))
(update :line-height + (/ vertical-fill-space num-line-fill))
(and row? (:line-fill? %))
(update :line-width + (/ horizontal-fill-space num-line-fill)))))
total-height (if (and col? (> num-line-fill 0)) layout-height total-height)
total-width (if (and row? (> num-line-fill 0)) layout-width total-width)
base-p (get-base-line total-width total-height)
[layout-lines _ _ _ _]
(reduce add-starts [[] base-p] layout-lines)]
layout-lines))))
(defn calc-layout-line-data
[{:keys [layout-type layout-gap] :as shape}
{:keys [width height] :as layout-bounds}
{:keys [num-children line-width line-height] :as line-data}]
(let [layout-gap
(cond
(= :packed layout-type)
layout-gap
(= :space-around layout-type)
0
(and (col? shape) (= :space-between layout-type))
(/ (- width line-width) (dec num-children))
(and (row? shape) (= :space-between layout-type))
(/ (- height line-height) (dec num-children)))
margin-x
(if (and (col? shape) (= :space-around layout-type))
(/ (- width line-width) (inc num-children) )
0)
margin-y
(if (and (row? shape) (= :space-around layout-type))
(/ (- height line-height) (inc num-children))
0)]
(assoc line-data
:layout-bounds layout-bounds
:layout-gap layout-gap
:margin-x margin-x
:margin-y margin-y)))
(defn next-p
"Calculates the position for the current shape given the layout-data context"
[parent
child-bounds
{:keys [start-p layout-gap margin-x margin-y] :as layout-data}]
(let [width (width-points child-bounds)
height (height-points child-bounds)
row? (row? parent)
col? (col? parent)
h-center? (h-center? parent)
h-end? (h-end? parent)
v-center? (v-center? parent)
v-end? (v-end? parent)
points (:points parent)
corner-p
(cond-> start-p
(and row? h-center?)
(gpt/add (start-hv points (- (/ width 2))))
(and row? h-end?)
(gpt/add (start-hv points (- width)))
(and col? v-center?)
(gpt/add (start-vv points (- (/ height 2))))
(and col? v-end?)
(gpt/add (start-vv points (- height)))
(some? margin-x)
(gpt/add (start-hv points margin-x))
(some? margin-y)
(gpt/add (start-vv points margin-y)))
next-p
(cond-> start-p
col?
(gpt/add (start-hv points (+ width layout-gap)))
row?
(gpt/add (start-vv points (+ height layout-gap)))
(some? margin-x)
(gpt/add (start-hv points margin-x))
(some? margin-y)
(gpt/add (start-vv points margin-y)))
layout-data
(assoc layout-data :start-p next-p)]
[corner-p layout-data]))
(defn calc-fill-width-data
[child-bounds
{:keys [layout-gap] :as parent}
{:keys [layout-h-behavior] :as child}
{:keys [num-children line-width layout-bounds line-fill? child-fill?] :as layout-data}]
(cond
(and (col? parent) (= :fill layout-h-behavior) child-fill?)
(let [fill-space (- (:width layout-bounds) line-width (* layout-gap num-children))
fill-width (/ fill-space (:num-child-fill layout-data))
fill-scale (/ fill-width (:width child-bounds))]
{:bounds {:width fill-width}
:modifiers [{:type :resize
:origin (gpt/point child-bounds)
:vector (gpt/point fill-scale 1)}]})
(and (row? parent) (= :fill layout-h-behavior) line-fill?)
(let [fill-scale (/ line-width (:width child-bounds))]
{:bounds {:width line-width}
:modifiers [{:type :resize
:origin (gpt/point child-bounds)
:vector (gpt/point fill-scale 1)}]})
))
(defn calc-fill-height-data
[child-bounds
{:keys [layout-gap] :as parent}
{:keys [layout-v-behavior] :as child}
{:keys [num-children line-height layout-bounds line-fill? child-fill?] :as layout-data}]
(cond
(and (row? parent) (= :fill layout-v-behavior) child-fill?)
(let [fill-space (- (:height layout-bounds) line-height (* layout-gap num-children))
fill-height (/ fill-space (:num-child-fill layout-data))
fill-scale (/ fill-height (:height child-bounds))]
{:bounds {:height fill-height}
:modifiers [{:type :resize
:origin (gpt/point child-bounds)
:vector (gpt/point 1 fill-scale)}]})
(and (col? parent) (= :fill layout-v-behavior) line-fill?)
(let [fill-scale (/ line-height (:height child-bounds))]
{:bounds {:height line-height}
:modifiers [{:type :resize
:origin (gpt/point child-bounds)
:vector (gpt/point 1 fill-scale)}]})
))
(defn normalize-child-modifiers
"Apply the modifiers and then normalized them against the parent coordinates"
[parent child modifiers transformed-parent]
(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))]
(-> modifiers
(update :v2 #(conj %
{:type :resize
:transform (:transform transformed-parent)
:transform-inverse (:transform-inverse transformed-parent)
:origin (-> transformed-parent :points (nth 0))
:vector (gpt/point scale-x scale-y)})))))
(defn calc-layout-data
"Digest the layout data to pass it to the constrains"
[{:keys [layout-dir points layout-padding layout-padding-type] :as parent} children]
(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])
layout-bounds (-> points (pad-points pad-top pad-right pad-bottom pad-left))
;; Reverse
reverse? (or (= :left layout-dir) (= :bottom layout-dir))
children (cond->> children reverse? reverse)
;; Creates the layout lines information
layout-lines
(->> (calc-layout-lines parent children layout-bounds)
(calc-layout-lines-position parent layout-bounds)
(map (partial calc-layout-line-data parent layout-bounds)))]
{:layout-lines layout-lines
:reverse? reverse?}))
(defn calc-layout-modifiers
"Calculates the modifiers for the layout"
[parent child layout-line]
(let [child-bounds (gst/parent-coords-points child parent)
;;fill-width (calc-fill-width-data child-bounds parent child layout-line)
;;fill-height (calc-fill-height-data child-bounds parent child layout-line)
;;child-bounds (cond-> child-bounds
;; fill-width (merge (:bounds fill-width))
;; fill-height (merge (:bounds fill-height)))
[corner-p layout-line] (next-p parent child-bounds layout-line)
move-vec (gpt/to-vec (origin child-bounds) corner-p)
modifiers
(-> []
#_(cond-> fill-width (d/concat-vec (:modifiers fill-width)))
#_(cond-> fill-height (d/concat-vec (:modifiers fill-height)))
(conj {:type :move :vector move-vec}))]
[modifiers layout-line]))

View file

@ -11,7 +11,8 @@
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes.common :as gco] [app.common.geom.shapes.common :as gco]
[app.common.geom.shapes.constraints :as gct] [app.common.geom.shapes.constraints :as gct]
[app.common.geom.shapes.layout :as gcl] [app.common.geom.shapes.layout :as gclo]
[app.common.geom.shapes.layout-new :as gcln]
[app.common.geom.shapes.rect :as gpr] [app.common.geom.shapes.rect :as gpr]
[app.common.geom.shapes.transforms :as gtr] [app.common.geom.shapes.transforms :as gtr]
[app.common.math :as mth] [app.common.math :as mth]
@ -108,40 +109,21 @@
(defn set-children-modifiers (defn set-children-modifiers
[modif-tree objects shape ignore-constraints snap-pixel?] [modif-tree objects parent ignore-constraints snap-pixel?]
;; TODO LAYOUT: SNAP PIXEL! ;; TODO LAYOUT: SNAP PIXEL!
(letfn [(set-child [transformed-parent _snap-pixel? modif-tree child] (letfn [(set-child [transformed-parent _snap-pixel? modif-tree child]
(let [modifiers (get-in modif-tree [(:id shape) :modifiers]) (let [modifiers (get-in modif-tree [(:id parent) :modifiers])
child-modifiers (gct/calc-child-modifiers parent child modifiers ignore-constraints transformed-parent)
child-modifiers (gct/calc-child-modifiers shape child modifiers ignore-constraints transformed-parent)
;;_ (.log js/console (:name child) (clj->js child-modifiers))
;;child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child)) ;;child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))
]
result
(cond-> modif-tree (cond-> modif-tree
(not (ctm/empty-modifiers? child-modifiers)) (not (ctm/empty-modifiers? child-modifiers))
(update-in [(:id child) :modifiers :v2] #(d/concat-vec % (:v2 child-modifiers))) (update-in [(:id child) :modifiers :v2] d/concat-vec (:v2 child-modifiers)))))]
#_(update-in [(:id child) :modifiers] #(merge-mod2 child-modifiers %))
#_(update-in [(:id child) :modifiers] #(merge child-modifiers %)))
;;_ (.log js/console ">>>" (:name child)) (let [children (map (d/getf objects) (:shapes parent))
;;_ (.log js/console " >" (clj->js child-modifiers)) modifiers (get-in modif-tree [(:id parent) :modifiers])
;;_ (.log js/console " >" (clj->js (get-in modif-tree [(:id child) :modifiers]))) transformed-parent (gtr/transform-shape parent modifiers)]
;;_ (.log js/console " >" (clj->js (get-in result [(:id child) :modifiers]))) (reduce (partial set-child transformed-parent snap-pixel?) modif-tree children))))
]
result
))
]
(let [children (map (d/getf objects) (:shapes shape))
modifiers (get-in modif-tree [(:id shape) :modifiers])
;; transformed-rect (gtr/transform-selrect (:selrect shape) modifiers)
;; transformed-rect (-> shape (merge {:modifiers modifiers}) gtr/transform-shape :selrect)
transformed-parent (-> shape (merge {:modifiers modifiers}) gtr/transform-shape)
resize-modif? (or (:resize-vector modifiers) (:resize-vector-2 modifiers))]
(reduce (partial set-child transformed-parent (and snap-pixel? resize-modif?)) modif-tree children))))
(defn group? [shape] (defn group? [shape]
(or (= :group (:type shape)) (or (= :group (:type shape))
@ -158,6 +140,68 @@
;; TODO LAYOUT: SNAP PIXEL! ;; TODO LAYOUT: SNAP PIXEL!
[modif-tree objects parent _snap-pixel?] [modif-tree objects parent _snap-pixel?]
(letfn [(normalize-child [transformed-parent _snap-pixel? modif-tree child]
(let [modifiers (get-in modif-tree [(:id parent) :modifiers])
child-modifiers (gcln/normalize-child-modifiers parent child modifiers transformed-parent)]
(cond-> modif-tree
(not (ctm/empty-modifiers? child-modifiers))
(update-in [(:id child) :modifiers :v2] d/concat-vec (:v2 child-modifiers)))))
(apply-modifiers [modif-tree child]
(let [modifiers (get-in modif-tree [(:id child) :modifiers])]
(cond-> child
(some? modifiers)
(gtr/transform-shape modifiers)
(and (nil? modifiers) (group? child))
(gtr/apply-group-modifiers objects modif-tree))))
(set-layout-modifiers [parent [layout-line modif-tree] child]
(let [[modifiers layout-line]
(gcln/calc-layout-modifiers parent child layout-line)
modif-tree
(cond-> modif-tree
(d/not-empty? modifiers)
(update-in [(:id child) :modifiers :v2] d/concat-vec modifiers))]
[layout-line modif-tree]))]
(let [children (map (d/getf objects) (:shapes parent))
modifiers (get-in modif-tree [(:id parent) :modifiers])
transformed-parent (gtr/transform-shape parent modifiers)
modif-tree (reduce (partial normalize-child transformed-parent _snap-pixel?) modif-tree children)
children (->> children (map (partial apply-modifiers modif-tree)))
layout-data (gcln/calc-layout-data transformed-parent children)
children (into [] (cond-> children (: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)
from-idx 0]
(if (and (some? layout-line) (<= from-idx max-idx))
(let [to-idx (+ from-idx (:num-children layout-line))
children (subvec children from-idx to-idx)
[_ modif-tree]
(reduce (partial set-layout-modifiers transformed-parent) [layout-line modif-tree] children)]
(recur modif-tree (first pending) (rest pending) to-idx))
modif-tree)))))
#_(defn set-layout-modifiers'
;; TODO LAYOUT: SNAP PIXEL!
[modif-tree objects parent _snap-pixel?]
(letfn [(transform-child [child] (letfn [(transform-child [child]
(let [modifiers (get modif-tree (:id child)) (let [modifiers (get modif-tree (:id child))
@ -182,8 +226,7 @@
modif-tree modif-tree
(cond-> modif-tree (cond-> modif-tree
(d/not-empty? modifiers) (d/not-empty? modifiers)
(update-in [(:id child) :modifiers :v2] d/concat-vec modifiers) (update-in [(:id child) :modifiers :v2] d/concat-vec modifiers))]
#_(merge-modifiers [(:id child)] modifiers))]
[layout-data modif-tree]))] [layout-data modif-tree]))]
@ -218,7 +261,6 @@
[_ modif-tree] [_ modif-tree]
(reduce (partial set-layout-modifiers shape transform) [layout-line modif-tree] children)] (reduce (partial set-layout-modifiers shape transform) [layout-line modif-tree] children)]
(recur modif-tree (first pending) (rest pending) to-idx)) (recur modif-tree (first pending) (rest pending) to-idx))
modif-tree))))) modif-tree)))))
@ -316,11 +358,12 @@
is-inside-layout? (inside-layout? objects shape)] is-inside-layout? (inside-layout? objects shape)]
(cond-> modif-tree (cond-> modif-tree
(and has-modifiers? is-parent?)
(set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?)
is-layout? is-layout?
(set-layout-modifiers objects shape snap-pixel?) (set-layout-modifiers objects shape snap-pixel?)
)))
(and has-modifiers? is-parent?)
(set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?))))
modif-tree))] modif-tree))]

View file

@ -558,3 +558,19 @@
(apply-group-modifiers shape objects modif-tree) (apply-group-modifiers shape objects modif-tree)
shape)))))] shape)))))]
(update-group-selrect group children))) (update-group-selrect group children)))
(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))))

View file

@ -24,7 +24,10 @@
[app.main.ui.workspace.shapes.frame.node-store :as fns] [app.main.ui.workspace.shapes.frame.node-store :as fns]
[app.main.ui.workspace.shapes.frame.thumbnail-render :as ftr] [app.main.ui.workspace.shapes.frame.thumbnail-render :as ftr]
[beicon.core :as rx] [beicon.core :as rx]
[rumext.v2 :as mf])) [rumext.v2 :as mf]
[app.common.geom.shapes.layout :as gsl]
[app.common.geom.point :as gpt]))
(defn frame-shape-factory (defn frame-shape-factory
[shape-wrapper] [shape-wrapper]