mirror of
https://github.com/penpot/penpot.git
synced 2025-06-07 15:31:37 +02:00
Merge pull request #247 from uxbox/488/snap_grid_imprecision
Fixes problem with snap imprecisions
This commit is contained in:
commit
aed3113a7a
6 changed files with 36 additions and 30 deletions
|
@ -64,8 +64,9 @@
|
||||||
(rx/of handle-drawing-generic)))))
|
(rx/of handle-drawing-generic)))))
|
||||||
|
|
||||||
(def handle-drawing-generic
|
(def handle-drawing-generic
|
||||||
(letfn [(resize-shape [{:keys [x y] :as shape} point lock? point-snap]
|
(letfn [(resize-shape [{:keys [x y width height] :as shape} point lock? point-snap]
|
||||||
(let [initial (gpt/point x y)
|
(let [;; The new shape behaves like a resize on the bottom-right corner
|
||||||
|
initial (gpt/point (+ x width) (+ y height))
|
||||||
shape' (geom/shape->rect-shape shape)
|
shape' (geom/shape->rect-shape shape)
|
||||||
shapev (gpt/point (:width shape') (:height shape'))
|
shapev (gpt/point (:width shape') (:height shape'))
|
||||||
deltav (gpt/to-vec initial point-snap)
|
deltav (gpt/to-vec initial point-snap)
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
|
|
||||||
;; -- RESIZE
|
;; -- RESIZE
|
||||||
(defn start-resize
|
(defn start-resize
|
||||||
[handler ids shape]
|
[handler initial ids shape]
|
||||||
(letfn [(resize [shape initial resizing-shapes [point lock? point-snap]]
|
(letfn [(resize [shape initial resizing-shapes [point lock? point-snap]]
|
||||||
(let [{:keys [width height rotation]} shape
|
(let [{:keys [width height rotation]} shape
|
||||||
shapev (-> (gpt/point width height))
|
shapev (-> (gpt/point width height))
|
||||||
|
@ -132,7 +132,8 @@
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [initial @ms/mouse-position
|
(let [current-pointer @ms/mouse-position
|
||||||
|
initial-position (merge current-pointer initial)
|
||||||
stoper (rx/filter ms/mouse-up? stream)
|
stoper (rx/filter ms/mouse-up? stream)
|
||||||
page-id (get state :current-page-id)
|
page-id (get state :current-page-id)
|
||||||
resizing-shapes (map #(get-in state [:workspace-data page-id :objects %]) ids)
|
resizing-shapes (map #(get-in state [:workspace-data page-id :objects %]) ids)
|
||||||
|
@ -144,7 +145,7 @@
|
||||||
(rx/switch-map (fn [[point :as current]]
|
(rx/switch-map (fn [[point :as current]]
|
||||||
(->> (snap/closest-snap-point page-id resizing-shapes layout point)
|
(->> (snap/closest-snap-point page-id resizing-shapes layout point)
|
||||||
(rx/map #(conj current %)))))
|
(rx/map #(conj current %)))))
|
||||||
(rx/mapcat (partial resize shape initial resizing-shapes))
|
(rx/mapcat (partial resize shape initial-position resizing-shapes))
|
||||||
(rx/take-until stoper))
|
(rx/take-until stoper))
|
||||||
#_(rx/empty)
|
#_(rx/empty)
|
||||||
(rx/of (apply-modifiers ids)
|
(rx/of (apply-modifiers ids)
|
||||||
|
|
|
@ -178,7 +178,7 @@
|
||||||
(->> (closest-snap page-id frame-id [point] filter-shapes)
|
(->> (closest-snap page-id frame-id [point] filter-shapes)
|
||||||
(rx/map #(or % (gpt/point 0 0)))
|
(rx/map #(or % (gpt/point 0 0)))
|
||||||
(rx/map #(gpt/add point %))
|
(rx/map #(gpt/add point %))
|
||||||
(rx/map gpt/round))))
|
)))
|
||||||
|
|
||||||
(defn closest-snap-move
|
(defn closest-snap-move
|
||||||
[page-id shapes objects layout movev]
|
[page-id shapes objects layout movev]
|
||||||
|
|
|
@ -147,12 +147,12 @@
|
||||||
:width (/ resize-point-rect-size zoom)
|
:width (/ resize-point-rect-size zoom)
|
||||||
:height (/ resize-point-rect-size zoom)
|
:height (/ resize-point-rect-size zoom)
|
||||||
:fill (if (debug? :resize-handler) "red" "transparent")
|
:fill (if (debug? :resize-handler) "red" "transparent")
|
||||||
:on-mouse-down on-resize
|
:on-mouse-down #(on-resize {:x cx' :y cy'} %)
|
||||||
:style {:cursor (if (#{:top-left :bottom-right} position)
|
:style {:cursor (if (#{:top-left :bottom-right} position)
|
||||||
(cur/resize-nesw rotation) (cur/resize-nwse rotation))}
|
(cur/resize-nesw rotation) (cur/resize-nwse rotation))}
|
||||||
:transform (gmt/multiply transform
|
:transform (gmt/multiply transform
|
||||||
(gmt/rotate-matrix rot-square (gpt/point cx cy)))}]
|
(gmt/rotate-matrix rot-square (gpt/point cx cy)))}]
|
||||||
[:circle {:on-mouse-down on-resize
|
[:circle {:on-mouse-down #(on-resize {:x cx' :y cy'} %)
|
||||||
:r (/ resize-point-circle-radius zoom)
|
:r (/ resize-point-circle-radius zoom)
|
||||||
:fill (if (debug? :resize-handler) "red" "transparent")
|
:fill (if (debug? :resize-handler) "red" "transparent")
|
||||||
:cx cx'
|
:cx cx'
|
||||||
|
@ -162,17 +162,20 @@
|
||||||
]))
|
]))
|
||||||
|
|
||||||
(mf/defc resize-side-handler [{:keys [x y length angle zoom position rotation transform on-resize]}]
|
(mf/defc resize-side-handler [{:keys [x y length angle zoom position rotation transform on-resize]}]
|
||||||
|
(let [res-point (if (#{:top :bottom} position)
|
||||||
|
{:y y}
|
||||||
|
{:x x})]
|
||||||
[:rect {:x (+ x (/ resize-point-rect-size zoom))
|
[:rect {:x (+ x (/ resize-point-rect-size zoom))
|
||||||
:y (- y (/ resize-side-height 2 zoom))
|
:y (- y (/ resize-side-height 2 zoom))
|
||||||
:width (max 0 (- length (/ (* resize-point-rect-size 2) zoom)))
|
:width (max 0 (- length (/ (* resize-point-rect-size 2) zoom)))
|
||||||
:height (/ resize-side-height zoom)
|
:height (/ resize-side-height zoom)
|
||||||
:transform (gmt/multiply transform
|
:transform (gmt/multiply transform
|
||||||
(gmt/rotate-matrix angle (gpt/point x y)))
|
(gmt/rotate-matrix angle (gpt/point x y)))
|
||||||
:on-mouse-down on-resize
|
:on-mouse-down #(on-resize res-point %)
|
||||||
:style {:fill (if (debug? :resize-handler) "yellow" "transparent")
|
:style {:fill (if (debug? :resize-handler) "yellow" "transparent")
|
||||||
:cursor (if (#{:left :right} position)
|
:cursor (if (#{:left :right} position)
|
||||||
(cur/resize-ew rotation)
|
(cur/resize-ew rotation)
|
||||||
(cur/resize-ns rotation)) }}])
|
(cur/resize-ns rotation)) }}]))
|
||||||
|
|
||||||
(mf/defc controls
|
(mf/defc controls
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
|
@ -268,8 +271,9 @@
|
||||||
[{:keys [shapes selected zoom] :as props}]
|
[{:keys [shapes selected zoom] :as props}]
|
||||||
(let [shape (geom/selection-rect shapes)
|
(let [shape (geom/selection-rect shapes)
|
||||||
shape-center (geom/center shape)
|
shape-center (geom/center shape)
|
||||||
on-resize #(do (dom/stop-propagation %2)
|
on-resize (fn [current-position initial-position event]
|
||||||
(st/emit! (dw/start-resize %1 selected shape)))
|
(dom/stop-propagation event)
|
||||||
|
(st/emit! (dw/start-resize current-position initial-position selected shape)))
|
||||||
|
|
||||||
on-rotate #(do (dom/stop-propagation %)
|
on-rotate #(do (dom/stop-propagation %)
|
||||||
(st/emit! (dw/start-rotate shapes)))]
|
(st/emit! (dw/start-rotate shapes)))]
|
||||||
|
@ -287,9 +291,9 @@
|
||||||
(let [shape-id (:id shape)
|
(let [shape-id (:id shape)
|
||||||
shape (geom/transform-shape shape)
|
shape (geom/transform-shape shape)
|
||||||
shape' (if (debug? :simple-selection) (geom/selection-rect [shape]) shape)
|
shape' (if (debug? :simple-selection) (geom/selection-rect [shape]) shape)
|
||||||
on-resize
|
on-resize (fn [current-position initial-position event]
|
||||||
#(do (dom/stop-propagation %2)
|
(dom/stop-propagation event)
|
||||||
(st/emit! (dw/start-resize %1 #{shape-id} shape')))
|
(st/emit! (dw/start-resize current-position initial-position #{shape-id} shape')))
|
||||||
|
|
||||||
on-rotate
|
on-rotate
|
||||||
#(do (dom/stop-propagation %)
|
#(do (dom/stop-propagation %)
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
frame-length (if (= :column (:type grid)) (:width frame) (:height frame))
|
frame-length (if (= :column (:type grid)) (:width frame) (:height frame))
|
||||||
item-length (if (or (nil? size) (= :auto size))
|
item-length (if (or (nil? size) (= :auto size))
|
||||||
(-> (gg/calculate-default-item-length frame-length margin gutter)
|
(-> (gg/calculate-default-item-length frame-length margin gutter)
|
||||||
(mth/round))
|
(mth/precision 2))
|
||||||
item-length)]
|
item-length)]
|
||||||
(emit-changes! #(-> %
|
(emit-changes! #(-> %
|
||||||
(assoc-in [:params :size] size)
|
(assoc-in [:params :size] size)
|
||||||
|
|
|
@ -94,7 +94,7 @@
|
||||||
:on-change on-width-change
|
:on-change on-width-change
|
||||||
:value (str (-> (:width shape)
|
:value (str (-> (:width shape)
|
||||||
(d/coalesce 0)
|
(d/coalesce 0)
|
||||||
(math/round)))}]]
|
(math/precision 2)))}]]
|
||||||
|
|
||||||
|
|
||||||
[:div.input-element.height
|
[:div.input-element.height
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
:on-change on-height-change
|
:on-change on-height-change
|
||||||
:value (str (-> (:height shape)
|
:value (str (-> (:height shape)
|
||||||
(d/coalesce 0)
|
(d/coalesce 0)
|
||||||
(math/round)))}]]])
|
(math/precision 2)))}]]])
|
||||||
|
|
||||||
;; POSITION
|
;; POSITION
|
||||||
(when (options :position)
|
(when (options :position)
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
:on-change on-rotation-change
|
:on-change on-rotation-change
|
||||||
:value (str (-> (:rotation shape)
|
:value (str (-> (:rotation shape)
|
||||||
(d/coalesce 0)
|
(d/coalesce 0)
|
||||||
(math/round)))}]]
|
(math/precision 2)))}]]
|
||||||
[:input.slidebar
|
[:input.slidebar
|
||||||
{:type "range"
|
{:type "range"
|
||||||
:min "0"
|
:min "0"
|
||||||
|
@ -150,7 +150,7 @@
|
||||||
:on-change on-rotation-change
|
:on-change on-rotation-change
|
||||||
:value (str (-> (:rotation shape)
|
:value (str (-> (:rotation shape)
|
||||||
(d/coalesce 0)
|
(d/coalesce 0)
|
||||||
(math/round)))}]])
|
(math/precision 2)))}]])
|
||||||
|
|
||||||
(when (options :radius)
|
(when (options :radius)
|
||||||
[:div.row-flex
|
[:div.row-flex
|
||||||
|
@ -163,5 +163,5 @@
|
||||||
:on-change on-radius-change
|
:on-change on-radius-change
|
||||||
:value (str (-> (:rx shape)
|
:value (str (-> (:rx shape)
|
||||||
(d/coalesce 0)
|
(d/coalesce 0)
|
||||||
(math/round)))}]]
|
(math/precision 2)))}]]
|
||||||
[:div.input-element]])]]))
|
[:div.input-element]])]]))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue