mirror of
https://github.com/penpot/penpot.git
synced 2025-03-20 03:31:24 -05:00
✨ Adds autolayout positions calculations
This commit is contained in:
parent
5050c35257
commit
c01c46041d
37 changed files with 938 additions and 594 deletions
common/src/app/common
geom
pages
types
frontend/src/app
main
data/workspace
render.cljsui
shapes
viewer
workspace
util/geom
|
@ -252,3 +252,14 @@
|
|||
(update :d mth/precision 4)
|
||||
(update :e mth/precision 4)
|
||||
(update :f mth/precision 4)))
|
||||
|
||||
(defn transform-point-center
|
||||
"Transform a point around the shape center"
|
||||
[point center matrix]
|
||||
(if (and (some? point) (some? matrix) (some? center))
|
||||
(gpt/transform
|
||||
point
|
||||
(multiply (translate-matrix center)
|
||||
matrix
|
||||
(translate-matrix (gpt/negate center))))
|
||||
point))
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
rotation of each shape. Mainly used for multiple selection."
|
||||
[shapes]
|
||||
(->> shapes
|
||||
(map (comp gpr/points->selrect :points gtr/transform-shape))
|
||||
(map (comp gpr/points->selrect :points))
|
||||
(gpr/join-selrects)))
|
||||
|
||||
(defn translate-to-frame
|
||||
|
@ -166,23 +166,17 @@
|
|||
(dm/export gtr/transform-matrix)
|
||||
(dm/export gtr/transform-str)
|
||||
(dm/export gtr/inverse-transform-matrix)
|
||||
(dm/export gtr/transform-point-center)
|
||||
(dm/export gtr/transform-rect)
|
||||
(dm/export gtr/calculate-adjust-matrix)
|
||||
(dm/export gtr/update-group-selrect)
|
||||
(dm/export gtr/update-mask-selrect)
|
||||
(dm/export gtr/resize-modifiers)
|
||||
(dm/export gtr/change-orientation-modifiers)
|
||||
(dm/export gtr/rotation-modifiers)
|
||||
(dm/export gtr/merge-modifiers)
|
||||
(dm/export gtr/transform-shape)
|
||||
(dm/export gtr/transform-selrect)
|
||||
(dm/export gtr/transform-selrect-matrix)
|
||||
(dm/export gtr/transform-bounds)
|
||||
(dm/export gtr/modifiers->transform)
|
||||
(dm/export gtr/empty-modifiers?)
|
||||
(dm/export gtr/move-position-data)
|
||||
(dm/export gtr/apply-transform)
|
||||
(dm/export gtr/apply-objects-modifiers)
|
||||
|
||||
;; Constratins
|
||||
(dm/export gct/calc-child-modifiers)
|
||||
|
|
|
@ -6,14 +6,19 @@
|
|||
|
||||
(ns app.common.geom.shapes.constraints
|
||||
(:require
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
[app.common.geom.shapes.intersect :as gsi]
|
||||
[app.common.geom.shapes.rect :as gre]
|
||||
[app.common.geom.shapes.transforms :as gst]
|
||||
[app.common.math :as mth]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
||||
;; Auxiliary methods to work in an specifica axis
|
||||
(defn other-axis [axis]
|
||||
(if (= :x axis) :y :x))
|
||||
|
||||
(defn get-delta-start [axis rect tr-rect]
|
||||
(if (= :x axis)
|
||||
(- (:x1 tr-rect) (:x1 rect))
|
||||
|
@ -29,6 +34,11 @@
|
|||
(- (:width tr-rect) (:width rect))
|
||||
(- (:height tr-rect) (:height rect))))
|
||||
|
||||
(defn get-delta-scale [axis rect tr-rect]
|
||||
(if (= :x axis)
|
||||
(/ (:width tr-rect) (:width rect))
|
||||
(/ (:height tr-rect) (:height rect))))
|
||||
|
||||
(defn get-delta-center [axis center tr-center]
|
||||
(if (= :x axis)
|
||||
(- (:x tr-center) (:x center))
|
||||
|
@ -53,78 +63,138 @@
|
|||
(:width rect)
|
||||
(:height rect)))
|
||||
|
||||
(defn right-vector
|
||||
[child-points parent-points]
|
||||
(let [[p0 p1 p2 _] parent-points
|
||||
[_c0 c1 _ _] child-points
|
||||
dir-v (gpt/to-vec p0 p1)
|
||||
cp (gsi/line-line-intersect c1 (gpt/add c1 dir-v) p1 p2)]
|
||||
(gpt/to-vec c1 cp)))
|
||||
|
||||
(defn left-vector
|
||||
[child-points parent-points]
|
||||
|
||||
(let [[p0 p1 _ p3] parent-points
|
||||
[_ _ _ c3] child-points
|
||||
dir-v (gpt/to-vec p0 p1)
|
||||
cp (gsi/line-line-intersect c3 (gpt/add c3 dir-v) p0 p3)]
|
||||
(gpt/to-vec c3 cp)))
|
||||
|
||||
|
||||
(defn top-vector
|
||||
[child-points parent-points]
|
||||
|
||||
(let [[p0 p1 _ p3] parent-points
|
||||
[c0 _ _ _] child-points
|
||||
dir-v (gpt/to-vec p0 p3)
|
||||
cp (gsi/line-line-intersect c0 (gpt/add c0 dir-v) p0 p1)]
|
||||
(gpt/to-vec c0 cp)))
|
||||
|
||||
(defn bottom-vector
|
||||
[child-points parent-points]
|
||||
|
||||
(let [[p0 _ p2 p3] parent-points
|
||||
[_ _ c2 _] child-points
|
||||
dir-v (gpt/to-vec p0 p3)
|
||||
cp (gsi/line-line-intersect c2 (gpt/add c2 dir-v) p2 p3)]
|
||||
(gpt/to-vec c2 cp)))
|
||||
|
||||
(defn center-horizontal-vector
|
||||
[child-points parent-points]
|
||||
|
||||
(let [[p0 p1 _ p3] parent-points
|
||||
[_ c1 _ _] child-points
|
||||
|
||||
dir-v (gpt/to-vec p0 p1)
|
||||
|
||||
p1c (gpt/add p0 (gpt/scale dir-v 0.5))
|
||||
p2c (gpt/add p3 (gpt/scale dir-v 0.5))
|
||||
|
||||
cp (gsi/line-line-intersect c1 (gpt/add c1 dir-v) p1c p2c)]
|
||||
|
||||
(gpt/to-vec c1 cp)))
|
||||
|
||||
(defn center-vertical-vector
|
||||
[child-points parent-points]
|
||||
(let [[p0 p1 p2 _] parent-points
|
||||
[_ c1 _ _] child-points
|
||||
|
||||
dir-v (gpt/to-vec p1 p2)
|
||||
|
||||
p3c (gpt/add p0 (gpt/scale dir-v 0.5))
|
||||
p2c (gpt/add p1 (gpt/scale dir-v 0.5))
|
||||
|
||||
cp (gsi/line-line-intersect c1 (gpt/add c1 dir-v) p3c p2c)]
|
||||
|
||||
(gpt/to-vec c1 cp)))
|
||||
|
||||
(defn start-vector
|
||||
[axis child-points parent-points]
|
||||
((if (= :x axis) left-vector top-vector) child-points parent-points))
|
||||
|
||||
(defn end-vector
|
||||
[axis child-points parent-points]
|
||||
((if (= :x axis) right-vector bottom-vector) child-points parent-points))
|
||||
|
||||
(defn center-vector
|
||||
[axis child-points parent-points]
|
||||
((if (= :x axis) center-horizontal-vector center-vertical-vector) child-points parent-points))
|
||||
|
||||
|
||||
;; Constraint function definitions
|
||||
|
||||
(defmulti constraint-modifier (fn [type & _] type))
|
||||
|
||||
(defmethod constraint-modifier :start
|
||||
[_ axis parent _ _ transformed-parent-rect]
|
||||
|
||||
(let [parent-rect (:selrect parent)
|
||||
delta-start (get-delta-start axis parent-rect transformed-parent-rect)]
|
||||
(if-not (mth/almost-zero? delta-start)
|
||||
{:displacement (get-displacement axis delta-start)}
|
||||
{})))
|
||||
|
||||
(defmethod constraint-modifier :end
|
||||
[_ axis parent _ _ transformed-parent-rect]
|
||||
(let [parent-rect (:selrect parent)
|
||||
delta-end (get-delta-end axis parent-rect transformed-parent-rect)]
|
||||
(if-not (mth/almost-zero? delta-end)
|
||||
{:displacement (get-displacement axis delta-end)}
|
||||
{})))
|
||||
[_ axis child-points-before parent-points-before child-points-after parent-points-after]
|
||||
(let [end-before (end-vector axis child-points-before parent-points-before)
|
||||
end-after (end-vector axis child-points-after parent-points-after)
|
||||
end-angl (gpt/angle-with-other end-before end-after)
|
||||
target-end (if (mth/close? end-angl 180) (- (gpt/length end-before)) (gpt/length end-before))
|
||||
disp-vector-end (gpt/subtract end-after (gpt/scale (gpt/unit end-after) target-end))]
|
||||
[{:type :move
|
||||
:vector disp-vector-end}]))
|
||||
|
||||
(defmethod constraint-modifier :fixed
|
||||
[_ axis parent child _ transformed-parent-rect]
|
||||
(let [parent-rect (:selrect parent)
|
||||
child-rect (gre/points->rect (:points child))
|
||||
[_ axis child-points-before parent-points-before child-points-after parent-points-after transformed-parent]
|
||||
(let [[c0 c1 _ c4] child-points-after
|
||||
|
||||
delta-start (get-delta-start axis parent-rect transformed-parent-rect)
|
||||
delta-size (get-delta-size axis parent-rect transformed-parent-rect)
|
||||
child-size (get-size axis child-rect)]
|
||||
(if (or (not (mth/almost-zero? delta-start))
|
||||
(not (mth/almost-zero? delta-size)))
|
||||
;; 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)
|
||||
end-angl (gpt/angle-with-other end-before end-after)
|
||||
target-end (if (mth/close? end-angl 180) (- (gpt/length end-before)) (gpt/length end-before))
|
||||
disp-vector-end (gpt/subtract end-after (gpt/scale (gpt/unit end-after) target-end))
|
||||
|
||||
{:displacement (get-displacement axis delta-start)
|
||||
:resize-origin (get-displacement axis delta-start (:x child-rect) (:y child-rect))
|
||||
:resize-vector (get-scale axis (/ (+ child-size delta-size) child-size))}
|
||||
{})))
|
||||
before-vec (if (= axis :x) (gpt/to-vec c0 c1) (gpt/to-vec c0 c4))
|
||||
after-vec (if (= axis :x)
|
||||
(gpt/to-vec c0 (gpt/add c1 disp-vector-end))
|
||||
(gpt/to-vec c0 (gpt/add c4 disp-vector-end))
|
||||
)
|
||||
|
||||
resize-angl (gpt/angle-with-other before-vec after-vec)
|
||||
resize-sign (if (mth/close? resize-angl 180) -1 1)
|
||||
|
||||
scale (* resize-sign (/ (gpt/length after-vec) (gpt/length before-vec)))
|
||||
]
|
||||
[{:type :resize
|
||||
:vector (get-scale axis scale)
|
||||
:origin c0
|
||||
:transform (:transform transformed-parent)
|
||||
:transform-inverse (:transform-inverse transformed-parent)}]))
|
||||
|
||||
(defmethod constraint-modifier :center
|
||||
[_ axis parent _ _ transformed-parent-rect]
|
||||
(let [parent-rect (:selrect parent)
|
||||
parent-center (gco/center-rect parent-rect)
|
||||
transformed-parent-center (gco/center-rect transformed-parent-rect)
|
||||
delta-center (get-delta-center axis parent-center transformed-parent-center)]
|
||||
(if-not (mth/almost-zero? delta-center)
|
||||
{:displacement (get-displacement axis delta-center)}
|
||||
{})))
|
||||
|
||||
(defmethod constraint-modifier :scale
|
||||
[_ axis _ _ modifiers _]
|
||||
(let [{:keys [resize-vector resize-vector-2 displacement]} modifiers]
|
||||
(cond-> {}
|
||||
(and (some? resize-vector)
|
||||
(not= (axis resize-vector) 1))
|
||||
(assoc :resize-origin (:resize-origin modifiers)
|
||||
:resize-vector (if (= :x axis)
|
||||
(gpt/point (:x resize-vector) 1)
|
||||
(gpt/point 1 (:y resize-vector))))
|
||||
|
||||
(and (= :y axis) (some? resize-vector-2)
|
||||
(not (mth/close? (:y resize-vector-2) 1)))
|
||||
(assoc :resize-origin (:resize-origin-2 modifiers)
|
||||
:resize-vector (gpt/point 1 (:y resize-vector-2)))
|
||||
|
||||
(some? displacement)
|
||||
(assoc :displacement
|
||||
(get-displacement axis (-> (gpt/point 0 0)
|
||||
(gpt/transform displacement)
|
||||
(gpt/transform (:resize-transform-inverse modifiers (gmt/matrix)))
|
||||
axis))))))
|
||||
[_ axis child-points-before parent-points-before child-points-after parent-points-after]
|
||||
(let [center-before (center-vector axis child-points-before parent-points-before)
|
||||
center-after (center-vector axis child-points-after parent-points-after)
|
||||
center-angl (gpt/angle-with-other center-before center-after)
|
||||
target-center (if (mth/close? center-angl 180) (- (gpt/length center-before)) (gpt/length center-before))
|
||||
disp-vector-center (gpt/subtract center-after (gpt/scale (gpt/unit center-after) target-center))]
|
||||
[{:type :move
|
||||
:vector disp-vector-center}]))
|
||||
|
||||
(defmethod constraint-modifier :default [_ _ _ _ _]
|
||||
{})
|
||||
[])
|
||||
|
||||
(def const->type+axis
|
||||
{:left :start
|
||||
|
@ -152,7 +222,7 @@
|
|||
:top
|
||||
:scale)))
|
||||
|
||||
(defn clean-modifiers
|
||||
#_(defn clean-modifiers
|
||||
"Remove redundant modifiers"
|
||||
[{:keys [displacement resize-vector resize-vector-2] :as modifiers}]
|
||||
|
||||
|
@ -174,55 +244,91 @@
|
|||
(mth/almost-zero? (- 1.0 (:y resize-vector-2))))
|
||||
(dissoc :resize-origin-2 :resize-vector-2)))
|
||||
|
||||
|
||||
(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 transformed-parent]
|
||||
|
||||
(let [child-bb-before
|
||||
(-> child
|
||||
: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-y (/ (:height child-bb-before) (:height child-bb-after))]
|
||||
|
||||
(-> modifiers
|
||||
(update :v2 #(cond-> %
|
||||
(not= :scale constraints-h)
|
||||
(conj
|
||||
;; This resize will leave the shape in its original position relative to the parent
|
||||
{:type :resize
|
||||
:transform (:transform transformed-parent)
|
||||
:transform-inverse (:transform-inverse transformed-parent)
|
||||
:origin (-> transformed-parent :points (nth 0))
|
||||
:vector (gpt/point scale-x 1)})
|
||||
|
||||
(not= :scale constraints-v)
|
||||
(conj
|
||||
{:type :resize
|
||||
:transform (:transform transformed-parent)
|
||||
:transform-inverse (:transform-inverse transformed-parent)
|
||||
:origin (-> transformed-parent :points (nth 0))
|
||||
:vector (gpt/point 1 scale-y)}))))))
|
||||
|
||||
(defn calc-child-modifiers
|
||||
[parent child modifiers ignore-constraints transformed-parent-rect]
|
||||
[parent child modifiers ignore-constraints transformed-parent]
|
||||
|
||||
(if (and (nil? (:resize-vector modifiers))
|
||||
(nil? (:resize-vector-2 modifiers)))
|
||||
;; If we don't have a resize modifier we return the same modifiers
|
||||
modifiers
|
||||
(let [constraints-h
|
||||
(if-not ignore-constraints
|
||||
(:constraints-h child (default-constraints-h child))
|
||||
:scale)
|
||||
(let [constraints-h
|
||||
(if-not ignore-constraints
|
||||
(:constraints-h child (default-constraints-h child))
|
||||
:scale)
|
||||
|
||||
constraints-v
|
||||
(if-not ignore-constraints
|
||||
(:constraints-v child (default-constraints-v child))
|
||||
:scale)
|
||||
constraints-v
|
||||
(if-not ignore-constraints
|
||||
(:constraints-v child (default-constraints-v child))
|
||||
:scale)]
|
||||
|
||||
modifiers-h (constraint-modifier (constraints-h const->type+axis) :x parent child modifiers transformed-parent-rect)
|
||||
modifiers-v (constraint-modifier (constraints-v const->type+axis) :y parent child modifiers transformed-parent-rect)]
|
||||
(if (and (= :scale constraints-h) (= :scale constraints-v))
|
||||
modifiers
|
||||
|
||||
;; Build final child modifiers. Apply transform again to the result, to get the
|
||||
;; real modifiers that need to be applied to the child, including rotation as needed.
|
||||
(cond-> {}
|
||||
(some? (:displacement-after modifiers))
|
||||
(assoc :displacement-after (:displacement-after modifiers))
|
||||
(let [transformed-child (gst/transform-shape child modifiers)
|
||||
modifiers (normalize-modifiers constraints-h constraints-v modifiers child parent transformed-child transformed-parent)
|
||||
|
||||
(or (contains? modifiers-h :displacement)
|
||||
(contains? modifiers-v :displacement))
|
||||
(assoc :displacement (cond-> (gpt/point (get-in modifiers-h [:displacement :x] 0)
|
||||
(get-in modifiers-v [:displacement :y] 0))
|
||||
(some? (:resize-transform modifiers))
|
||||
(gpt/transform (:resize-transform modifiers))
|
||||
tranformed-child-2 (gst/transform-shape child modifiers)
|
||||
parent-points-before (:points parent)
|
||||
child-points-before (bounding-box-parent-transform child parent)
|
||||
|
||||
:always
|
||||
(gmt/translate-matrix)))
|
||||
parent-points-after (:points transformed-parent)
|
||||
child-points-after (bounding-box-parent-transform tranformed-child-2 transformed-parent)
|
||||
|
||||
(:resize-vector modifiers-h)
|
||||
(assoc :resize-origin (:resize-origin modifiers-h)
|
||||
:resize-vector (gpt/point (get-in modifiers-h [:resize-vector :x] 1)
|
||||
(get-in modifiers-h [:resize-vector :y] 1)))
|
||||
modifiers-h (constraint-modifier (constraints-h const->type+axis) :x
|
||||
child-points-before parent-points-before
|
||||
child-points-after parent-points-after
|
||||
transformed-parent)
|
||||
|
||||
(:resize-vector modifiers-v)
|
||||
(assoc :resize-origin-2 (:resize-origin modifiers-v)
|
||||
:resize-vector-2 (gpt/point (get-in modifiers-v [:resize-vector :x] 1)
|
||||
(get-in modifiers-v [:resize-vector :y] 1)))
|
||||
modifiers-v (constraint-modifier (constraints-v const->type+axis) :y
|
||||
child-points-before parent-points-before
|
||||
child-points-after parent-points-after
|
||||
transformed-parent)]
|
||||
|
||||
(:resize-transform modifiers)
|
||||
(assoc :resize-transform (:resize-transform modifiers)
|
||||
:resize-transform-inverse (:resize-transform-inverse modifiers))
|
||||
|
||||
:always
|
||||
(clean-modifiers)))))
|
||||
(update modifiers :v2 d/concat-vec modifiers-h modifiers-v)))))
|
||||
|
|
|
@ -348,3 +348,25 @@
|
|||
:points
|
||||
(every? (partial has-point-rect? rect))))
|
||||
|
||||
|
||||
(defn line-line-intersect
|
||||
"Calculates the interesection point for two lines given by the points a-b and b-c"
|
||||
[a b c d]
|
||||
|
||||
(let [;; Line equation representation: ax + by + c = 0
|
||||
a1 (- (:y b) (:y a))
|
||||
b1 (- (:x a) (:x b))
|
||||
c1 (+ (* a1 (:x a)) (* b1 (:y a)))
|
||||
|
||||
a2 (- (:y d) (:y c))
|
||||
b2 (- (:x c) (:x d))
|
||||
c2 (+ (* a2 (:x c)) (* b2 (:y c)))
|
||||
|
||||
;; Cramer's rule
|
||||
det (- (* a1 b2) (* a2 b1))]
|
||||
|
||||
;; If almost zero the lines are parallel
|
||||
(when (not (mth/almost-zero? det))
|
||||
(let [x (/ (- (* b2 c1) (* b1 c2)) det)
|
||||
y (/ (- (* c2 a1) (* c1 a2)) det)]
|
||||
(gpt/point x y)))))
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
(ns app.common.geom.shapes.layout
|
||||
(:require
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.rect :as gre]))
|
||||
|
||||
|
@ -71,24 +70,39 @@
|
|||
(let [wrap? (= layout-wrap-type :wrap)
|
||||
|
||||
reduce-fn
|
||||
(fn [[{:keys [line-width line-height num-children] :as line-data} result] child]
|
||||
(fn [[{:keys [line-width line-height num-children child-fill? num-child-fill] :as line-data} result] child]
|
||||
(let [child-bounds (-> child :points gre/points->rect)
|
||||
next-width (-> child-bounds :width)
|
||||
next-height (-> child-bounds :height)]
|
||||
|
||||
cur-child-fill?
|
||||
(or (and (col? shape) (= :fill (:layout-h-behavior child)))
|
||||
(and (row? shape) (= :fill (:layout-v-behavior child))))
|
||||
|
||||
next-width (if cur-child-fill?
|
||||
0
|
||||
(-> child-bounds :width))
|
||||
|
||||
next-height (if cur-child-fill?
|
||||
0
|
||||
(-> child-bounds :height))]
|
||||
|
||||
(if (and (some? line-data)
|
||||
(or (not wrap?)
|
||||
(and (col? shape) (<= (+ line-width next-width (* layout-gap num-children)) width))
|
||||
(and (row? shape) (<= (+ line-height next-height (* layout-gap num-children)) height))))
|
||||
|
||||
[{:line-width (if (col? shape) (+ line-width next-width) (max line-width next-width))
|
||||
:line-height (if (row? shape) (+ line-height next-height) (max line-height next-height))
|
||||
:num-children (inc num-children)}
|
||||
;; Si autofill añadimos el minwidth que por defecto es 0
|
||||
[{:line-width (if (col? shape) (+ line-width next-width) (max line-width next-width))
|
||||
:line-height (if (row? shape) (+ line-height next-height) (max line-height next-height))
|
||||
:num-children (inc num-children)
|
||||
:child-fill? (or cur-child-fill? child-fill?)
|
||||
:num-child-fill (cond-> num-child-fill cur-child-fill? inc)}
|
||||
result]
|
||||
|
||||
[{:line-width next-width
|
||||
:line-height next-height
|
||||
:num-children 1}
|
||||
[{:line-width next-width
|
||||
:line-height next-height
|
||||
:num-children 1
|
||||
:child-fill? child-fill?
|
||||
:num-child-fill (if child-fill? 1 0)}
|
||||
(cond-> result (some? line-data) (conj line-data))])))
|
||||
|
||||
[line-data layout-lines] (reduce reduce-fn [nil []] children)]
|
||||
|
@ -124,13 +138,14 @@
|
|||
[base-x base-y]))
|
||||
|
||||
(get-start-line
|
||||
[{:keys [line-width line-height num-children]} base-x base-y]
|
||||
[{:keys [line-width line-height num-children child-fill?]} base-x base-y]
|
||||
|
||||
(let [children-gap (* layout-gap (dec num-children))
|
||||
|
||||
start-x
|
||||
(cond
|
||||
(or (and (col? shape) (= :space-between layout-type))
|
||||
(or (and (col? shape) child-fill?)
|
||||
(and (col? shape) (= :space-between layout-type))
|
||||
(and (col? shape) (= :space-around layout-type)))
|
||||
x
|
||||
|
||||
|
@ -154,7 +169,8 @@
|
|||
|
||||
start-y
|
||||
(cond
|
||||
(or (and (row? shape) (= :space-between layout-type))
|
||||
(or (and (row? shape) child-fill?)
|
||||
(and (row? shape) (= :space-between layout-type))
|
||||
(and (row? shape) (= :space-around layout-type)))
|
||||
y
|
||||
|
||||
|
@ -240,6 +256,7 @@
|
|||
0)]
|
||||
|
||||
(assoc line-data
|
||||
:layout-bounds layout-bounds
|
||||
:layout-gap layout-gap
|
||||
:margin-x margin-x
|
||||
:margin-y margin-y)))
|
||||
|
@ -314,14 +331,39 @@
|
|||
"Calculates the modifiers for the layout"
|
||||
[parent transform child layout-data]
|
||||
|
||||
(let [bounds (-> child :points gre/points->selrect)
|
||||
(let [child-bounds (-> child :points gre/points->selrect)
|
||||
|
||||
[corner-p layout-data] (next-p parent bounds layout-data)
|
||||
fill-space (- (-> layout-data :layout-bounds :width) (:line-width layout-data))
|
||||
|
||||
fill-width (- (/ fill-space (:num-child-fill layout-data))
|
||||
(* 2 (:layout-gap layout-data)))
|
||||
|
||||
fill-scale (/ fill-width (:width child-bounds))
|
||||
|
||||
child-bounds
|
||||
(cond-> child-bounds
|
||||
(and (col? parent) (= :fill (:layout-h-behavior child)))
|
||||
(assoc :width fill-width))
|
||||
|
||||
[corner-p layout-data] (next-p parent child-bounds layout-data)
|
||||
|
||||
delta-p (-> corner-p
|
||||
(gpt/subtract (gpt/point bounds))
|
||||
(gpt/subtract (gpt/point child-bounds))
|
||||
(cond-> (some? transform) (gpt/transform transform)))
|
||||
|
||||
modifiers {:displacement-after (gmt/translate-matrix delta-p)}]
|
||||
modifiers []
|
||||
|
||||
modifiers
|
||||
(cond-> modifiers
|
||||
(and (col? parent) (= :fill (:layout-h-behavior child)))
|
||||
(conj {:type :resize
|
||||
:from :layout
|
||||
:origin (gpt/point child-bounds)
|
||||
:vector (gpt/point fill-scale 1)}))
|
||||
|
||||
modifiers
|
||||
(conj modifiers {:type :move
|
||||
:from :layout
|
||||
:vector delta-p})]
|
||||
|
||||
[modifiers layout-data]))
|
||||
|
|
|
@ -15,8 +15,10 @@
|
|||
[app.common.geom.shapes.rect :as gpr]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
||||
;; TODO LAYOUT: ADAPT TO NEW MODIFIERS
|
||||
(defn set-pixel-precision
|
||||
"Adjust modifiers so they adjust to the pixel grid"
|
||||
[modifiers shape]
|
||||
|
@ -106,44 +108,65 @@
|
|||
|
||||
|
||||
(defn set-children-modifiers
|
||||
[modif-tree shape objects ignore-constraints snap-pixel?]
|
||||
(letfn [(set-child [transformed-rect snap-pixel? modif-tree child]
|
||||
[modif-tree objects shape ignore-constraints snap-pixel?]
|
||||
;; TODO LAYOUT: SNAP PIXEL!
|
||||
(letfn [(set-child [transformed-parent _snap-pixel? modif-tree child]
|
||||
(let [modifiers (get-in modif-tree [(:id shape) :modifiers])
|
||||
child-modifiers (gct/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect)
|
||||
child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))]
|
||||
(cond-> modif-tree
|
||||
(not (gtr/empty-modifiers? child-modifiers))
|
||||
(update-in [(:id child) :modifiers] #(merge child-modifiers %)))))]
|
||||
|
||||
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))
|
||||
|
||||
result
|
||||
(cond-> modif-tree
|
||||
(not (ctm/empty-modifiers? 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))
|
||||
;;_ (.log js/console " >" (clj->js child-modifiers))
|
||||
;;_ (.log js/console " >" (clj->js (get-in modif-tree [(:id child) :modifiers])))
|
||||
;;_ (.log js/console " >" (clj->js (get-in result [(:id child) :modifiers])))
|
||||
]
|
||||
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 (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-rect (and snap-pixel? resize-modif?)) modif-tree children))))
|
||||
(reduce (partial set-child transformed-parent (and snap-pixel? resize-modif?)) modif-tree children))))
|
||||
|
||||
(defn group? [shape]
|
||||
(or (= :group (:type shape))
|
||||
(= :bool (:type shape))))
|
||||
|
||||
(defn merge-modifiers
|
||||
[modif-tree ids modifiers]
|
||||
(reduce
|
||||
(fn [modif-tree id]
|
||||
(update-in modif-tree [id :modifiers] #(merge % modifiers)))
|
||||
modif-tree
|
||||
ids))
|
||||
(defn frame? [shape]
|
||||
(= :frame (:type shape)))
|
||||
|
||||
(defn layout? [shape]
|
||||
(and (frame? shape)
|
||||
(:layout shape)))
|
||||
|
||||
(defn set-layout-modifiers
|
||||
[modif-tree objects id]
|
||||
;; TODO LAYOUT: SNAP PIXEL!
|
||||
[modif-tree objects parent _snap-pixel?]
|
||||
|
||||
(letfn [(transform-child [parent child]
|
||||
(letfn [(transform-child [child]
|
||||
(let [modifiers (get modif-tree (:id child))
|
||||
|
||||
child
|
||||
(cond-> child
|
||||
(not (group? child))
|
||||
(some? modifiers)
|
||||
(-> (merge modifiers) gtr/transform-shape)
|
||||
|
||||
(group? child)
|
||||
(and (nil? modifiers) (group? child))
|
||||
(gtr/apply-group-modifiers objects modif-tree))
|
||||
|
||||
child
|
||||
|
@ -158,22 +181,17 @@
|
|||
|
||||
modif-tree
|
||||
(cond-> modif-tree
|
||||
(not (gtr/empty-modifiers? modifiers))
|
||||
(merge-modifiers [(:id child)] modifiers)
|
||||
|
||||
(and (not (gtr/empty-modifiers? modifiers)) (group? child))
|
||||
(merge-modifiers (:shapes child) modifiers))]
|
||||
(d/not-empty? modifiers)
|
||||
(update-in [(:id child) :modifiers :v2] d/concat-vec modifiers)
|
||||
#_(merge-modifiers [(:id child)] modifiers))]
|
||||
|
||||
[layout-data modif-tree]))]
|
||||
|
||||
(let [modifiers (get modif-tree id)
|
||||
|
||||
shape (-> (get objects id) (merge modifiers) gtr/transform-shape)
|
||||
|
||||
|
||||
(let [modifiers (get modif-tree (:id parent))
|
||||
shape (-> parent (merge modifiers) gtr/transform-shape)
|
||||
children (->> (:shapes shape)
|
||||
(map (d/getf objects))
|
||||
(map (partial transform-child shape)))
|
||||
(map transform-child))
|
||||
|
||||
center (gco/center-shape shape)
|
||||
{:keys [transform transform-inverse]} shape
|
||||
|
@ -230,6 +248,17 @@
|
|||
:else
|
||||
(recur (:id parent) result)))))
|
||||
|
||||
(defn resolve-tree-sequence
|
||||
;; TODO LAYOUT: Esta ahora puesto al zero pero tiene que mirar todas las raices
|
||||
"Given the ids that have changed search for layout roots to recalculate"
|
||||
[_ids objects]
|
||||
(->> (tree-seq
|
||||
#(d/not-empty? (get-in objects [% :shapes]))
|
||||
#(get-in objects [% :shapes])
|
||||
uuid/zero)
|
||||
|
||||
(map #(get objects %))))
|
||||
|
||||
(defn resolve-layout-ids
|
||||
"Given a list of ids, resolve the parent layouts that will need to update. This will go upwards
|
||||
in the tree while a layout is found"
|
||||
|
@ -239,6 +268,28 @@
|
|||
(map #(get-first-layout % objects))
|
||||
ids))
|
||||
|
||||
(defn inside-layout?
|
||||
[objects shape]
|
||||
|
||||
(loop [current-id (:id shape)]
|
||||
(let [current (get objects current-id)]
|
||||
(cond
|
||||
(or (nil? current) (= current-id (:parent-id current)))
|
||||
false
|
||||
|
||||
(= :frame (:type current))
|
||||
(:layout current)
|
||||
|
||||
:else
|
||||
(recur (:parent-id current))))))
|
||||
|
||||
#_(defn modif->js
|
||||
[modif-tree objects]
|
||||
(clj->js (into {}
|
||||
(map (fn [[k v]]
|
||||
[(get-in objects [k :name]) v]))
|
||||
modif-tree)))
|
||||
|
||||
(defn set-objects-modifiers
|
||||
[ids objects get-modifier ignore-constraints snap-pixel?]
|
||||
|
||||
|
@ -251,40 +302,27 @@
|
|||
|
||||
modif-tree (reduce set-modifiers {} ids)
|
||||
|
||||
ids (resolve-layout-ids ids objects)
|
||||
shapes-tree (resolve-tree-sequence ids objects)
|
||||
|
||||
;; First: Calculate children modifiers (constraints, etc)
|
||||
[modif-tree touched-layouts]
|
||||
(loop [current (first ids)
|
||||
pending (rest ids)
|
||||
modif-tree modif-tree
|
||||
touched-layouts (d/ordered-set)]
|
||||
(if (some? current)
|
||||
(let [shape (get objects current)
|
||||
pending (concat pending (:shapes shape))
|
||||
|
||||
touched-layouts
|
||||
(cond-> touched-layouts
|
||||
(:layout shape)
|
||||
(conj (:id shape)))
|
||||
|
||||
modif-tree
|
||||
(-> modif-tree
|
||||
(set-children-modifiers shape objects ignore-constraints snap-pixel?))]
|
||||
|
||||
(recur (first pending) (rest pending) modif-tree touched-layouts))
|
||||
|
||||
[modif-tree touched-layouts]))
|
||||
|
||||
;; Second: Calculate layout positioning
|
||||
modif-tree
|
||||
(loop [current (first touched-layouts)
|
||||
pending (rest touched-layouts)
|
||||
modif-tree modif-tree]
|
||||
(->> shapes-tree
|
||||
(reduce
|
||||
(fn [modif-tree shape]
|
||||
(let [has-modifiers? (some? (get-in modif-tree [(:id shape) :modifiers]))
|
||||
is-layout? (layout? shape)
|
||||
is-parent? (or (group? shape) (and (frame? shape) (not (layout? shape))))
|
||||
|
||||
(if (some? current)
|
||||
(let [modif-tree (set-layout-modifiers modif-tree objects current)]
|
||||
(recur (first pending) (rest pending) modif-tree))
|
||||
modif-tree))]
|
||||
;; If the current child is inside the layout we ignore the constraints
|
||||
is-inside-layout? (inside-layout? objects shape)]
|
||||
|
||||
(cond-> modif-tree
|
||||
is-layout?
|
||||
(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))]
|
||||
|
||||
;;(.log js/console ">result" (modif->js modif-tree objects))
|
||||
modif-tree))
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
[app.common.geom.shapes.path :as gpa]
|
||||
[app.common.geom.shapes.rect :as gpr]
|
||||
[app.common.math :as mth]
|
||||
[app.common.spec :as us]
|
||||
[app.common.text :as txt]))
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.modifiers :as ctm]))
|
||||
|
||||
(def ^:dynamic *skip-adjust* false)
|
||||
|
||||
|
@ -76,14 +76,6 @@
|
|||
|
||||
; ---- Geometric operations
|
||||
|
||||
(defn- normalize-scale
|
||||
"We normalize the scale so it's not too close to 0"
|
||||
[scale]
|
||||
(cond
|
||||
(and (< scale 0) (> scale -0.01)) -0.01
|
||||
(and (>= scale 0) (< scale 0.01)) 0.01
|
||||
:else scale))
|
||||
|
||||
(defn- calculate-skew-angle
|
||||
"Calculates the skew angle of the parallelogram given by the points"
|
||||
[[p1 _ p3 p4]]
|
||||
|
@ -182,17 +174,6 @@
|
|||
(gmt/multiply (:transform-inverse shape (gmt/matrix)))
|
||||
(gmt/translate (gpt/negate center)))))
|
||||
|
||||
(defn transform-point-center
|
||||
"Transform a point around the shape center"
|
||||
[point center matrix]
|
||||
(if (and (some? point) (some? matrix) (some? center))
|
||||
(gpt/transform
|
||||
point
|
||||
(gmt/multiply (gmt/translate-matrix center)
|
||||
matrix
|
||||
(gmt/translate-matrix (gpt/negate center))))
|
||||
point))
|
||||
|
||||
(defn transform-rect
|
||||
"Transform a rectangles and changes its attributes"
|
||||
[rect matrix]
|
||||
|
@ -273,6 +254,30 @@
|
|||
(if transform (gmt/multiply transform matrix) matrix)
|
||||
(if transform-inverse (gmt/multiply matrix-inverse transform-inverse) matrix-inverse)]))
|
||||
|
||||
(defn- adjust-shape-flips
|
||||
"After some tranformations the flip-x/flip-y flags can change we need
|
||||
to check this before adjusting the selrect"
|
||||
[shape points]
|
||||
|
||||
(let [points' (:points shape)
|
||||
|
||||
xv1 (gpt/to-vec (nth points' 0) (nth points' 1))
|
||||
xv2 (gpt/to-vec (nth points 0) (nth points 1))
|
||||
dot-x (gpt/dot xv1 xv2)
|
||||
|
||||
yv1 (gpt/to-vec (nth points' 0) (nth points' 3))
|
||||
yv2 (gpt/to-vec (nth points 0) (nth points 3))
|
||||
dot-y (gpt/dot yv1 yv2)]
|
||||
|
||||
(cond-> shape
|
||||
(neg? dot-x)
|
||||
(-> (update :flip-x not)
|
||||
(update :rotation -))
|
||||
|
||||
(neg? dot-y)
|
||||
(-> (update :flip-y not)
|
||||
(update :rotation -)))))
|
||||
|
||||
(defn apply-transform
|
||||
"Given a new set of points transformed, set up the rectangle so it keeps
|
||||
its properties. We adjust de x,y,width,height and create a custom transform"
|
||||
|
@ -280,6 +285,7 @@
|
|||
|
||||
(let [points' (:points shape)
|
||||
points (gco/transform-points points' transform-mtx)
|
||||
shape (-> shape (adjust-shape-flips points))
|
||||
bool? (= (:type shape) :bool)
|
||||
path? (= (:type shape) :path)
|
||||
|
||||
|
@ -289,7 +295,6 @@
|
|||
base-rotation (or (:rotation shape) 0)
|
||||
modif-rotation (or (get-in shape [:modifiers :rotation]) 0)
|
||||
rotation (mod (+ base-rotation modif-rotation) 360)]
|
||||
|
||||
(-> shape
|
||||
(cond-> bool?
|
||||
(update :bool-content gpa/transform-content transform-mtx))
|
||||
|
@ -368,173 +373,8 @@
|
|||
(assoc :flip-x (-> mask :flip-x))
|
||||
(assoc :flip-y (-> mask :flip-y)))))
|
||||
|
||||
;; --- Modifiers
|
||||
|
||||
;; The `modifiers` structure contains a list of transformations to
|
||||
;; do make to a shape, in this order:
|
||||
;;
|
||||
;; - resize-origin (gpt/point) + resize-vector (gpt/point)
|
||||
;; apply a scale vector to all points of the shapes, starting
|
||||
;; from the origin point.
|
||||
;;
|
||||
;; - resize-origin-2 + resize-vector-2
|
||||
;; same as the previous one, for cases in that we need to make
|
||||
;; two vectors from different origin points.
|
||||
;;
|
||||
;; - displacement (gmt/matrix)
|
||||
;; apply a translation matrix to the shape
|
||||
;;
|
||||
;; - rotation (gmt/matrix)
|
||||
;; apply a rotation matrix to the shape
|
||||
;;
|
||||
;; - resize-transform (gmt/matrix) + resize-transform-inverse (gmt/matrix)
|
||||
;; a copy of the rotation matrix currently applied to the shape;
|
||||
;; this is needed temporarily to apply the resize vectors.
|
||||
;;
|
||||
;; - resize-scale-text (bool)
|
||||
;; tells if the resize vectors must be applied to text shapes
|
||||
;; or not.
|
||||
|
||||
(defn empty-modifiers? [modifiers]
|
||||
(empty? (dissoc modifiers :ignore-geometry?)))
|
||||
|
||||
(defn resize-modifiers
|
||||
[shape attr value]
|
||||
(us/assert map? shape)
|
||||
(us/assert #{:width :height} attr)
|
||||
(us/assert number? value)
|
||||
(let [{:keys [proportion proportion-lock]} shape
|
||||
size (select-keys (:selrect shape) [:width :height])
|
||||
new-size (if-not proportion-lock
|
||||
(assoc size attr value)
|
||||
(if (= attr :width)
|
||||
(-> size
|
||||
(assoc :width value)
|
||||
(assoc :height (/ value proportion)))
|
||||
(-> size
|
||||
(assoc :height value)
|
||||
(assoc :width (* value proportion)))))
|
||||
width (:width new-size)
|
||||
height (:height new-size)
|
||||
|
||||
shape-transform (:transform shape)
|
||||
shape-transform-inv (:transform-inverse shape)
|
||||
shape-center (gco/center-shape shape)
|
||||
{sr-width :width sr-height :height} (:selrect shape)
|
||||
|
||||
origin (cond-> (gpt/point (:selrect shape))
|
||||
(some? shape-transform)
|
||||
(transform-point-center shape-center shape-transform))
|
||||
|
||||
scalev (gpt/divide (gpt/point width height)
|
||||
(gpt/point sr-width sr-height))]
|
||||
{:resize-vector scalev
|
||||
:resize-origin origin
|
||||
:resize-transform shape-transform
|
||||
:resize-transform-inverse shape-transform-inv}))
|
||||
|
||||
(defn change-orientation-modifiers
|
||||
[shape orientation]
|
||||
(us/assert map? shape)
|
||||
(us/verify #{:horiz :vert} orientation)
|
||||
(let [width (:width shape)
|
||||
height (:height shape)
|
||||
new-width (if (= orientation :horiz) (max width height) (min width height))
|
||||
new-height (if (= orientation :horiz) (min width height) (max width height))
|
||||
|
||||
shape-transform (:transform shape)
|
||||
shape-transform-inv (:transform-inverse shape)
|
||||
shape-center (gco/center-shape shape)
|
||||
{sr-width :width sr-height :height} (:selrect shape)
|
||||
|
||||
origin (cond-> (gpt/point (:selrect shape))
|
||||
(some? shape-transform)
|
||||
(transform-point-center shape-center shape-transform))
|
||||
|
||||
scalev (gpt/divide (gpt/point new-width new-height)
|
||||
(gpt/point sr-width sr-height))]
|
||||
{:resize-vector scalev
|
||||
:resize-origin origin
|
||||
:resize-transform shape-transform
|
||||
:resize-transform-inverse shape-transform-inv}))
|
||||
|
||||
(defn rotation-modifiers
|
||||
[shape center angle]
|
||||
(let [displacement (let [shape-center (gco/center-shape shape)]
|
||||
(-> (gmt/matrix)
|
||||
(gmt/rotate angle center)
|
||||
(gmt/rotate (- angle) shape-center)))]
|
||||
{:rotation angle
|
||||
:displacement displacement}))
|
||||
|
||||
(defn merge-modifiers
|
||||
[objects modifiers]
|
||||
|
||||
(let [set-modifier
|
||||
(fn [objects [id modifiers]]
|
||||
(-> objects
|
||||
(d/update-when id merge modifiers)))]
|
||||
(->> modifiers
|
||||
(reduce set-modifier objects))))
|
||||
|
||||
(defn modifiers->transform
|
||||
([modifiers]
|
||||
(modifiers->transform nil modifiers))
|
||||
|
||||
([center modifiers]
|
||||
(let [displacement (:displacement modifiers)
|
||||
displacement-after (:displacement-after modifiers)
|
||||
resize-v1 (:resize-vector modifiers)
|
||||
resize-v2 (:resize-vector-2 modifiers)
|
||||
origin-1 (:resize-origin modifiers (gpt/point))
|
||||
origin-2 (:resize-origin-2 modifiers (gpt/point))
|
||||
|
||||
;; Normalize x/y vector coordinates because scale by 0 is infinite
|
||||
resize-1 (when (some? resize-v1)
|
||||
(gpt/point (normalize-scale (:x resize-v1))
|
||||
(normalize-scale (:y resize-v1))))
|
||||
|
||||
resize-2 (when (some? resize-v2)
|
||||
(gpt/point (normalize-scale (:x resize-v2))
|
||||
(normalize-scale (:y resize-v2))))
|
||||
|
||||
|
||||
resize-transform (:resize-transform modifiers)
|
||||
resize-transform-inverse (:resize-transform-inverse modifiers)
|
||||
|
||||
rt-modif (:rotation modifiers)]
|
||||
|
||||
(cond-> (gmt/matrix)
|
||||
(some? displacement-after)
|
||||
(gmt/multiply displacement-after)
|
||||
|
||||
(some? resize-1)
|
||||
(-> (gmt/translate origin-1)
|
||||
(cond-> (some? resize-transform)
|
||||
(gmt/multiply resize-transform))
|
||||
(gmt/scale resize-1)
|
||||
(cond-> (some? resize-transform-inverse)
|
||||
(gmt/multiply resize-transform-inverse))
|
||||
(gmt/translate (gpt/negate origin-1)))
|
||||
|
||||
(some? resize-2)
|
||||
(-> (gmt/translate origin-2)
|
||||
(cond-> (some? resize-transform)
|
||||
(gmt/multiply resize-transform))
|
||||
(gmt/scale resize-2)
|
||||
(cond-> (some? resize-transform-inverse)
|
||||
(gmt/multiply resize-transform-inverse))
|
||||
(gmt/translate (gpt/negate origin-2)))
|
||||
|
||||
(some? displacement)
|
||||
(gmt/multiply displacement)
|
||||
|
||||
(some? rt-modif)
|
||||
(-> (gmt/translate center)
|
||||
(gmt/multiply (gmt/rotate-matrix rt-modif))
|
||||
(gmt/translate (gpt/negate center)))))))
|
||||
|
||||
(defn- set-flip [shape modifiers]
|
||||
#_(defn- set-flip [shape modifiers]
|
||||
(let [rv1x (or (get-in modifiers [:resize-vector :x]) 1)
|
||||
rv1y (or (get-in modifiers [:resize-vector :y]) 1)
|
||||
rv2x (or (get-in modifiers [:resize-vector-2 :x]) 1)
|
||||
|
@ -547,7 +387,25 @@
|
|||
(-> (update :flip-y not)
|
||||
(update :rotation -)))))
|
||||
|
||||
(defn- apply-displacement [shape]
|
||||
#_(defn- set-flip-2 [shape transform]
|
||||
(let [pt-a (gpt/point (:selrect shape))
|
||||
pt-b (gpt/point (-> shape :selrect :x2) (-> shape :selrect :y2))
|
||||
|
||||
shape-transform (:transform shape (gmt/matrix))
|
||||
pt-a' (gpt/transform pt-a (gmt/multiply shape-transform transform ))
|
||||
pt-b' (gpt/transform pt-b (gmt/multiply shape-transform transform ))
|
||||
|
||||
{:keys [x y]} (gpt/to-vec pt-a' pt-b')]
|
||||
|
||||
(cond-> shape
|
||||
(neg? x)
|
||||
(-> (update :flip-x not)
|
||||
(update :rotation -))
|
||||
(neg? y)
|
||||
(-> (update :flip-y not)
|
||||
(update :rotation -)))))
|
||||
|
||||
#_(defn- apply-displacement [shape]
|
||||
(let [modifiers (:modifiers shape)]
|
||||
(if (contains? modifiers :displacement)
|
||||
(let [mov-vec (-> (gpt/point 0 0)
|
||||
|
@ -580,64 +438,87 @@
|
|||
(defn apply-modifiers
|
||||
[shape modifiers]
|
||||
(let [center (gco/center-shape shape)
|
||||
transform (modifiers->transform center modifiers)]
|
||||
(apply-transform shape transform)))
|
||||
transform (ctm/modifiers->transform center modifiers)]
|
||||
(-> shape
|
||||
#_(set-flip-2 transform)
|
||||
(apply-transform transform))))
|
||||
|
||||
(defn apply-objects-modifiers
|
||||
[objects modifiers]
|
||||
(letfn [(process-shape [objects [id modifier]]
|
||||
(update objects id apply-modifiers (:modifiers modifier)))]
|
||||
(reduce process-shape objects modifiers)))
|
||||
|
||||
(defn transform-shape
|
||||
[shape]
|
||||
(let [modifiers (:modifiers shape)]
|
||||
(cond
|
||||
(nil? modifiers)
|
||||
shape
|
||||
([shape]
|
||||
(let [modifiers (:modifiers shape)]
|
||||
(-> shape
|
||||
(dissoc :modifiers)
|
||||
(transform-shape modifiers))))
|
||||
|
||||
(empty-modifiers? modifiers)
|
||||
(dissoc shape :modifiers)
|
||||
([shape modifiers]
|
||||
(cond-> shape
|
||||
(and (some? modifiers) (not (ctm/empty-modifiers? modifiers)))
|
||||
(-> (apply-modifiers modifiers)
|
||||
(apply-text-resize modifiers)))))
|
||||
|
||||
:else
|
||||
(let [shape (apply-displacement shape)
|
||||
modifiers (:modifiers shape)]
|
||||
(cond-> shape
|
||||
(not (empty-modifiers? modifiers))
|
||||
(-> (set-flip modifiers)
|
||||
(apply-modifiers modifiers)
|
||||
(apply-text-resize modifiers))
|
||||
(defn transform-bounds-v2
|
||||
[points center modifiers]
|
||||
(let [transform (ctm/modifiers->transform center {:v2 modifiers})
|
||||
result (gco/transform-points points center transform)]
|
||||
|
||||
:always
|
||||
(dissoc :modifiers))))))
|
||||
;;(.log js/console "??" (str transform) (clj->js result))
|
||||
result)
|
||||
|
||||
#_(letfn [(apply-modifier [points {:keys [type vector origin]}]
|
||||
(case type
|
||||
:move
|
||||
(let [displacement (gmt/translate-matrix vector)]
|
||||
(gco/transform-points points displacement))
|
||||
|
||||
:resize
|
||||
(gco/transform-points points origin (gmt/scale-matrix vector))
|
||||
|
||||
points))]
|
||||
(->> modifiers
|
||||
(reduce apply-modifier points))))
|
||||
|
||||
(defn transform-bounds
|
||||
[points center {:keys [displacement displacement-after resize-transform-inverse resize-vector resize-origin resize-vector-2 resize-origin-2]}]
|
||||
[points center {:keys [v2 displacement displacement-after resize-transform-inverse resize-vector resize-origin resize-vector-2 resize-origin-2]}]
|
||||
|
||||
;; FIXME: Improve Performance
|
||||
(let [resize-transform-inverse (or resize-transform-inverse (gmt/matrix))
|
||||
(if (some? v2)
|
||||
(transform-bounds-v2 points center v2)
|
||||
(let [resize-transform-inverse (or resize-transform-inverse (gmt/matrix))
|
||||
|
||||
displacement
|
||||
(when (some? displacement)
|
||||
(gmt/multiply resize-transform-inverse displacement))
|
||||
displacement
|
||||
(when (some? displacement)
|
||||
(gmt/multiply resize-transform-inverse displacement))
|
||||
|
||||
resize-origin
|
||||
(when (some? resize-origin)
|
||||
(transform-point-center resize-origin center resize-transform-inverse))
|
||||
resize-origin
|
||||
(when (some? resize-origin)
|
||||
(gmt/transform-point-center resize-origin center resize-transform-inverse))
|
||||
|
||||
resize-origin-2
|
||||
(when (some? resize-origin-2)
|
||||
(transform-point-center resize-origin-2 center resize-transform-inverse))
|
||||
]
|
||||
resize-origin-2
|
||||
(when (some? resize-origin-2)
|
||||
(gmt/transform-point-center resize-origin-2 center resize-transform-inverse))
|
||||
]
|
||||
|
||||
(if (and (nil? displacement) (nil? resize-origin) (nil? resize-origin-2) (nil? displacement-after))
|
||||
points
|
||||
(if (and (nil? displacement) (nil? resize-origin) (nil? resize-origin-2) (nil? displacement-after))
|
||||
points
|
||||
|
||||
(cond-> points
|
||||
(some? displacement)
|
||||
(gco/transform-points displacement)
|
||||
(cond-> points
|
||||
(some? displacement)
|
||||
(gco/transform-points displacement)
|
||||
|
||||
(some? resize-origin)
|
||||
(gco/transform-points resize-origin (gmt/scale-matrix resize-vector))
|
||||
(some? resize-origin)
|
||||
(gco/transform-points resize-origin (gmt/scale-matrix resize-vector))
|
||||
|
||||
(some? resize-origin-2)
|
||||
(gco/transform-points resize-origin-2 (gmt/scale-matrix resize-vector-2))
|
||||
(some? resize-origin-2)
|
||||
(gco/transform-points resize-origin-2 (gmt/scale-matrix resize-vector-2))
|
||||
|
||||
(some? displacement-after)
|
||||
(gco/transform-points displacement-after)))))
|
||||
(some? displacement-after)
|
||||
(gco/transform-points displacement-after))))))
|
||||
|
||||
(defn transform-selrect
|
||||
[selrect modifiers]
|
||||
|
|
|
@ -102,13 +102,7 @@
|
|||
(fix-frames-selrects)
|
||||
|
||||
(and (empty? (:points object)) (not= (:id object) uuid/zero))
|
||||
(fix-empty-points)
|
||||
|
||||
;; Setup an empty transformation to re-calculate selrects
|
||||
;; and points data
|
||||
:always
|
||||
(-> (assoc :modifiers {:displacement (gmt/matrix)})
|
||||
(gsh/transform-shape))))
|
||||
(fix-empty-points)))
|
||||
|
||||
(update-page [page]
|
||||
(update page :objects d/update-vals update-object))]
|
||||
|
|
256
common/src/app/common/types/modifiers.cljc
Normal file
256
common/src/app/common/types/modifiers.cljc
Normal file
|
@ -0,0 +1,256 @@
|
|||
;; 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.types.modifiers
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
[app.common.spec :as us]))
|
||||
|
||||
;; --- Modifiers
|
||||
|
||||
;; The `modifiers` structure contains a list of transformations to
|
||||
;; do make to a shape, in this order:
|
||||
;;
|
||||
;; - resize-origin (gpt/point) + resize-vector (gpt/point)q
|
||||
;; apply a scale vector to all points of the shapes, starting
|
||||
;; from the origin point.
|
||||
;;
|
||||
;; - resize-origin-2 + resize-vector-2
|
||||
;; same as the previous one, for cases in that we need to make
|
||||
;; two vectors from different origin points.
|
||||
;;
|
||||
;; - displacement (gmt/matrix)
|
||||
;; apply a translation matrix to the shape
|
||||
;;
|
||||
;; - rotation (gmt/matrix)
|
||||
;; apply a rotation matrix to the shape
|
||||
;;
|
||||
;; - resize-transform (gmt/matrix) + resize-transform-inverse (gmt/matrix)
|
||||
;; a copy of the rotation matrix currently applied to the shape;
|
||||
;; this is needed temporarily to apply the resize vectors.
|
||||
;;
|
||||
;; - resize-scale-text (bool)
|
||||
;; tells if the resize vectors must be applied to text shapes
|
||||
;; or not.
|
||||
|
||||
(defn move
|
||||
([x y]
|
||||
(move (gpt/point x y)))
|
||||
|
||||
([vector]
|
||||
{:v2 [{:type :move :vector vector}]}))
|
||||
|
||||
(defn resize
|
||||
[vector origin]
|
||||
{:v2 [{:type :resize :vector vector :origin origin}]})
|
||||
|
||||
(defn add-move
|
||||
([object x y]
|
||||
(add-move object (gpt/point x y)))
|
||||
|
||||
([object vector]
|
||||
(assoc-in
|
||||
object
|
||||
[:modifiers :displacement]
|
||||
(gmt/translate-matrix (:x vector) (:y vector)))))
|
||||
|
||||
(defn add-resize
|
||||
[object vector origin]
|
||||
(-> object
|
||||
(assoc-in [:modifiers :resize-vector] vector)
|
||||
(assoc-in [:modifiers :resize-origin] origin)))
|
||||
|
||||
(defn empty-modifiers? [modifiers]
|
||||
(empty? (dissoc modifiers :ignore-geometry?)))
|
||||
|
||||
(defn resize-modifiers
|
||||
[shape attr value]
|
||||
(us/assert map? shape)
|
||||
(us/assert #{:width :height} attr)
|
||||
(us/assert number? value)
|
||||
(let [{:keys [proportion proportion-lock]} shape
|
||||
size (select-keys (:selrect shape) [:width :height])
|
||||
new-size (if-not proportion-lock
|
||||
(assoc size attr value)
|
||||
(if (= attr :width)
|
||||
(-> size
|
||||
(assoc :width value)
|
||||
(assoc :height (/ value proportion)))
|
||||
(-> size
|
||||
(assoc :height value)
|
||||
(assoc :width (* value proportion)))))
|
||||
width (:width new-size)
|
||||
height (:height new-size)
|
||||
|
||||
shape-transform (:transform shape)
|
||||
shape-transform-inv (:transform-inverse shape)
|
||||
shape-center (gco/center-shape shape)
|
||||
{sr-width :width sr-height :height} (:selrect shape)
|
||||
|
||||
origin (cond-> (gpt/point (:selrect shape))
|
||||
(some? shape-transform)
|
||||
(gmt/transform-point-center shape-center shape-transform))
|
||||
|
||||
scalev (gpt/divide (gpt/point width height)
|
||||
(gpt/point sr-width sr-height))]
|
||||
{:resize-vector scalev
|
||||
:resize-origin origin
|
||||
:resize-transform shape-transform
|
||||
:resize-transform-inverse shape-transform-inv}))
|
||||
|
||||
(defn change-orientation-modifiers
|
||||
[shape orientation]
|
||||
(us/assert map? shape)
|
||||
(us/verify #{:horiz :vert} orientation)
|
||||
(let [width (:width shape)
|
||||
height (:height shape)
|
||||
new-width (if (= orientation :horiz) (max width height) (min width height))
|
||||
new-height (if (= orientation :horiz) (min width height) (max width height))
|
||||
|
||||
shape-transform (:transform shape)
|
||||
shape-transform-inv (:transform-inverse shape)
|
||||
shape-center (gco/center-shape shape)
|
||||
{sr-width :width sr-height :height} (:selrect shape)
|
||||
|
||||
origin (cond-> (gpt/point (:selrect shape))
|
||||
(some? shape-transform)
|
||||
(gmt/transform-point-center shape-center shape-transform))
|
||||
|
||||
scalev (gpt/divide (gpt/point new-width new-height)
|
||||
(gpt/point sr-width sr-height))]
|
||||
{:resize-vector scalev
|
||||
:resize-origin origin
|
||||
:resize-transform shape-transform
|
||||
:resize-transform-inverse shape-transform-inv}))
|
||||
|
||||
(defn rotation-modifiers
|
||||
[shape center angle]
|
||||
(let [shape-center (gco/center-shape shape)
|
||||
rotation (-> (gmt/matrix)
|
||||
(gmt/rotate angle center)
|
||||
(gmt/rotate (- angle) shape-center))]
|
||||
|
||||
{:v2 [{:type :rotation
|
||||
:center shape-center
|
||||
:rotation angle}
|
||||
|
||||
{:type :move
|
||||
:vector (gpt/transform (gpt/point 1 1) rotation)}]}
|
||||
#_{:rotation angle
|
||||
:displacement displacement}))
|
||||
|
||||
(defn merge-modifiers
|
||||
[objects modifiers]
|
||||
|
||||
(let [set-modifier
|
||||
(fn [objects [id modifiers]]
|
||||
(-> objects
|
||||
(d/update-when id merge modifiers)))]
|
||||
(->> modifiers
|
||||
(reduce set-modifier objects))))
|
||||
|
||||
(defn modifiers-v2->transform
|
||||
[modifiers]
|
||||
(letfn [(apply-modifier [matrix {:keys [type vector rotation center origin transform transform-inverse] :as modifier}]
|
||||
(case type
|
||||
:move
|
||||
(gmt/multiply (gmt/translate-matrix vector) matrix)
|
||||
|
||||
;;:transform
|
||||
;;(gmt/multiply transform 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)
|
||||
|
||||
:rotation
|
||||
;; TODO LAYOUT: Comprobar que pasa si no hay centro
|
||||
(gmt/multiply
|
||||
(-> (gmt/matrix)
|
||||
(gmt/translate center)
|
||||
(gmt/multiply (gmt/rotate-matrix rotation))
|
||||
(gmt/translate (gpt/negate center)))
|
||||
matrix)))]
|
||||
(->> modifiers
|
||||
(reduce apply-modifier (gmt/matrix)))))
|
||||
|
||||
(defn- normalize-scale
|
||||
"We normalize the scale so it's not too close to 0"
|
||||
[scale]
|
||||
(cond
|
||||
(and (< scale 0) (> scale -0.01)) -0.01
|
||||
(and (>= scale 0) (< scale 0.01)) 0.01
|
||||
:else scale))
|
||||
|
||||
(defn modifiers->transform
|
||||
([modifiers]
|
||||
(modifiers->transform nil modifiers))
|
||||
|
||||
([center modifiers]
|
||||
(if (some? (:v2 modifiers))
|
||||
(modifiers-v2->transform (:v2 modifiers))
|
||||
(let [displacement (:displacement modifiers)
|
||||
displacement-after (:displacement-after modifiers)
|
||||
resize-v1 (:resize-vector modifiers)
|
||||
resize-v2 (:resize-vector-2 modifiers)
|
||||
origin-1 (:resize-origin modifiers (gpt/point))
|
||||
origin-2 (:resize-origin-2 modifiers (gpt/point))
|
||||
|
||||
;; Normalize x/y vector coordinates because scale by 0 is infinite
|
||||
resize-1 (when (some? resize-v1)
|
||||
(gpt/point (normalize-scale (:x resize-v1))
|
||||
(normalize-scale (:y resize-v1))))
|
||||
|
||||
resize-2 (when (some? resize-v2)
|
||||
(gpt/point (normalize-scale (:x resize-v2))
|
||||
(normalize-scale (:y resize-v2))))
|
||||
|
||||
resize-transform (:resize-transform modifiers)
|
||||
resize-transform-inverse (:resize-transform-inverse modifiers)
|
||||
|
||||
rt-modif (:rotation modifiers)]
|
||||
|
||||
(cond-> (gmt/matrix)
|
||||
(some? displacement-after)
|
||||
(gmt/multiply displacement-after)
|
||||
|
||||
(some? resize-1)
|
||||
(-> (gmt/translate origin-1)
|
||||
(cond-> (some? resize-transform)
|
||||
(gmt/multiply resize-transform))
|
||||
(gmt/scale resize-1)
|
||||
(cond-> (some? resize-transform-inverse)
|
||||
(gmt/multiply resize-transform-inverse))
|
||||
(gmt/translate (gpt/negate origin-1)))
|
||||
|
||||
(some? resize-2)
|
||||
(-> (gmt/translate origin-2)
|
||||
(cond-> (some? resize-transform)
|
||||
(gmt/multiply resize-transform))
|
||||
(gmt/scale resize-2)
|
||||
(cond-> (some? resize-transform-inverse)
|
||||
(gmt/multiply resize-transform-inverse))
|
||||
(gmt/translate (gpt/negate origin-2)))
|
||||
|
||||
(some? displacement)
|
||||
(gmt/multiply displacement)
|
||||
|
||||
(some? rt-modif)
|
||||
(-> (gmt/translate center)
|
||||
(gmt/multiply (gmt/rotate-matrix rt-modif))
|
||||
(gmt/translate (gpt/negate center))))))
|
||||
))
|
|
@ -159,8 +159,8 @@
|
|||
build-move-event
|
||||
(fn [comment-thread]
|
||||
(let [frame (get objects (:frame-id comment-thread))
|
||||
frame' (-> (merge frame (get object-modifiers (:frame-id comment-thread)))
|
||||
(gsh/transform-shape))
|
||||
modifiers (get object-modifiers (:frame-id comment-thread))
|
||||
frame' (gsh/transform-shape frame modifiers)
|
||||
moved (gpt/to-vec (gpt/point (:x frame) (:y frame))
|
||||
(gpt/point (:x frame') (:y frame')))
|
||||
position (get-in threads-position-map [(:id comment-thread) :position])
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.uuid :as uuid]
|
||||
|
@ -37,9 +38,7 @@
|
|||
scalev)]
|
||||
(-> shape
|
||||
(assoc :click-draw? false)
|
||||
(assoc-in [:modifiers :resize-vector] scalev)
|
||||
(assoc-in [:modifiers :resize-origin] (gpt/point x y))
|
||||
(assoc-in [:modifiers :resize-rotation] 0))))
|
||||
(gsh/transform-shape (ctm/resize scalev (gpt/point x y))))))
|
||||
|
||||
(defn update-drawing [state point lock?]
|
||||
(update-in state [:workspace-drawing :object] resize-shape point lock?))
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
(ns app.main.data.workspace.drawing.common
|
||||
(:require
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
|
@ -51,8 +51,8 @@
|
|||
|
||||
(and click-draw? (not text?))
|
||||
(-> (assoc :width min-side :height min-side)
|
||||
(assoc-in [:modifiers :displacement]
|
||||
(gmt/translate-matrix (- (/ min-side 2)) (- (/ min-side 2)))))
|
||||
(gsh/transform-shape (ctm/move (- (/ min-side 2)) (- (/ min-side 2))))
|
||||
#_(ctm/add-move (- (/ min-side 2)) (- (/ min-side 2))))
|
||||
|
||||
(and click-draw? text?)
|
||||
(assoc :height 17 :width 4 :grow-type :auto-width)
|
||||
|
@ -61,8 +61,7 @@
|
|||
(cts/setup-rect-selrect)
|
||||
|
||||
:always
|
||||
(-> (gsh/transform-shape)
|
||||
(dissoc :initialized? :click-draw?)))]
|
||||
(dissoc :initialized? :click-draw?))]
|
||||
;; Add & select the created shape to the workspace
|
||||
(rx/concat
|
||||
(if (= :text (:type shape))
|
||||
|
|
|
@ -79,8 +79,7 @@
|
|||
build-move-event
|
||||
(fn [guide]
|
||||
(let [frame (get objects (:frame-id guide))
|
||||
frame' (-> (merge frame (get object-modifiers (:frame-id guide)))
|
||||
(gsh/transform-shape))
|
||||
frame' (gsh/transform-shape (get object-modifiers (:frame-id guide)))
|
||||
|
||||
moved (gpt/to-vec (gpt/point (:x frame) (:y frame))
|
||||
(gpt/point (:x frame') (:y frame')))
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
(dwt/apply-modifiers))
|
||||
(rx/empty))))))
|
||||
|
||||
;; TODO: Remove constraints from children
|
||||
;; TODO LAYOUT: Remove constraints from children
|
||||
(defn create-layout
|
||||
[ids type]
|
||||
(ptk/reify ::create-layout
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.path.commands :as upc]))
|
||||
[app.common.path.commands :as upc]
|
||||
[app.common.types.modifiers :as ctm]))
|
||||
|
||||
(defn lookup-page
|
||||
([state]
|
||||
|
@ -137,5 +137,6 @@
|
|||
children (select-keys objects children-ids)]
|
||||
|
||||
(as-> children $
|
||||
(gsh/merge-modifiers $ modifiers)
|
||||
;; TODO LAYOUT: REVIEW THIS
|
||||
(ctm/merge-modifiers $ modifiers)
|
||||
(d/mapm (set-content-modifiers state) $))))
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[app.common.math :as mth]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
|
@ -319,17 +320,16 @@
|
|||
(letfn [(update-fn [shape]
|
||||
(let [{:keys [selrect grow-type]} shape
|
||||
{shape-width :width shape-height :height} selrect
|
||||
modifier-width (gsh/resize-modifiers shape :width new-width)
|
||||
modifier-height (gsh/resize-modifiers shape :height new-height)]
|
||||
modifier-width (ctm/resize-modifiers shape :width new-width)
|
||||
modifier-height (ctm/resize-modifiers shape :height new-height)]
|
||||
;; TODO LAYOUT: MEZCLAR ESTOS EN UN UNICO MODIFIER
|
||||
(cond-> shape
|
||||
(and (not-changed? shape-width new-width) (= grow-type :auto-width))
|
||||
(-> (assoc :modifiers modifier-width)
|
||||
(gsh/transform-shape))
|
||||
(gsh/transform-shape modifier-width)
|
||||
|
||||
(and (not-changed? shape-height new-height)
|
||||
(or (= grow-type :auto-height) (= grow-type :auto-width)))
|
||||
(-> (assoc :modifiers modifier-height)
|
||||
(gsh/transform-shape)))))]
|
||||
(gsh/transform-shape modifier-height))))]
|
||||
|
||||
(rx/of (dch/update-shapes [id] update-fn {:reg-objects? true :save-undo? false}))))))
|
||||
|
||||
|
@ -346,18 +346,17 @@
|
|||
(defn apply-text-modifier
|
||||
[shape {:keys [width height position-data]}]
|
||||
|
||||
(let [modifier-width (when width (gsh/resize-modifiers shape :width width))
|
||||
modifier-height (when height (gsh/resize-modifiers shape :height height))
|
||||
(let [modifier-width (when width (ctm/resize-modifiers shape :width width))
|
||||
modifier-height (when height (ctm/resize-modifiers shape :height height))
|
||||
|
||||
;; TODO LAYOUT: MEZCLAR LOS DOS EN UN UNICO MODIFIER
|
||||
new-shape
|
||||
(cond-> shape
|
||||
(some? modifier-width)
|
||||
(-> (assoc :modifiers modifier-width)
|
||||
(gsh/transform-shape))
|
||||
(gsh/transform-shape modifier-width)
|
||||
|
||||
(some? modifier-height)
|
||||
(-> (assoc :modifiers modifier-height)
|
||||
(gsh/transform-shape))
|
||||
(gsh/transform-shape modifier-height)
|
||||
|
||||
(some? position-data)
|
||||
(assoc :position-data position-data))
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
[app.common.pages.common :as cpc]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.collapse :as dwc]
|
||||
|
@ -154,14 +155,14 @@
|
|||
ids
|
||||
(->> shapes
|
||||
(remove #(get % :blocked false))
|
||||
(mapcat #(cph/get-children objects (:id %)))
|
||||
(concat shapes)
|
||||
#_(mapcat #(cph/get-children objects (:id %)))
|
||||
#_(concat shapes)
|
||||
(filter #((cpc/editable-attrs (:type %)) :rotation))
|
||||
(map :id))
|
||||
|
||||
get-modifier
|
||||
(fn [shape]
|
||||
(gsh/rotation-modifiers shape center angle))
|
||||
(ctm/rotation-modifiers shape center angle))
|
||||
|
||||
modif-tree
|
||||
(gsh/set-objects-modifiers ids objects get-modifier false false)]
|
||||
|
@ -193,7 +194,7 @@
|
|||
(let [objects (wsh/lookup-page-objects state)
|
||||
object-modifiers (get state :workspace-modifiers)
|
||||
|
||||
ids (keys object-modifiers)
|
||||
ids (or (keys object-modifiers) [])
|
||||
ids-with-children (into (vec ids) (mapcat #(cph/get-children-ids objects %)) ids)
|
||||
|
||||
shapes (map (d/getf objects) ids)
|
||||
|
@ -209,11 +210,10 @@
|
|||
(dch/update-shapes
|
||||
ids
|
||||
(fn [shape]
|
||||
(let [modif (get object-modifiers (:id shape))
|
||||
(let [modif (get-in object-modifiers [(:id shape) :modifiers])
|
||||
text-shape? (cph/text-shape? shape)]
|
||||
(-> shape
|
||||
(merge modif)
|
||||
(gsh/transform-shape)
|
||||
(gsh/transform-shape modif)
|
||||
(cond-> text-shape?
|
||||
(update-grow-type shape)))))
|
||||
{:reg-objects? true
|
||||
|
@ -295,7 +295,7 @@
|
|||
(let [children (map (d/getf objects) (:shapes shape))
|
||||
|
||||
shape-id (:id shape)
|
||||
transformed-shape (gsh/transform-shape (merge shape (get modif-tree shape-id)))
|
||||
transformed-shape (gsh/transform-shape shape (get modif-tree shape-id))
|
||||
|
||||
[root transformed-root ignore-geometry?]
|
||||
(check-delta shape root transformed-shape transformed-root objects modif-tree)
|
||||
|
@ -331,10 +331,10 @@
|
|||
|
||||
rotation (or rotation 0)
|
||||
|
||||
initial (gsh/transform-point-center initial shape-center shape-transform-inverse)
|
||||
initial (gmt/transform-point-center initial shape-center shape-transform-inverse)
|
||||
initial (fix-init-point initial handler shape)
|
||||
|
||||
point (gsh/transform-point-center (if (= rotation 0) point-snap point)
|
||||
point (gmt/transform-point-center (if (= rotation 0) point-snap point)
|
||||
shape-center shape-transform-inverse)
|
||||
|
||||
shapev (-> (gpt/point width height))
|
||||
|
@ -381,14 +381,28 @@
|
|||
(gpt/transform shape-transform)))
|
||||
|
||||
resize-origin
|
||||
(cond-> (gsh/transform-point-center handler-origin shape-center shape-transform)
|
||||
(cond-> (gmt/transform-point-center handler-origin shape-center shape-transform)
|
||||
(some? displacement)
|
||||
(gpt/add displacement))
|
||||
|
||||
displacement (when (some? displacement)
|
||||
(gmt/translate-matrix displacement))]
|
||||
(gpt/add displacement))]
|
||||
|
||||
(rx/of (set-modifiers ids
|
||||
{:v2 (-> []
|
||||
(cond-> displacement
|
||||
(conj {:type :move
|
||||
:vector displacement}))
|
||||
(conj {:type :resize
|
||||
:vector scalev
|
||||
:origin resize-origin
|
||||
:transform shape-transform
|
||||
:transform-inverse shape-transform-inverse}))
|
||||
;;:displacement displacement
|
||||
;;:resize-vector scalev
|
||||
;;:resize-origin resize-origin
|
||||
;;:resize-transform shape-transform
|
||||
;;:resize-scale-text scale-text
|
||||
;;:resize-transform-inverse shape-transform-inverse
|
||||
}))
|
||||
#_(rx/of (set-modifiers ids
|
||||
{:displacement displacement
|
||||
:resize-vector scalev
|
||||
:resize-origin resize-origin
|
||||
|
@ -444,7 +458,7 @@
|
|||
snap-pixel? (and (contains? (:workspace-layout state) :snap-pixel-grid)
|
||||
(int? value))
|
||||
get-modifier
|
||||
(fn [shape] (gsh/resize-modifiers shape attr value))
|
||||
(fn [shape] (ctm/resize-modifiers shape attr value))
|
||||
|
||||
modif-tree
|
||||
(gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)]
|
||||
|
@ -468,7 +482,7 @@
|
|||
snap-pixel? (contains? (get state :workspace-layout) :snap-pixel-grid)
|
||||
|
||||
get-modifier
|
||||
(fn [shape] (gsh/change-orientation-modifiers shape orientation))
|
||||
(fn [shape] (ctm/change-orientation-modifiers shape orientation))
|
||||
|
||||
modif-tree
|
||||
(gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)]
|
||||
|
@ -655,7 +669,10 @@
|
|||
(rx/with-latest vector snap-delta)
|
||||
;; We try to use the previous snap so we don't have to wait for the result of the new
|
||||
(rx/map snap/correct-snap-point)
|
||||
(rx/map #(hash-map :displacement (gmt/translate-matrix %)))
|
||||
|
||||
#_(rx/map #(hash-map :displacement (gmt/translate-matrix %)))
|
||||
(rx/map #(array-map :v2 [{:type :move :vector %}]))
|
||||
|
||||
(rx/map (partial set-modifiers ids))
|
||||
(rx/take-until stopper))
|
||||
|
||||
|
@ -704,7 +721,7 @@
|
|||
(rx/merge
|
||||
(->> move-events
|
||||
(rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0))
|
||||
(rx/map #(hash-map :displacement (gmt/translate-matrix %)))
|
||||
(rx/map #(ctm/move %))
|
||||
(rx/map (partial set-modifiers selected))
|
||||
(rx/take-until stopper))
|
||||
(rx/of (move-selected direction shift?)))
|
||||
|
@ -735,11 +752,11 @@
|
|||
cpos (gpt/point (:x bbox) (:y bbox))
|
||||
pos (gpt/point (or (:x position) (:x bbox))
|
||||
(or (:y position) (:y bbox)))
|
||||
delta (gpt/subtract pos cpos)
|
||||
displ (gmt/translate-matrix delta)]
|
||||
delta (gpt/subtract pos cpos)]
|
||||
|
||||
(rx/of (set-modifiers [id] {:displacement displ} false true)
|
||||
(apply-modifiers [id]))))))
|
||||
(rx/of
|
||||
(set-modifiers [id] (ctm/move delta))
|
||||
(apply-modifiers [id]))))))
|
||||
|
||||
(defn- calculate-frame-for-move
|
||||
[ids]
|
||||
|
@ -787,11 +804,16 @@
|
|||
(let [objects (wsh/lookup-page-objects state)
|
||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/selection-rect (->> shapes (map gsh/transform-shape)))
|
||||
selrect (gsh/selection-rect shapes)
|
||||
origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2)))]
|
||||
|
||||
(rx/of (set-modifiers selected
|
||||
{:resize-vector (gpt/point -1.0 1.0)
|
||||
{:v2 [{:type :resize
|
||||
:vector (gpt/point -1.0 1.0)
|
||||
:origin origin}
|
||||
{:type :move
|
||||
:vector (gpt/point (:width selrect) 0)}]}
|
||||
#_{:resize-vector (gpt/point -1.0 1.0)
|
||||
:resize-origin origin
|
||||
:displacement (gmt/translate-matrix (gpt/point (- (:width selrect)) 0))}
|
||||
true)
|
||||
|
@ -804,11 +826,16 @@
|
|||
(let [objects (wsh/lookup-page-objects state)
|
||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/selection-rect (->> shapes (map gsh/transform-shape)))
|
||||
selrect (gsh/selection-rect shapes)
|
||||
origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect))]
|
||||
|
||||
(rx/of (set-modifiers selected
|
||||
{:resize-vector (gpt/point 1.0 -1.0)
|
||||
{:v2 [{:type :resize
|
||||
:vector (gpt/point 1.0 -1.0)
|
||||
:origin origin}
|
||||
{:type :move
|
||||
:vector (gpt/point 0 (:height selrect))}]}
|
||||
#_{:resize-vector (gpt/point 1.0 -1.0)
|
||||
:resize-origin origin
|
||||
:displacement (gmt/translate-matrix (gpt/point 0 (- (:height selrect))))}
|
||||
true)
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
["react-dom/server" :as rds]
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.bounds :as gsb]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.config :as cfg]
|
||||
[app.main.fonts :as fonts]
|
||||
|
@ -82,7 +82,8 @@
|
|||
|
||||
(let [render-thumbnails? (mf/use-ctx muc/render-thumbnails)
|
||||
childs (mapv #(get objects %) (:shapes shape))
|
||||
shape (gsh/transform-shape shape)]
|
||||
;;shape (gsh/transform-shape shape)
|
||||
]
|
||||
(if (and render-thumbnails? (some? (:thumbnail shape)))
|
||||
[:& frame/frame-thumbnail {:shape shape :bounds (:children-bounds shape)}]
|
||||
[:& frame-shape {:shape shape :childs childs}])))))
|
||||
|
@ -135,7 +136,7 @@
|
|||
bool-wrapper (mf/use-memo (mf/deps objects) #(bool-wrapper-factory objects))
|
||||
frame-wrapper (mf/use-memo (mf/deps objects) #(frame-wrapper-factory objects))]
|
||||
(when (and shape (not (:hidden shape)))
|
||||
(let [shape (gsh/transform-shape shape)
|
||||
(let [;;shape (gsh/transform-shape shape)
|
||||
opts #js {:shape shape}
|
||||
svg-raw? (= :svg-raw (:type shape))]
|
||||
(if-not svg-raw?
|
||||
|
@ -167,7 +168,8 @@
|
|||
(let [shapes (cph/get-immediate-children objects)
|
||||
srect (gsh/selection-rect shapes)
|
||||
object (merge object (select-keys srect [:x :y :width :height]))
|
||||
object (gsh/transform-shape object)]
|
||||
;; object (gsh/transform-shape object)
|
||||
]
|
||||
(assoc object :fill-color "#f0f0f0")))
|
||||
|
||||
(defn adapt-objects-for-shape
|
||||
|
@ -180,14 +182,12 @@
|
|||
;; Replace the previous object with the new one
|
||||
objects (assoc objects object-id object)
|
||||
|
||||
modifier (-> (gpt/point (:x object) (:y object))
|
||||
(gpt/negate)
|
||||
(gmt/translate-matrix))
|
||||
vector (-> (gpt/point (:x object) (:y object))
|
||||
(gpt/negate))
|
||||
|
||||
mod-ids (cons object-id (cph/get-children-ids objects object-id))
|
||||
updt-fn #(-> %1
|
||||
(assoc-in [%2 :modifiers :displacement] modifier)
|
||||
(update %2 gsh/transform-shape))]
|
||||
|
||||
updt-fn #(update %1 %2 gsh/transform-shape (ctm/move vector))]
|
||||
|
||||
(reduce updt-fn objects mod-ids)))
|
||||
|
||||
|
@ -247,24 +247,21 @@
|
|||
bounds2 (gsb/get-object-bounds objects (dissoc frame :shadow :blur))
|
||||
|
||||
delta-bounds (gpt/point (:x bounds) (:y bounds))
|
||||
|
||||
modifier (gmt/translate-matrix (gpt/negate delta-bounds))
|
||||
vector (gpt/negate delta-bounds)
|
||||
|
||||
children-ids
|
||||
(cph/get-children-ids objects frame-id)
|
||||
|
||||
objects
|
||||
(mf/with-memo [frame-id objects modifier]
|
||||
(let [update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)]
|
||||
(mf/with-memo [frame-id objects vector]
|
||||
(let [update-fn #(update-in %1 %2 ctm/add-move vector)]
|
||||
(->> children-ids
|
||||
(into [frame-id])
|
||||
(reduce update-fn objects))))
|
||||
|
||||
frame
|
||||
(mf/with-memo [modifier]
|
||||
(-> frame
|
||||
(assoc-in [:modifiers :displacement] modifier)
|
||||
(gsh/transform-shape)))
|
||||
(mf/with-memo [vector]
|
||||
(gsh/transform-shape frame (ctm/move vector)))
|
||||
|
||||
frame
|
||||
(cond-> frame
|
||||
|
@ -305,22 +302,21 @@
|
|||
(let [group-id (:id group)
|
||||
include-metadata? (mf/use-ctx export/include-metadata-ctx)
|
||||
|
||||
modifier
|
||||
vector
|
||||
(mf/use-memo
|
||||
(mf/deps (:x group) (:y group))
|
||||
(fn []
|
||||
(-> (gpt/point (:x group) (:y group))
|
||||
(gpt/negate)
|
||||
(gmt/translate-matrix))))
|
||||
(gpt/negate))))
|
||||
|
||||
objects
|
||||
(mf/use-memo
|
||||
(mf/deps modifier objects group-id)
|
||||
(mf/deps vector objects group-id)
|
||||
(fn []
|
||||
(let [modifier-ids (cons group-id (cph/get-children-ids objects group-id))
|
||||
update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)
|
||||
update-fn #(update %1 %2 ctm/add-move vector)
|
||||
modifiers (reduce update-fn {} modifier-ids)]
|
||||
(gsh/merge-modifiers objects modifiers))))
|
||||
(ctm/merge-modifiers objects modifiers))))
|
||||
|
||||
group (get objects group-id)
|
||||
width (* (:width group) zoom)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
(ns app.main.ui.shapes.bool
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.main.ui.hooks :refer [use-equal-memo]]
|
||||
|
@ -15,6 +14,7 @@
|
|||
[app.util.object :as obj]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
;; TODO LAYOUT: REVIEW DYNAMIC CHANGES IN BOOLEANS
|
||||
(defn bool-shape
|
||||
[shape-wrapper]
|
||||
(mf/fnc bool-shape
|
||||
|
@ -35,7 +35,7 @@
|
|||
|
||||
(some? childs)
|
||||
(->> childs
|
||||
(d/mapm #(gsh/transform-shape %2))
|
||||
#_(d/mapm #(gsh/transform-shape %2))
|
||||
(gsh/calc-bool-content shape)))))]
|
||||
|
||||
[:*
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
(ns app.main.ui.shapes.mask
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.main.ui.context :as muc]
|
||||
[cuerdas.core :as str]
|
||||
|
@ -50,9 +51,7 @@
|
|||
render-id (mf/use-ctx muc/render-id)
|
||||
svg-text? (and (= :text (:type mask)) (some? (:position-data mask)))
|
||||
|
||||
mask-bb (-> (gsh/transform-shape mask)
|
||||
(:points))
|
||||
|
||||
mask-bb (:points mask)
|
||||
mask-bb-rect (gsh/points->rect mask-bb)]
|
||||
[:defs
|
||||
[:filter {:id (filter-id render-id mask)}
|
||||
|
@ -68,7 +67,7 @@
|
|||
[:clipPath {:class "mask-clip-path"
|
||||
:id (clip-id render-id mask)}
|
||||
[:polyline {:points (->> mask-bb
|
||||
(map #(str (:x %) "," (:y %)))
|
||||
(map #(dm/str (:x %) "," (:y %)))
|
||||
(str/join " "))}]]
|
||||
|
||||
;; When te shape is a text we pass to the shape the info and disable the filter.
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
[props]
|
||||
(let [shape (unchecked-get props "shape")
|
||||
childs (mapv #(get objects %) (:shapes shape))
|
||||
shape (gsh/transform-shape shape)
|
||||
;;shape (gsh/transform-shape shape)
|
||||
|
||||
props (-> (obj/create)
|
||||
(obj/merge! props)
|
||||
|
@ -171,8 +171,7 @@
|
|||
(mf/use-memo (mf/deps objects)
|
||||
#(svg-raw-container-factory objects))]
|
||||
(when (and shape (not (:hidden shape)))
|
||||
(let [shape (-> (gsh/transform-shape shape)
|
||||
(gsh/translate-to-frame frame))
|
||||
(let [shape (gsh/translate-to-frame shape frame)
|
||||
opts #js {:shape shape
|
||||
:frame frame}]
|
||||
(case (:type shape)
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
(: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.pages.helpers :as cph]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.comments :as dcm]
|
||||
|
@ -31,11 +31,10 @@
|
|||
[frame size objects]
|
||||
(let [
|
||||
frame-id (:id frame)
|
||||
modifier (-> (gpt/point (:x size) (:y size))
|
||||
(gpt/negate)
|
||||
(gmt/translate-matrix))
|
||||
vector (-> (gpt/point (:x size) (:y size))
|
||||
(gpt/negate))
|
||||
|
||||
update-fn #(d/update-when %1 %2 assoc-in [:modifiers :displacement] modifier)]
|
||||
update-fn #(d/update-when %1 %2 ctm/add-move vector)]
|
||||
|
||||
(->> (cph/get-children-ids objects frame-id)
|
||||
(into [frame-id])
|
||||
|
|
|
@ -350,7 +350,7 @@
|
|||
[props]
|
||||
(let [shape (obj/get props "shape")
|
||||
childs (mapv #(get objects %) (:shapes shape))
|
||||
shape (gsh/transform-shape shape)
|
||||
;;shape (gsh/transform-shape shape)
|
||||
props (obj/merge! #js {} props
|
||||
#js {:shape shape
|
||||
:childs childs
|
||||
|
@ -429,7 +429,8 @@
|
|||
(mf/with-memo [objects]
|
||||
(svg-raw-container-factory objects))]
|
||||
(when (and shape (not (:hidden shape)))
|
||||
(let [shape (-> (gsh/transform-shape shape)
|
||||
(let [shape (-> shape
|
||||
#_(gsh/transform-shape)
|
||||
(gsh/translate-to-frame frame))
|
||||
|
||||
opts #js {:shape shape
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.workspace.viewport.utils :as vwu]
|
||||
[app.util.dom :as dom]
|
||||
|
@ -184,6 +185,7 @@
|
|||
text? (= type :text)
|
||||
transform-text? (and text? (and (nil? (:resize-vector modifiers)) (nil? (:resize-vector-2 modifiers))))]
|
||||
|
||||
;; TODO LAYOUT: Adapt to new modifiers
|
||||
(doseq [node nodes]
|
||||
(cond
|
||||
;; Text shapes need special treatment because their resize only change
|
||||
|
@ -197,7 +199,7 @@
|
|||
|
||||
(dom/class? node "text-container")
|
||||
(let [modifiers (dissoc modifiers :displacement :rotation)]
|
||||
(when (not (gsh/empty-modifiers? modifiers))
|
||||
(when (not (ctm/empty-modifiers? modifiers))
|
||||
(let [mtx (-> shape
|
||||
(assoc :modifiers modifiers)
|
||||
(gsh/transform-shape)
|
||||
|
@ -260,12 +262,15 @@
|
|||
(d/mapm (fn [id {modifiers :modifiers}]
|
||||
(let [shape (get objects id)
|
||||
center (gsh/center-shape shape)
|
||||
|
||||
;; TODO LAYOUT: Adapt to new modifiers
|
||||
modifiers (cond-> modifiers
|
||||
;; For texts we only use the displacement because
|
||||
;; resize needs to recalculate the text layout
|
||||
(= :text (:type shape))
|
||||
(select-keys [:displacement :rotation]))]
|
||||
(gsh/modifiers->transform center modifiers)))
|
||||
(select-keys [:displacement :rotation]))
|
||||
]
|
||||
(ctm/modifiers->transform center modifiers)))
|
||||
modifiers))))
|
||||
|
||||
shapes
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
:height height
|
||||
:style {:fill "none" :stroke "red"}}]
|
||||
|
||||
;; Text baselineazo
|
||||
;; Text baseline
|
||||
[:line {:x1 (mth/round x)
|
||||
:y1 (mth/round (- (:y data) (:height data)))
|
||||
:x2 (mth/round (+ x width))
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[app.common.math :as mth]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.main.refs :as refs]
|
||||
|
@ -33,6 +34,7 @@
|
|||
(with-meta (meta (:position-data shape))))
|
||||
(dissoc :position-data :transform :transform-inverse)))
|
||||
|
||||
;; TODO LAYOUT: Adapt to new modifiers
|
||||
(defn strip-modifier
|
||||
[modifier]
|
||||
(if (or (some? (dm/get-in modifier [:modifiers :resize-vector]))
|
||||
|
@ -43,9 +45,9 @@
|
|||
(defn process-shape [modifiers {:keys [id] :as shape}]
|
||||
(let [modifier (-> (get modifiers id) strip-modifier)
|
||||
shape (cond-> shape
|
||||
(not (gsh/empty-modifiers? (:modifiers modifier)))
|
||||
(not (ctm/empty-modifiers? (:modifiers modifier)))
|
||||
(-> (assoc :grow-type :fixed)
|
||||
(merge modifier) gsh/transform-shape))]
|
||||
(gsh/transform-shape modifier)))]
|
||||
(-> shape
|
||||
(cond-> (nil? (:position-data shape))
|
||||
(assoc :migrate true))
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
(ns app.main.ui.workspace.sidebar.options
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.main.data.workspace :as udw]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
|
@ -64,7 +64,7 @@
|
|||
shared-libs (mf/deref refs/workspace-libraries)
|
||||
modifiers (mf/deref refs/workspace-modifiers)
|
||||
objects-modified (mf/with-memo [base-objects modifiers]
|
||||
(gsh/merge-modifiers base-objects modifiers))
|
||||
(ctm/merge-modifiers base-objects modifiers))
|
||||
selected-shapes (into [] (keep (d/getf objects-modified)) selected)]
|
||||
[:div.tool-window
|
||||
[:div.tool-window-content
|
||||
|
|
|
@ -79,8 +79,7 @@
|
|||
modifiers (mf/deref refs/workspace-modifiers)
|
||||
|
||||
objects-modified (mf/with-memo [base-objects modifiers]
|
||||
(gsh/merge-modifiers base-objects modifiers))
|
||||
|
||||
(gsh/apply-objects-modifiers base-objects modifiers))
|
||||
background (get options :background clr/canvas)
|
||||
|
||||
;; STATE
|
||||
|
@ -203,7 +202,7 @@
|
|||
{:key (dm/str "texts-" page-id)
|
||||
:page-id page-id
|
||||
:objects objects
|
||||
:modifiers modifiers
|
||||
;;:modifiers modifiers
|
||||
:edition edition}]]]]
|
||||
|
||||
(when show-comments?
|
||||
|
@ -336,10 +335,9 @@
|
|||
(when show-prototypes?
|
||||
[:& widgets/frame-flows
|
||||
{:flows (:flows options)
|
||||
:objects base-objects
|
||||
:objects objects-modified
|
||||
:selected selected
|
||||
:zoom zoom
|
||||
:modifiers modifiers
|
||||
:on-frame-enter on-frame-enter
|
||||
:on-frame-leave on-frame-leave
|
||||
:on-frame-select on-frame-select}])
|
||||
|
@ -348,8 +346,7 @@
|
|||
[:& drawarea/draw-area
|
||||
{:shape drawing-obj
|
||||
:zoom zoom
|
||||
:tool drawing-tool
|
||||
:modifiers modifiers}])
|
||||
:tool drawing-tool}])
|
||||
|
||||
(when show-grids?
|
||||
[:& frame-grid/frame-grid
|
||||
|
@ -371,9 +368,8 @@
|
|||
:zoom zoom
|
||||
:page-id page-id
|
||||
:selected selected
|
||||
:objects base-objects
|
||||
:focus focus
|
||||
:modifiers modifiers}])
|
||||
:objects objects-modified
|
||||
:focus focus}])
|
||||
|
||||
(when show-snap-distance?
|
||||
[:& snap-distances/snap-distances
|
||||
|
@ -416,7 +412,6 @@
|
|||
{:zoom zoom
|
||||
:vbox vbox
|
||||
:hover-frame frame-parent
|
||||
:modifiers modifiers
|
||||
:disabled-guides? disabled-guides?}])
|
||||
|
||||
(when show-selection-handlers?
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
(ns app.main.ui.workspace.viewport.drawarea
|
||||
"Drawing components."
|
||||
(:require
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.main.ui.shapes.path :refer [path-shape]]
|
||||
[app.main.ui.workspace.shapes :as shapes]
|
||||
|
@ -22,7 +21,7 @@
|
|||
|
||||
[:g.draw-area
|
||||
[:g {:style {:pointer-events "none"}}
|
||||
[:& shapes/shape-wrapper {:shape (gsh/transform-shape shape)}]]
|
||||
[:& shapes/shape-wrapper {:shape shape}]]
|
||||
|
||||
(case tool
|
||||
:path [:& path-editor {:shape shape :zoom zoom}]
|
||||
|
@ -31,7 +30,7 @@
|
|||
|
||||
(mf/defc generic-draw-area
|
||||
[{:keys [shape zoom]}]
|
||||
(let [{:keys [x y width height]} (:selrect (gsh/transform-shape shape))]
|
||||
(let [{:keys [x y width height]} (:selrect shape)]
|
||||
(when (and x y
|
||||
(not (mth/nan? x))
|
||||
(not (mth/nan? y)))
|
||||
|
|
|
@ -278,7 +278,7 @@
|
|||
frame]} (use-guide handle-change-position get-hover-frame zoom guide)
|
||||
|
||||
base-frame (or frame hover-frame)
|
||||
frame (gsh/transform-shape (merge base-frame frame-modifier))
|
||||
frame (gsh/transform-shape base-frame frame-modifier)
|
||||
|
||||
move-vec (gpt/to-vec (gpt/point (:x base-frame) (:y base-frame))
|
||||
(gpt/point (:x frame) (:y frame)))
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
@ -254,13 +253,11 @@
|
|||
(mf/defc interactions
|
||||
[{:keys [current-transform objects zoom selected hover-disabled?] :as props}]
|
||||
(let [active-shapes (into []
|
||||
(comp (filter #(seq (:interactions %)))
|
||||
(map gsh/transform-shape))
|
||||
(comp (filter #(seq (:interactions %))))
|
||||
(vals objects))
|
||||
|
||||
selected-shapes (into []
|
||||
(comp (map (d/getf objects))
|
||||
(map gsh/transform-shape))
|
||||
(map (d/getf objects))
|
||||
selected)
|
||||
|
||||
{:keys [editing-interaction-index
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
"var(--color-primary)" "var(--color-component-highlight)")]
|
||||
(for [shape shapes]
|
||||
[:& outline {:key (str "outline-" (:id shape))
|
||||
:shape (gsh/transform-shape shape)
|
||||
:shape shape
|
||||
:zoom zoom
|
||||
:color color}])))
|
||||
|
||||
|
|
|
@ -341,7 +341,7 @@
|
|||
(let [shape (mf/use-memo
|
||||
(mf/deps shapes)
|
||||
#(->> shapes
|
||||
(map gsh/transform-shape)
|
||||
#_(map gsh/transform-shape)
|
||||
(gsh/selection-rect)
|
||||
(cts/setup-shape)))
|
||||
on-resize
|
||||
|
@ -369,7 +369,7 @@
|
|||
(let [shape (mf/use-memo
|
||||
(mf/deps shapes)
|
||||
#(->> shapes
|
||||
(map gsh/transform-shape)
|
||||
#_(map gsh/transform-shape)
|
||||
(gsh/selection-rect)
|
||||
(cts/setup-shape)))]
|
||||
|
||||
|
@ -384,7 +384,7 @@
|
|||
(mf/defc single-handlers
|
||||
[{:keys [shape zoom color disable-handlers] :as props}]
|
||||
(let [shape-id (:id shape)
|
||||
shape (gsh/transform-shape shape)
|
||||
;;shape (gsh/transform-shape shape)
|
||||
|
||||
on-resize
|
||||
(fn [current-position _initial-position event]
|
||||
|
@ -408,14 +408,13 @@
|
|||
|
||||
(mf/defc single-selection
|
||||
[{:keys [shape zoom color disable-handlers on-move-selected on-context-menu] :as props}]
|
||||
(let [shape (gsh/transform-shape shape)]
|
||||
[:& controls-selection
|
||||
{:shape shape
|
||||
:zoom zoom
|
||||
:color color
|
||||
:disable-handlers disable-handlers
|
||||
:on-move-selected on-move-selected
|
||||
:on-context-menu on-context-menu}]))
|
||||
[:& controls-selection
|
||||
{:shape shape
|
||||
:zoom zoom
|
||||
:color color
|
||||
:disable-handlers disable-handlers
|
||||
:on-move-selected on-move-selected
|
||||
:on-context-menu on-context-menu}])
|
||||
|
||||
(mf/defc selection-area
|
||||
{::mf/wrap [mf/memo]}
|
||||
|
|
|
@ -50,20 +50,14 @@
|
|||
:opacity line-opacity}])
|
||||
|
||||
(defn get-snap
|
||||
[coord {:keys [shapes page-id remove-snap? zoom modifiers]}]
|
||||
(let [shapes-sr
|
||||
(->> shapes
|
||||
;; Merge modifiers into shapes
|
||||
(map #(merge % (get modifiers (:id %))))
|
||||
;; Create the bounding rectangle for the shapes
|
||||
(gsh/selection-rect))
|
||||
[coord {:keys [shapes page-id remove-snap? zoom]}]
|
||||
(let [bounds (gsh/selection-rect shapes)
|
||||
frame-id (snap/snap-frame-id shapes)]
|
||||
|
||||
frame-id (snap/snap-frame-id shapes)]
|
||||
|
||||
(->> (rx/of shapes-sr)
|
||||
(->> (rx/of bounds)
|
||||
(rx/flat-map
|
||||
(fn [selrect]
|
||||
(->> (sp/selrect-snap-points selrect)
|
||||
(fn [bounds]
|
||||
(->> (sp/selrect-snap-points bounds)
|
||||
(map #(vector frame-id %)))))
|
||||
|
||||
(rx/flat-map
|
||||
|
@ -159,7 +153,7 @@
|
|||
|
||||
(mf/defc snap-points
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [layout zoom objects selected page-id drawing modifiers focus] :as props}]
|
||||
[{:keys [layout zoom objects selected page-id drawing focus] :as props}]
|
||||
(us/assert set? selected)
|
||||
(let [shapes (into [] (keep (d/getf objects)) selected)
|
||||
|
||||
|
@ -182,6 +176,5 @@
|
|||
[:& snap-feedback {:shapes shapes
|
||||
:page-id page-id
|
||||
:remove-snap? remove-snap?
|
||||
:zoom zoom
|
||||
:modifiers modifiers}]))
|
||||
:zoom zoom}]))
|
||||
|
||||
|
|
|
@ -53,9 +53,7 @@
|
|||
(defn text-transform
|
||||
[{:keys [x y]} zoom]
|
||||
(let [inv-zoom (/ 1 zoom)]
|
||||
(str
|
||||
"scale(" inv-zoom ", " inv-zoom ") "
|
||||
"translate(" (* zoom x) ", " (* zoom y) ")")))
|
||||
(dm/fmt "scale(%, %) translate(%, %)" inv-zoom inv-zoom (* zoom x) (* zoom y))))
|
||||
|
||||
(defn title-transform [frame zoom]
|
||||
(let [frame-transform (gsh/transform-str frame {:no-flip true})
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.types.shape-tree :as ctt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
@ -182,8 +181,8 @@
|
|||
:on-frame-select on-frame-select}]))]))
|
||||
|
||||
(mf/defc frame-flow
|
||||
[{:keys [flow frame modifiers selected? zoom on-frame-enter on-frame-leave on-frame-select]}]
|
||||
(let [{:keys [x y]} (gsh/transform-shape frame)
|
||||
[{:keys [flow frame selected? zoom on-frame-enter on-frame-leave on-frame-select]}]
|
||||
(let [{:keys [x y]} frame
|
||||
flow-pos (gpt/point x (- y (/ 35 zoom)))
|
||||
|
||||
on-mouse-down
|
||||
|
@ -217,9 +216,7 @@
|
|||
:y -15
|
||||
:width 100000
|
||||
:height 24
|
||||
:transform (str (when (and selected? modifiers)
|
||||
(str (:displacement modifiers) " " ))
|
||||
(vwu/text-transform flow-pos zoom))}
|
||||
:transform (vwu/text-transform flow-pos zoom)}
|
||||
[:div.flow-badge {:class (dom/classnames :selected selected?)}
|
||||
[:div.content {:on-mouse-down on-mouse-down
|
||||
:on-double-click on-double-click
|
||||
|
@ -234,7 +231,6 @@
|
|||
(let [flows (unchecked-get props "flows")
|
||||
objects (unchecked-get props "objects")
|
||||
zoom (unchecked-get props "zoom")
|
||||
modifiers (unchecked-get props "modifiers")
|
||||
selected (or (unchecked-get props "selected") #{})
|
||||
|
||||
on-frame-enter (unchecked-get props "on-frame-enter")
|
||||
|
@ -248,7 +244,6 @@
|
|||
:frame frame
|
||||
:selected? (contains? selected (:id frame))
|
||||
:zoom zoom
|
||||
:modifiers modifiers
|
||||
:on-frame-enter on-frame-enter
|
||||
:on-frame-leave on-frame-leave
|
||||
:on-frame-select on-frame-select}]))]))
|
||||
|
|
|
@ -29,10 +29,9 @@
|
|||
(defn shape-snap-points
|
||||
[{:keys [hidden blocked] :as shape}]
|
||||
(when (and (not blocked) (not hidden))
|
||||
(let [shape (gsh/transform-shape shape)]
|
||||
(case (:type shape)
|
||||
:frame (-> shape :points gsh/points->selrect frame-snap-points)
|
||||
(into #{(gsh/center-shape shape)} (:points shape))))))
|
||||
(case (:type shape)
|
||||
:frame (-> shape :points gsh/points->selrect frame-snap-points)
|
||||
(into #{(gsh/center-shape shape)} (:points shape)))))
|
||||
|
||||
(defn guide-snap-points
|
||||
[guide frame]
|
||||
|
|
Loading…
Add table
Reference in a new issue