mirror of
https://github.com/penpot/penpot.git
synced 2025-05-29 00:56:10 +02:00
✨ Improvements over selrect generation
This commit is contained in:
parent
0f54e85b36
commit
f4be3aa9de
19 changed files with 176 additions and 171 deletions
|
@ -17,39 +17,6 @@
|
||||||
[app.common.geom.shapes.transforms :as gtr]
|
[app.common.geom.shapes.transforms :as gtr]
|
||||||
[app.common.math :as mth]))
|
[app.common.math :as mth]))
|
||||||
|
|
||||||
;; --- Setup (Initialize)
|
|
||||||
;; FIXME: Is this the correct place for these functions?
|
|
||||||
|
|
||||||
(defn- setup-rect
|
|
||||||
"A specialized function for setup rect-like shapes."
|
|
||||||
[shape {:keys [x y width height]}]
|
|
||||||
(let [rect {:x x :y y :width width :height height}
|
|
||||||
points (gpr/rect->points rect)
|
|
||||||
selrect (gpr/points->selrect points)]
|
|
||||||
(assoc shape
|
|
||||||
:x x
|
|
||||||
:y y
|
|
||||||
:width width
|
|
||||||
:height height
|
|
||||||
:points points
|
|
||||||
:selrect selrect)))
|
|
||||||
|
|
||||||
(defn- setup-image
|
|
||||||
[{:keys [metadata] :as shape} props]
|
|
||||||
(-> (setup-rect shape props)
|
|
||||||
(assoc
|
|
||||||
:proportion (/ (:width metadata)
|
|
||||||
(:height metadata))
|
|
||||||
:proportion-lock true)))
|
|
||||||
|
|
||||||
(defn setup
|
|
||||||
"A function that initializes the first coordinates for
|
|
||||||
the shape. Used mainly for draw operations."
|
|
||||||
[shape props]
|
|
||||||
(case (:type shape)
|
|
||||||
:image (setup-image shape props)
|
|
||||||
(setup-rect shape props)))
|
|
||||||
|
|
||||||
;; --- Outer Rect
|
;; --- Outer Rect
|
||||||
|
|
||||||
(defn selection-rect
|
(defn selection-rect
|
||||||
|
@ -121,13 +88,6 @@
|
||||||
(defn distance-shapes [shape other]
|
(defn distance-shapes [shape other]
|
||||||
(distance-selrect (:selrect shape) (:selrect other)))
|
(distance-selrect (:selrect shape) (:selrect other)))
|
||||||
|
|
||||||
(defn setup-selrect [shape]
|
|
||||||
(let [selrect (gpr/rect->selrect shape)
|
|
||||||
points (gpr/rect->points shape)]
|
|
||||||
(-> shape
|
|
||||||
(assoc :selrect selrect
|
|
||||||
:points points))))
|
|
||||||
|
|
||||||
(defn shape-stroke-margin
|
(defn shape-stroke-margin
|
||||||
[shape stroke-width]
|
[shape stroke-width]
|
||||||
(if (= (:type shape) :path)
|
(if (= (:type shape) :path)
|
||||||
|
|
|
@ -30,15 +30,13 @@
|
||||||
"Calculates the selrect+points for the boolean shape"
|
"Calculates the selrect+points for the boolean shape"
|
||||||
[shape children objects]
|
[shape children objects]
|
||||||
|
|
||||||
(let [content (calc-bool-content shape objects)
|
(let [bool-content (calc-bool-content shape objects)
|
||||||
[points selrect]
|
shape (assoc shape :bool-content bool-content)
|
||||||
(if (empty? content)
|
[points selrect] (gsp/content->points+selrect shape bool-content)]
|
||||||
(let [selrect (gtr/selection-rect children)
|
|
||||||
points (gpr/rect->points selrect)]
|
(if (and (some? selrect) (d/not-empty? points))
|
||||||
[points selrect])
|
|
||||||
(gsp/content->points+selrect shape content))]
|
|
||||||
(-> shape
|
(-> shape
|
||||||
(assoc :selrect selrect)
|
(assoc :selrect selrect)
|
||||||
(assoc :points points)
|
(assoc :points points))
|
||||||
(assoc :bool-content content))))
|
(gtr/update-group-selrect shape children))))
|
||||||
|
|
||||||
|
|
|
@ -333,11 +333,8 @@
|
||||||
(command->point command :c2)]]
|
(command->point command :c2)]]
|
||||||
(->> (curve-extremities curve)
|
(->> (curve-extremities curve)
|
||||||
(mapv #(curve-values curve %)))))
|
(mapv #(curve-values curve %)))))
|
||||||
[])
|
[])]
|
||||||
selrect (gpr/points->selrect points)]
|
(gpr/points->selrect points))))
|
||||||
(-> selrect
|
|
||||||
(update :width #(if (mth/almost-zero? %) 1 %))
|
|
||||||
(update :height #(if (mth/almost-zero? %) 1 %))))))
|
|
||||||
|
|
||||||
(defn content->selrect [content]
|
(defn content->selrect [content]
|
||||||
(let [calc-extremities
|
(let [calc-extremities
|
||||||
|
@ -371,20 +368,26 @@
|
||||||
|
|
||||||
set-tr
|
set-tr
|
||||||
(fn [params px py]
|
(fn [params px py]
|
||||||
(-> params
|
(cond-> params
|
||||||
|
(d/num? dx)
|
||||||
(update px + dx)
|
(update px + dx)
|
||||||
|
|
||||||
|
(d/num? dy)
|
||||||
(update py + dy)))
|
(update py + dy)))
|
||||||
|
|
||||||
transform-params
|
transform-params
|
||||||
(fn [{:keys [x c1x c2x] :as params}]
|
(fn [{:keys [x y c1x c1y c2x c2y] :as params}]
|
||||||
(cond-> params
|
(cond-> params
|
||||||
(some? x) (set-tr :x :y)
|
(d/num? x y) (set-tr :x :y)
|
||||||
(some? c1x) (set-tr :c1x :c1y)
|
(d/num? c1x c1y) (set-tr :c1x :c1y)
|
||||||
(some? c2x) (set-tr :c2x :c2y)))]
|
(d/num? c2x c2y) (set-tr :c2x :c2y)))
|
||||||
|
|
||||||
(into []
|
update-command
|
||||||
(map #(update % :params transform-params))
|
(fn [command]
|
||||||
content)))
|
(update command :params transform-params))]
|
||||||
|
|
||||||
|
(->> content
|
||||||
|
(into [] (map update-command)))))
|
||||||
|
|
||||||
(defn transform-content
|
(defn transform-content
|
||||||
[content transform]
|
[content transform]
|
||||||
|
|
|
@ -21,28 +21,28 @@
|
||||||
|
|
||||||
;; --- Relative Movement
|
;; --- Relative Movement
|
||||||
|
|
||||||
(defn- move-selrect [selrect pt]
|
(defn- move-selrect [{:keys [x y x1 y1 x2 y2 width height] :as selrect} {dx :x dy :y :as pt}]
|
||||||
(when (and (some? selrect) (some? pt))
|
(if (and (some? selrect) (some? pt) (d/num? dx dy))
|
||||||
(let [dx (.-x pt)
|
{:x (if (d/num? x) (+ dx x) x)
|
||||||
dy (.-y pt)
|
:y (if (d/num? y) (+ dy y) y)
|
||||||
{:keys [x y x1 y1 x2 y2 width height]} selrect]
|
:x1 (if (d/num? x1) (+ dx x1) x1)
|
||||||
{:x (if (some? x) (+ dx x) x)
|
:y1 (if (d/num? y1) (+ dy y1) y1)
|
||||||
:y (if (some? y) (+ dy y) y)
|
:x2 (if (d/num? x2) (+ dx x2) x2)
|
||||||
:x1 (if (some? x1) (+ dx x1) x1)
|
:y2 (if (d/num? y2) (+ dy y2) y2)
|
||||||
:y1 (if (some? y1) (+ dy y1) y1)
|
|
||||||
:x2 (if (some? x2) (+ dx x2) x2)
|
|
||||||
:y2 (if (some? y2) (+ dy y2) y2)
|
|
||||||
:width width
|
:width width
|
||||||
:height height})))
|
:height height}
|
||||||
|
selrect))
|
||||||
|
|
||||||
(defn- move-points [points move-vec]
|
(defn- move-points [points move-vec]
|
||||||
(->> points
|
(cond->> points
|
||||||
|
(d/num? (:x move-vec) (:y move-vec))
|
||||||
(mapv #(gpt/add % move-vec))))
|
(mapv #(gpt/add % move-vec))))
|
||||||
|
|
||||||
(defn move-position-data
|
(defn move-position-data
|
||||||
[position-data dx dy]
|
[position-data dx dy]
|
||||||
|
|
||||||
(->> position-data
|
(cond->> position-data
|
||||||
|
(d/num? dx dy)
|
||||||
(mapv #(-> %
|
(mapv #(-> %
|
||||||
(update :x + dx)
|
(update :x + dx)
|
||||||
(update :y + dy)))))
|
(update :y + dy)))))
|
||||||
|
@ -51,8 +51,8 @@
|
||||||
"Move the shape relatively to its current
|
"Move the shape relatively to its current
|
||||||
position applying the provided delta."
|
position applying the provided delta."
|
||||||
[{:keys [type] :as shape} {dx :x dy :y}]
|
[{:keys [type] :as shape} {dx :x dy :y}]
|
||||||
(let [dx (d/check-num dx)
|
(let [dx (d/check-num dx 0)
|
||||||
dy (d/check-num dy)
|
dy (d/check-num dy 0)
|
||||||
move-vec (gpt/point dx dy)]
|
move-vec (gpt/point dx dy)]
|
||||||
|
|
||||||
(-> shape
|
(-> shape
|
||||||
|
@ -138,9 +138,12 @@
|
||||||
(defn transform-matrix
|
(defn transform-matrix
|
||||||
"Returns a transformation matrix without changing the shape properties.
|
"Returns a transformation matrix without changing the shape properties.
|
||||||
The result should be used in a `transform` attribute in svg"
|
The result should be used in a `transform` attribute in svg"
|
||||||
([shape] (transform-matrix shape nil))
|
([shape]
|
||||||
([shape params] (transform-matrix shape params (or (gco/center-shape shape)
|
(transform-matrix shape nil))
|
||||||
(gpt/point 0 0))))
|
|
||||||
|
([shape params]
|
||||||
|
(transform-matrix shape params (or (gco/center-shape shape) (gpt/point 0 0))))
|
||||||
|
|
||||||
([{:keys [flip-x flip-y] :as shape} {:keys [no-flip]} shape-center]
|
([{:keys [flip-x flip-y] :as shape} {:keys [no-flip]} shape-center]
|
||||||
(-> (gmt/matrix)
|
(-> (gmt/matrix)
|
||||||
(gmt/translate shape-center)
|
(gmt/translate shape-center)
|
||||||
|
@ -276,10 +279,6 @@
|
||||||
[(gpr/points->selrect points) nil nil]
|
[(gpr/points->selrect points) nil nil]
|
||||||
(adjust-rotated-transform shape points))
|
(adjust-rotated-transform shape points))
|
||||||
|
|
||||||
;;selrect (cond-> selrect
|
|
||||||
;; round-coords? gpr/round-selrect)
|
|
||||||
|
|
||||||
;; Redondear los points?
|
|
||||||
base-rotation (or (:rotation shape) 0)
|
base-rotation (or (:rotation shape) 0)
|
||||||
modif-rotation (or (get-in shape [:modifiers :rotation]) 0)
|
modif-rotation (or (get-in shape [:modifiers :rotation]) 0)
|
||||||
rotation (mod (+ base-rotation modif-rotation) 360)]
|
rotation (mod (+ base-rotation modif-rotation) 360)]
|
||||||
|
@ -296,8 +295,10 @@
|
||||||
(assoc :transform-inverse transform-inverse)))
|
(assoc :transform-inverse transform-inverse)))
|
||||||
(cond-> (not transform)
|
(cond-> (not transform)
|
||||||
(dissoc :transform :transform-inverse))
|
(dissoc :transform :transform-inverse))
|
||||||
(assoc :selrect selrect)
|
(cond-> (some? selrect)
|
||||||
(assoc :points points)
|
(assoc :selrect selrect))
|
||||||
|
(cond-> (d/not-empty? points)
|
||||||
|
(assoc :points points))
|
||||||
(assoc :rotation rotation))))
|
(assoc :rotation rotation))))
|
||||||
|
|
||||||
(defn- update-group-viewbox
|
(defn- update-group-viewbox
|
||||||
|
@ -568,11 +569,7 @@
|
||||||
|
|
||||||
displacement
|
displacement
|
||||||
(when (some? displacement)
|
(when (some? displacement)
|
||||||
(gmt/multiply resize-transform-inverse displacement)
|
(gmt/multiply resize-transform-inverse displacement))
|
||||||
#_(-> (gpt/point 0 0)
|
|
||||||
(gpt/transform displacement)
|
|
||||||
(gpt/transform resize-transform-inverse)
|
|
||||||
(gmt/translate-matrix)))
|
|
||||||
|
|
||||||
resize-origin
|
resize-origin
|
||||||
(when (some? resize-origin)
|
(when (some? resize-origin)
|
||||||
|
|
|
@ -42,4 +42,5 @@
|
||||||
(dm/export init/make-minimal-shape)
|
(dm/export init/make-minimal-shape)
|
||||||
(dm/export init/make-minimal-group)
|
(dm/export init/make-minimal-group)
|
||||||
(dm/export init/empty-file-data)
|
(dm/export init/empty-file-data)
|
||||||
|
(dm/export init/setup-shape)
|
||||||
|
(dm/export init/setup-rect-selrect)
|
||||||
|
|
|
@ -104,6 +104,7 @@
|
||||||
:group #{:proportion-lock
|
:group #{:proportion-lock
|
||||||
:width :height
|
:width :height
|
||||||
:x :y
|
:x :y
|
||||||
|
:rotation
|
||||||
:selrect
|
:selrect
|
||||||
|
|
||||||
:constraints-h
|
:constraints-h
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[app.common.colors :as clr]
|
[app.common.colors :as clr]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.pages.common :refer [file-version default-color]]
|
[app.common.pages.common :refer [file-version default-color]]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
|
@ -146,3 +147,40 @@
|
||||||
(assoc :id file-id)
|
(assoc :id file-id)
|
||||||
(update :pages conj page-id)
|
(update :pages conj page-id)
|
||||||
(update :pages-index assoc page-id pd)))))
|
(update :pages-index assoc page-id pd)))))
|
||||||
|
|
||||||
|
(defn setup-rect-selrect
|
||||||
|
"Initializes the selrect and points for a shape"
|
||||||
|
[shape]
|
||||||
|
(let [selrect (gsh/rect->selrect shape)
|
||||||
|
points (gsh/rect->points shape)]
|
||||||
|
(-> shape
|
||||||
|
(assoc :selrect selrect
|
||||||
|
:points points))))
|
||||||
|
|
||||||
|
(defn- setup-rect
|
||||||
|
"A specialized function for setup rect-like shapes."
|
||||||
|
[shape {:keys [x y width height]}]
|
||||||
|
(-> shape
|
||||||
|
(assoc :x x :y y :width width :height height)
|
||||||
|
(setup-rect-selrect)))
|
||||||
|
|
||||||
|
(defn- setup-image
|
||||||
|
[{:keys [metadata] :as shape} props]
|
||||||
|
(-> (setup-rect shape props)
|
||||||
|
(assoc
|
||||||
|
:proportion (/ (:width metadata)
|
||||||
|
(:height metadata))
|
||||||
|
:proportion-lock true)))
|
||||||
|
|
||||||
|
(defn setup-shape
|
||||||
|
"A function that initializes the first coordinates for
|
||||||
|
the shape. Used mainly for draw operations."
|
||||||
|
([props]
|
||||||
|
(setup-shape {:type :rect} props))
|
||||||
|
|
||||||
|
([shape props]
|
||||||
|
(case (:type shape)
|
||||||
|
:image (setup-image shape props)
|
||||||
|
(setup-rect shape props))))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
|
|
||||||
(fix-empty-points [shape]
|
(fix-empty-points [shape]
|
||||||
(let [shape (cond-> shape
|
(let [shape (cond-> shape
|
||||||
(empty? (:selrect shape)) (gsh/setup-selrect))]
|
(empty? (:selrect shape)) (cp/setup-rect-selrect))]
|
||||||
(cond-> shape
|
(cond-> shape
|
||||||
(empty? (:points shape))
|
(empty? (:points shape))
|
||||||
(assoc :points (gsh/rect->points (:selrect shape))))))
|
(assoc :points (gsh/rect->points (:selrect shape))))))
|
||||||
|
|
|
@ -1574,7 +1574,7 @@
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
frame-id (-> (wsh/lookup-page-objects state page-id)
|
frame-id (-> (wsh/lookup-page-objects state page-id)
|
||||||
(cph/frame-id-by-position @ms/mouse-position))
|
(cph/frame-id-by-position @ms/mouse-position))
|
||||||
shape (gsh/setup-selrect
|
shape (cp/setup-rect-selrect
|
||||||
{:id id
|
{:id id
|
||||||
:type :text
|
:type :text
|
||||||
:name "Text"
|
:name "Text"
|
||||||
|
@ -1667,7 +1667,7 @@
|
||||||
shape (-> (cp/make-minimal-shape :frame)
|
shape (-> (cp/make-minimal-shape :frame)
|
||||||
(merge {:x (:x srect) :y (:y srect) :width (:width srect) :height (:height srect)})
|
(merge {:x (:x srect) :y (:y srect) :width (:width srect) :height (:height srect)})
|
||||||
(assoc :frame-id frame-id)
|
(assoc :frame-id frame-id)
|
||||||
(gsh/setup-selrect))]
|
(cp/setup-rect-selrect))]
|
||||||
(rx/of
|
(rx/of
|
||||||
(dwu/start-undo-transaction)
|
(dwu/start-undo-transaction)
|
||||||
(dwc/add-shape shape)
|
(dwc/add-shape shape)
|
||||||
|
|
|
@ -480,7 +480,7 @@
|
||||||
(merge data)
|
(merge data)
|
||||||
(merge {:x x :y y})
|
(merge {:x x :y y})
|
||||||
(assoc :frame-id frame-id)
|
(assoc :frame-id frame-id)
|
||||||
(gsh/setup-selrect))]
|
(cp/setup-rect-selrect))]
|
||||||
(rx/of (add-shape shape))))))
|
(rx/of (add-shape shape))))))
|
||||||
|
|
||||||
(defn image-uploaded
|
(defn image-uploaded
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
|
[app.common.pages :as cp]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace.drawing.common :as common]
|
[app.main.data.workspace.drawing.common :as common]
|
||||||
|
@ -70,7 +71,10 @@
|
||||||
|
|
||||||
shape (-> state
|
shape (-> state
|
||||||
(get-in [:workspace-drawing :object])
|
(get-in [:workspace-drawing :object])
|
||||||
(gsh/setup {:x (:x initial) :y (:y initial) :width 0.01 :height 0.01})
|
(cp/setup-shape {:x (:x initial)
|
||||||
|
:y (:y initial)
|
||||||
|
:width 0.01
|
||||||
|
:height 0.01})
|
||||||
(assoc :frame-id fid)
|
(assoc :frame-id fid)
|
||||||
(assoc :initialized? true)
|
(assoc :initialized? true)
|
||||||
(assoc :click-draw? true))]
|
(assoc :click-draw? true))]
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
(ns app.main.data.workspace.drawing.common
|
(ns app.main.data.workspace.drawing.common
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.pages :as cp]
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
|
@ -49,7 +50,7 @@
|
||||||
(assoc :height 17 :width 4 :grow-type :auto-width)
|
(assoc :height 17 :width 4 :grow-type :auto-width)
|
||||||
|
|
||||||
click-draw?
|
click-draw?
|
||||||
(gsh/setup-selrect)
|
(cp/setup-rect-selrect)
|
||||||
|
|
||||||
:always
|
:always
|
||||||
(-> (gsh/transform-shape)
|
(-> (gsh/transform-shape)
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
|
|
||||||
selrect (gsh/selection-rect shapes)
|
selrect (gsh/selection-rect shapes)
|
||||||
group (-> (cp/make-minimal-group frame-id selrect gname)
|
group (-> (cp/make-minimal-group frame-id selrect gname)
|
||||||
(gsh/setup selrect)
|
(cp/setup-shape selrect)
|
||||||
(assoc :shapes (mapv :id shapes)
|
(assoc :shapes (mapv :id shapes)
|
||||||
:parent-id parent-id
|
:parent-id parent-id
|
||||||
:frame-id frame-id
|
:frame-id frame-id
|
||||||
|
|
|
@ -103,20 +103,21 @@
|
||||||
|
|
||||||
(defn handle-area-selection
|
(defn handle-area-selection
|
||||||
[shift?]
|
[shift?]
|
||||||
(letfn [(valid-rect? [{width :width height :height}]
|
(letfn [(valid-rect? [zoom {width :width height :height}]
|
||||||
(or (> width 10) (> height 10)))]
|
(or (> width (/ 10 zoom)) (> height (/ 10 zoom))))]
|
||||||
|
|
||||||
(ptk/reify ::handle-area-selection
|
(ptk/reify ::handle-area-selection
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ stream]
|
(watch [_ state stream]
|
||||||
(let [stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
|
(let [zoom (get-in state [:workspace-local :zoom] 1)
|
||||||
|
stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
|
||||||
stoper (->> stream (rx/filter stop?))
|
stoper (->> stream (rx/filter stop?))
|
||||||
from-p @ms/mouse-position]
|
from-p @ms/mouse-position]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
(rx/take-until stoper)
|
(rx/take-until stoper)
|
||||||
(rx/map #(gsh/points->rect [from-p %]))
|
(rx/map #(gsh/points->rect [from-p %]))
|
||||||
(rx/filter valid-rect?)
|
(rx/filter (partial valid-rect? zoom))
|
||||||
(rx/map update-area-selection))
|
(rx/map update-area-selection))
|
||||||
|
|
||||||
(rx/of (select-node-area shift?)
|
(rx/of (select-node-area shift?)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.pages.changes-builder :as pcb]
|
[app.common.pages.changes-builder :as pcb]
|
||||||
|
[app.common.pages :as cp]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.spec :refer [max-safe-int min-safe-int]]
|
[app.common.spec :refer [max-safe-int min-safe-int]]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
@ -165,7 +166,7 @@
|
||||||
(assoc :svg-attrs attrs)
|
(assoc :svg-attrs attrs)
|
||||||
(assoc :svg-viewbox (-> (select-keys svg-data [:width :height])
|
(assoc :svg-viewbox (-> (select-keys svg-data [:width :height])
|
||||||
(assoc :x offset-x :y offset-y)))
|
(assoc :x offset-x :y offset-y)))
|
||||||
(gsh/setup-selrect))))
|
(cp/setup-rect-selrect))))
|
||||||
|
|
||||||
(defn create-svg-root [frame-id svg-data]
|
(defn create-svg-root [frame-id svg-data]
|
||||||
(let [{:keys [name x y width height offset-x offset-y]} svg-data]
|
(let [{:keys [name x y width height offset-x offset-y]} svg-data]
|
||||||
|
@ -177,7 +178,7 @@
|
||||||
:height height
|
:height height
|
||||||
:x (+ x offset-x)
|
:x (+ x offset-x)
|
||||||
:y (+ y offset-y)}
|
:y (+ y offset-y)}
|
||||||
(gsh/setup-selrect)
|
(cp/setup-rect-selrect)
|
||||||
(assoc :svg-attrs (-> (:attrs svg-data)
|
(assoc :svg-attrs (-> (:attrs svg-data)
|
||||||
(dissoc :viewBox :xmlns)
|
(dissoc :viewBox :xmlns)
|
||||||
(d/without-keys usvg/inheritable-props))))))
|
(d/without-keys usvg/inheritable-props))))))
|
||||||
|
@ -197,7 +198,7 @@
|
||||||
(assoc :svg-attrs (d/without-keys attrs usvg/inheritable-props))
|
(assoc :svg-attrs (d/without-keys attrs usvg/inheritable-props))
|
||||||
(assoc :svg-viewbox (-> (select-keys svg-data [:width :height])
|
(assoc :svg-viewbox (-> (select-keys svg-data [:width :height])
|
||||||
(assoc :x offset-x :y offset-y)))
|
(assoc :x offset-x :y offset-y)))
|
||||||
(gsh/setup-selrect))))
|
(cp/setup-rect-selrect))))
|
||||||
|
|
||||||
(defn create-path-shape [name frame-id svg-data {:keys [attrs] :as data}]
|
(defn create-path-shape [name frame-id svg-data {:keys [attrs] :as data}]
|
||||||
(when (and (contains? attrs :d) (seq (:d attrs)))
|
(when (and (contains? attrs :d) (seq (:d attrs)))
|
||||||
|
|
|
@ -442,7 +442,9 @@
|
||||||
group (gsh/selection-rect shapes)
|
group (gsh/selection-rect shapes)
|
||||||
group-center (gsh/center-selrect group)
|
group-center (gsh/center-selrect group)
|
||||||
initial-angle (gpt/angle @ms/mouse-position group-center)
|
initial-angle (gpt/angle @ms/mouse-position group-center)
|
||||||
calculate-angle (fn [pos ctrl? shift?]
|
|
||||||
|
calculate-angle
|
||||||
|
(fn [pos ctrl? shift?]
|
||||||
(let [angle (- (gpt/angle pos group-center) initial-angle)
|
(let [angle (- (gpt/angle pos group-center) initial-angle)
|
||||||
angle (if (neg? angle) (+ 360 angle) angle)
|
angle (if (neg? angle) (+ 360 angle) angle)
|
||||||
angle (if (= angle 360)
|
angle (if (= angle 360)
|
||||||
|
@ -459,7 +461,8 @@
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
(rx/with-latest vector ms/mouse-position-ctrl)
|
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||||
(rx/with-latest vector ms/mouse-position-shift)
|
(rx/with-latest vector ms/mouse-position-shift)
|
||||||
(rx/map (fn [[[pos ctrl?] shift?]]
|
(rx/map
|
||||||
|
(fn [[[pos ctrl?] shift?]]
|
||||||
(let [delta-angle (calculate-angle pos ctrl? shift?)]
|
(let [delta-angle (calculate-angle pos ctrl? shift?)]
|
||||||
(set-rotation-modifiers delta-angle shapes group-center))))
|
(set-rotation-modifiers delta-angle shapes group-center))))
|
||||||
(rx/take-until stoper))
|
(rx/take-until stoper))
|
||||||
|
|
|
@ -256,16 +256,14 @@
|
||||||
filter-shapes (into #{} (map :id shapes))
|
filter-shapes (into #{} (map :id shapes))
|
||||||
remove-snap? (make-remove-snap layout filter-shapes objects focus)
|
remove-snap? (make-remove-snap layout filter-shapes objects focus)
|
||||||
|
|
||||||
shape (if (> (count shapes) 1)
|
snap-points
|
||||||
(->> shapes (map gsh/transform-shape) gsh/selection-rect (gsh/setup {:type :rect}))
|
(->> shapes
|
||||||
(->> shapes (first)))
|
(gsh/selection-rect)
|
||||||
|
(sp/selrect-snap-points)
|
||||||
shapes-points (->> shape
|
|
||||||
(sp/shape-snap-points)
|
|
||||||
;; Move the points in the translation vector
|
;; Move the points in the translation vector
|
||||||
(map #(gpt/add % movev)))]
|
(map #(gpt/add % movev)))]
|
||||||
|
|
||||||
(->> (rx/merge (closest-snap page-id frame-id shapes-points remove-snap? zoom)
|
(->> (rx/merge (closest-snap page-id frame-id snap-points remove-snap? zoom)
|
||||||
(when (contains? layout :dynamic-alignment)
|
(when (contains? layout :dynamic-alignment)
|
||||||
(closest-distance-snap page-id shapes objects zoom movev)))
|
(closest-distance-snap page-id shapes objects zoom movev)))
|
||||||
(rx/reduce combine-snaps-points)
|
(rx/reduce combine-snaps-points)
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as geom]
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.pages :as cp]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -33,7 +34,8 @@
|
||||||
(def min-selrect-side 10)
|
(def min-selrect-side 10)
|
||||||
(def small-selrect-side 30)
|
(def small-selrect-side 30)
|
||||||
|
|
||||||
(mf/defc selection-rect [{:keys [transform rect zoom color on-move-selected on-context-menu]}]
|
(mf/defc selection-rect
|
||||||
|
[{:keys [transform rect zoom color on-move-selected on-context-menu]}]
|
||||||
(when rect
|
(when rect
|
||||||
(let [{:keys [x y width height]} rect]
|
(let [{:keys [x y width height]} rect]
|
||||||
[:rect.main.viewport-selrect
|
[:rect.main.viewport-selrect
|
||||||
|
@ -117,10 +119,7 @@
|
||||||
(when show-resize-point?
|
(when show-resize-point?
|
||||||
{:type :resize-point
|
{:type :resize-point
|
||||||
:position :bottom-left
|
:position :bottom-left
|
||||||
:props {:cx x :cy (+ y height) :align align}})
|
:props {:cx x :cy (+ y height) :align align}})]
|
||||||
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
(filterv (comp not nil?)))))
|
(filterv (comp not nil?)))))
|
||||||
|
|
||||||
|
@ -185,8 +184,7 @@
|
||||||
:style {:fill (if (debug? :resize-handler) "red" "none")
|
:style {:fill (if (debug? :resize-handler) "red" "none")
|
||||||
:stroke (if (debug? :resize-handler) "red" "none")
|
:stroke (if (debug? :resize-handler) "red" "none")
|
||||||
:stroke-width 0
|
:stroke-width 0
|
||||||
:cursor cursor}}]
|
:cursor cursor}}])]))
|
||||||
)]))
|
|
||||||
|
|
||||||
(mf/defc resize-side-handler
|
(mf/defc resize-side-handler
|
||||||
"The side handler is always rendered horizontally and then rotated"
|
"The side handler is always rendered horizontally and then rotated"
|
||||||
|
@ -265,7 +263,7 @@
|
||||||
current-transform (mf/deref refs/current-transform)
|
current-transform (mf/deref refs/current-transform)
|
||||||
|
|
||||||
selrect (:selrect shape)
|
selrect (:selrect shape)
|
||||||
transform (geom/transform-matrix shape {:no-flip true})
|
transform (gsh/transform-matrix shape {:no-flip true})
|
||||||
|
|
||||||
rotation (-> (gpt/point 1 0)
|
rotation (-> (gpt/point 1 0)
|
||||||
(gpt/transform (:transform shape))
|
(gpt/transform (:transform shape))
|
||||||
|
@ -298,7 +296,7 @@
|
||||||
(let [{:keys [x y width height]} shape]
|
(let [{:keys [x y width height]} shape]
|
||||||
[:g.controls
|
[:g.controls
|
||||||
[:rect.main {:x x :y y
|
[:rect.main {:x x :y y
|
||||||
:transform (geom/transform-matrix shape)
|
:transform (gsh/transform-matrix shape)
|
||||||
:width width
|
:width width
|
||||||
:height height
|
:height height
|
||||||
:pointer-events "visible"
|
:pointer-events "visible"
|
||||||
|
@ -312,10 +310,9 @@
|
||||||
(let [shape (mf/use-memo
|
(let [shape (mf/use-memo
|
||||||
(mf/deps shapes)
|
(mf/deps shapes)
|
||||||
#(->> shapes
|
#(->> shapes
|
||||||
(map geom/transform-shape)
|
(map gsh/transform-shape)
|
||||||
(geom/selection-rect)
|
(gsh/selection-rect)
|
||||||
(geom/setup {:type :rect})))
|
(cp/setup-shape)))
|
||||||
|
|
||||||
on-resize
|
on-resize
|
||||||
(fn [current-position _initial-position event]
|
(fn [current-position _initial-position event]
|
||||||
(when (dom/left-mouse? event)
|
(when (dom/left-mouse? event)
|
||||||
|
@ -356,7 +353,7 @@
|
||||||
(mf/defc single-handlers
|
(mf/defc single-handlers
|
||||||
[{:keys [shape zoom color disable-handlers] :as props}]
|
[{:keys [shape zoom color disable-handlers] :as props}]
|
||||||
(let [shape-id (:id shape)
|
(let [shape-id (:id shape)
|
||||||
shape (geom/transform-shape shape)
|
shape (gsh/transform-shape shape)
|
||||||
|
|
||||||
on-resize
|
on-resize
|
||||||
(fn [current-position _initial-position event]
|
(fn [current-position _initial-position event]
|
||||||
|
|
|
@ -51,21 +51,23 @@
|
||||||
|
|
||||||
(defn get-snap
|
(defn get-snap
|
||||||
[coord {:keys [shapes page-id remove-snap? zoom modifiers]}]
|
[coord {:keys [shapes page-id remove-snap? zoom modifiers]}]
|
||||||
(let [shape (if (> (count shapes) 1)
|
(let [shapes-sr
|
||||||
(->> shapes (map gsh/transform-shape) gsh/selection-rect (gsh/setup {:type :rect}))
|
(->> shapes
|
||||||
(->> shapes (first)))
|
;; Merge modifiers into shapes
|
||||||
|
(map #(merge % (get modifiers (:id %))))
|
||||||
shape (if modifiers
|
;; Create the bounding rectangle for the shapes
|
||||||
(-> shape (merge (get modifiers (:id shape))) gsh/transform-shape)
|
(gsh/selection-rect))
|
||||||
shape)
|
|
||||||
|
|
||||||
frame-id (snap/snap-frame-id shapes)]
|
frame-id (snap/snap-frame-id shapes)]
|
||||||
|
|
||||||
(->> (rx/of shape)
|
(->> (rx/of shapes-sr)
|
||||||
(rx/flat-map (fn [shape]
|
(rx/flat-map
|
||||||
(->> (sp/shape-snap-points shape)
|
(fn [selrect]
|
||||||
|
(->> (sp/selrect-snap-points selrect)
|
||||||
(map #(vector frame-id %)))))
|
(map #(vector frame-id %)))))
|
||||||
(rx/flat-map (fn [[frame-id point]]
|
|
||||||
|
(rx/flat-map
|
||||||
|
(fn [[frame-id point]]
|
||||||
(->> (snap/get-snap-points page-id frame-id remove-snap? zoom point coord)
|
(->> (snap/get-snap-points page-id frame-id remove-snap? zoom point coord)
|
||||||
(rx/map #(vector point % coord)))))
|
(rx/map #(vector point % coord)))))
|
||||||
(rx/reduce conj []))))
|
(rx/reduce conj []))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue