mirror of
https://github.com/penpot/penpot.git
synced 2025-05-26 03:06:11 +02:00
✨ Improvements over selrect generation
This commit is contained in:
parent
0f54e85b36
commit
f4be3aa9de
19 changed files with 176 additions and 171 deletions
|
@ -1574,7 +1574,7 @@
|
|||
page-id (:current-page-id state)
|
||||
frame-id (-> (wsh/lookup-page-objects state page-id)
|
||||
(cph/frame-id-by-position @ms/mouse-position))
|
||||
shape (gsh/setup-selrect
|
||||
shape (cp/setup-rect-selrect
|
||||
{:id id
|
||||
:type :text
|
||||
:name "Text"
|
||||
|
@ -1667,7 +1667,7 @@
|
|||
shape (-> (cp/make-minimal-shape :frame)
|
||||
(merge {:x (:x srect) :y (:y srect) :width (:width srect) :height (:height srect)})
|
||||
(assoc :frame-id frame-id)
|
||||
(gsh/setup-selrect))]
|
||||
(cp/setup-rect-selrect))]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction)
|
||||
(dwc/add-shape shape)
|
||||
|
|
|
@ -480,7 +480,7 @@
|
|||
(merge data)
|
||||
(merge {:x x :y y})
|
||||
(assoc :frame-id frame-id)
|
||||
(gsh/setup-selrect))]
|
||||
(cp/setup-rect-selrect))]
|
||||
(rx/of (add-shape shape))))))
|
||||
|
||||
(defn image-uploaded
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.drawing.common :as common]
|
||||
|
@ -70,7 +71,10 @@
|
|||
|
||||
shape (-> state
|
||||
(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 :initialized? true)
|
||||
(assoc :click-draw? true))]
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
(ns app.main.data.workspace.drawing.common
|
||||
(:require
|
||||
[app.common.pages :as cp]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
|
@ -49,7 +50,7 @@
|
|||
(assoc :height 17 :width 4 :grow-type :auto-width)
|
||||
|
||||
click-draw?
|
||||
(gsh/setup-selrect)
|
||||
(cp/setup-rect-selrect)
|
||||
|
||||
:always
|
||||
(-> (gsh/transform-shape)
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
selrect (gsh/selection-rect shapes)
|
||||
group (-> (cp/make-minimal-group frame-id selrect gname)
|
||||
(gsh/setup selrect)
|
||||
(cp/setup-shape selrect)
|
||||
(assoc :shapes (mapv :id shapes)
|
||||
:parent-id parent-id
|
||||
:frame-id frame-id
|
||||
|
|
|
@ -103,20 +103,21 @@
|
|||
|
||||
(defn handle-area-selection
|
||||
[shift?]
|
||||
(letfn [(valid-rect? [{width :width height :height}]
|
||||
(or (> width 10) (> height 10)))]
|
||||
(letfn [(valid-rect? [zoom {width :width height :height}]
|
||||
(or (> width (/ 10 zoom)) (> height (/ 10 zoom))))]
|
||||
|
||||
(ptk/reify ::handle-area-selection
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ stream]
|
||||
(let [stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
|
||||
(watch [_ state stream]
|
||||
(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?))
|
||||
from-p @ms/mouse-position]
|
||||
(rx/concat
|
||||
(->> ms/mouse-position
|
||||
(rx/take-until stoper)
|
||||
(rx/map #(gsh/points->rect [from-p %]))
|
||||
(rx/filter valid-rect?)
|
||||
(rx/filter (partial valid-rect? zoom))
|
||||
(rx/map update-area-selection))
|
||||
|
||||
(rx/of (select-node-area shift?)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.changes-builder :as pcb]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :refer [max-safe-int min-safe-int]]
|
||||
[app.common.uuid :as uuid]
|
||||
|
@ -165,7 +166,7 @@
|
|||
(assoc :svg-attrs attrs)
|
||||
(assoc :svg-viewbox (-> (select-keys svg-data [:width :height])
|
||||
(assoc :x offset-x :y offset-y)))
|
||||
(gsh/setup-selrect))))
|
||||
(cp/setup-rect-selrect))))
|
||||
|
||||
(defn create-svg-root [frame-id svg-data]
|
||||
(let [{:keys [name x y width height offset-x offset-y]} svg-data]
|
||||
|
@ -177,7 +178,7 @@
|
|||
:height height
|
||||
:x (+ x offset-x)
|
||||
:y (+ y offset-y)}
|
||||
(gsh/setup-selrect)
|
||||
(cp/setup-rect-selrect)
|
||||
(assoc :svg-attrs (-> (:attrs svg-data)
|
||||
(dissoc :viewBox :xmlns)
|
||||
(d/without-keys usvg/inheritable-props))))))
|
||||
|
@ -197,7 +198,7 @@
|
|||
(assoc :svg-attrs (d/without-keys attrs usvg/inheritable-props))
|
||||
(assoc :svg-viewbox (-> (select-keys svg-data [:width :height])
|
||||
(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}]
|
||||
(when (and (contains? attrs :d) (seq (:d attrs)))
|
||||
|
|
|
@ -442,26 +442,29 @@
|
|||
group (gsh/selection-rect shapes)
|
||||
group-center (gsh/center-selrect group)
|
||||
initial-angle (gpt/angle @ms/mouse-position group-center)
|
||||
calculate-angle (fn [pos ctrl? shift?]
|
||||
(let [angle (- (gpt/angle pos group-center) initial-angle)
|
||||
angle (if (neg? angle) (+ 360 angle) angle)
|
||||
angle (if (= angle 360)
|
||||
0
|
||||
angle)
|
||||
angle (if ctrl?
|
||||
(* (mth/floor (/ angle 45)) 45)
|
||||
angle)
|
||||
angle (if shift?
|
||||
(* (mth/floor (/ angle 15)) 15)
|
||||
angle)]
|
||||
angle))]
|
||||
|
||||
calculate-angle
|
||||
(fn [pos ctrl? shift?]
|
||||
(let [angle (- (gpt/angle pos group-center) initial-angle)
|
||||
angle (if (neg? angle) (+ 360 angle) angle)
|
||||
angle (if (= angle 360)
|
||||
0
|
||||
angle)
|
||||
angle (if ctrl?
|
||||
(* (mth/floor (/ angle 45)) 45)
|
||||
angle)
|
||||
angle (if shift?
|
||||
(* (mth/floor (/ angle 15)) 15)
|
||||
angle)]
|
||||
angle))]
|
||||
(rx/concat
|
||||
(->> ms/mouse-position
|
||||
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||
(rx/with-latest vector ms/mouse-position-shift)
|
||||
(rx/map (fn [[[pos ctrl?] shift?]]
|
||||
(let [delta-angle (calculate-angle pos ctrl? shift?)]
|
||||
(set-rotation-modifiers delta-angle shapes group-center))))
|
||||
(rx/map
|
||||
(fn [[[pos ctrl?] shift?]]
|
||||
(let [delta-angle (calculate-angle pos ctrl? shift?)]
|
||||
(set-rotation-modifiers delta-angle shapes group-center))))
|
||||
(rx/take-until stoper))
|
||||
(rx/of (apply-modifiers (map :id shapes))
|
||||
(finish-transform)))))))
|
||||
|
|
|
@ -256,16 +256,14 @@
|
|||
filter-shapes (into #{} (map :id shapes))
|
||||
remove-snap? (make-remove-snap layout filter-shapes objects focus)
|
||||
|
||||
shape (if (> (count shapes) 1)
|
||||
(->> shapes (map gsh/transform-shape) gsh/selection-rect (gsh/setup {:type :rect}))
|
||||
(->> shapes (first)))
|
||||
snap-points
|
||||
(->> shapes
|
||||
(gsh/selection-rect)
|
||||
(sp/selrect-snap-points)
|
||||
;; Move the points in the translation vector
|
||||
(map #(gpt/add % movev)))]
|
||||
|
||||
shapes-points (->> shape
|
||||
(sp/shape-snap-points)
|
||||
;; Move the points in the translation vector
|
||||
(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)
|
||||
(closest-distance-snap page-id shapes objects zoom movev)))
|
||||
(rx/reduce combine-snaps-points)
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
(:require
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[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.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
|
@ -33,7 +34,8 @@
|
|||
(def min-selrect-side 10)
|
||||
(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
|
||||
(let [{:keys [x y width height]} rect]
|
||||
[:rect.main.viewport-selrect
|
||||
|
@ -117,10 +119,7 @@
|
|||
(when show-resize-point?
|
||||
{:type :resize-point
|
||||
:position :bottom-left
|
||||
:props {:cx x :cy (+ y height) :align align}})
|
||||
|
||||
|
||||
]
|
||||
:props {:cx x :cy (+ y height) :align align}})]
|
||||
|
||||
(filterv (comp not nil?)))))
|
||||
|
||||
|
@ -185,8 +184,7 @@
|
|||
:style {:fill (if (debug? :resize-handler) "red" "none")
|
||||
:stroke (if (debug? :resize-handler) "red" "none")
|
||||
:stroke-width 0
|
||||
:cursor cursor}}]
|
||||
)]))
|
||||
:cursor cursor}}])]))
|
||||
|
||||
(mf/defc resize-side-handler
|
||||
"The side handler is always rendered horizontally and then rotated"
|
||||
|
@ -265,7 +263,7 @@
|
|||
current-transform (mf/deref refs/current-transform)
|
||||
|
||||
selrect (:selrect shape)
|
||||
transform (geom/transform-matrix shape {:no-flip true})
|
||||
transform (gsh/transform-matrix shape {:no-flip true})
|
||||
|
||||
rotation (-> (gpt/point 1 0)
|
||||
(gpt/transform (:transform shape))
|
||||
|
@ -298,7 +296,7 @@
|
|||
(let [{:keys [x y width height]} shape]
|
||||
[:g.controls
|
||||
[:rect.main {:x x :y y
|
||||
:transform (geom/transform-matrix shape)
|
||||
:transform (gsh/transform-matrix shape)
|
||||
:width width
|
||||
:height height
|
||||
:pointer-events "visible"
|
||||
|
@ -312,10 +310,9 @@
|
|||
(let [shape (mf/use-memo
|
||||
(mf/deps shapes)
|
||||
#(->> shapes
|
||||
(map geom/transform-shape)
|
||||
(geom/selection-rect)
|
||||
(geom/setup {:type :rect})))
|
||||
|
||||
(map gsh/transform-shape)
|
||||
(gsh/selection-rect)
|
||||
(cp/setup-shape)))
|
||||
on-resize
|
||||
(fn [current-position _initial-position event]
|
||||
(when (dom/left-mouse? event)
|
||||
|
@ -356,7 +353,7 @@
|
|||
(mf/defc single-handlers
|
||||
[{:keys [shape zoom color disable-handlers] :as props}]
|
||||
(let [shape-id (:id shape)
|
||||
shape (geom/transform-shape shape)
|
||||
shape (gsh/transform-shape shape)
|
||||
|
||||
on-resize
|
||||
(fn [current-position _initial-position event]
|
||||
|
|
|
@ -51,23 +51,25 @@
|
|||
|
||||
(defn get-snap
|
||||
[coord {:keys [shapes page-id remove-snap? zoom modifiers]}]
|
||||
(let [shape (if (> (count shapes) 1)
|
||||
(->> shapes (map gsh/transform-shape) gsh/selection-rect (gsh/setup {:type :rect}))
|
||||
(->> shapes (first)))
|
||||
|
||||
shape (if modifiers
|
||||
(-> shape (merge (get modifiers (:id shape))) gsh/transform-shape)
|
||||
shape)
|
||||
(let [shapes-sr
|
||||
(->> shapes
|
||||
;; Merge modifiers into shapes
|
||||
(map #(merge % (get modifiers (:id %))))
|
||||
;; Create the bounding rectangle for the shapes
|
||||
(gsh/selection-rect))
|
||||
|
||||
frame-id (snap/snap-frame-id shapes)]
|
||||
|
||||
(->> (rx/of shape)
|
||||
(rx/flat-map (fn [shape]
|
||||
(->> (sp/shape-snap-points shape)
|
||||
(map #(vector frame-id %)))))
|
||||
(rx/flat-map (fn [[frame-id point]]
|
||||
(->> (snap/get-snap-points page-id frame-id remove-snap? zoom point coord)
|
||||
(rx/map #(vector point % coord)))))
|
||||
(->> (rx/of shapes-sr)
|
||||
(rx/flat-map
|
||||
(fn [selrect]
|
||||
(->> (sp/selrect-snap-points selrect)
|
||||
(map #(vector frame-id %)))))
|
||||
|
||||
(rx/flat-map
|
||||
(fn [[frame-id point]]
|
||||
(->> (snap/get-snap-points page-id frame-id remove-snap? zoom point coord)
|
||||
(rx/map #(vector point % coord)))))
|
||||
(rx/reduce conj []))))
|
||||
|
||||
(defn- flip
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue