0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-11 23:31:21 -05:00

Fixed angle with shift in paths

This commit is contained in:
alonso.torres 2020-11-25 22:08:04 +01:00
parent 5c71601fcf
commit 89f0f24707
4 changed files with 107 additions and 78 deletions

View file

@ -55,6 +55,11 @@
;;(assert (not (nil? y)))
(Point. x y)))
(defn angle->point [{:keys [x y]} angle distance]
(point
(+ x (* distance (mth/cos angle)))
(- y (* distance (mth/sin angle)))))
(defn add
"Returns the addition of the supplied value to both
coordinates of the point as a new point."

View file

@ -20,6 +20,7 @@
[app.common.data :as cd]
[app.util.geom.path :as ugp]
[app.main.streams :as ms]
[app.main.store :as st]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.drawing.common :as common]
[app.common.geom.shapes.path :as gsp]))
@ -67,7 +68,7 @@
;; CONSTANTS
(defonce enter-keycode 13)
(defonce drag-threshold 2)
(defonce drag-threshold 5)
;; PRIVATE METHODS
@ -96,6 +97,25 @@
points (gsh/rect->points selrect)]
(assoc shape :points points :selrect selrect)))
(defn closest-angle [angle]
(cond
(or (> angle 337.5) (<= angle 22.5)) 0
(and (> angle 22.5) (<= angle 67.5)) 45
(and (> angle 67.5) (<= angle 112.5)) 90
(and (> angle 112.5) (<= angle 157.5)) 135
(and (> angle 157.5) (<= angle 202.5)) 180
(and (> angle 202.5) (<= angle 247.5)) 225
(and (> angle 247.5) (<= angle 292.5)) 270
(and (> angle 292.5) (<= angle 337.5)) 315))
(defn position-fixed-angle [point from-point]
(if (and from-point point)
(let [angle (mod (+ 360 (- (gpt/angle point from-point))) 360)
to-angle (closest-angle angle)
distance (gpt/distance point from-point)]
(gpt/angle->point from-point (mth/radians to-angle) distance))
point))
(defn next-node
"Calculates the next-node to be inserted."
[shape position prev-point prev-handler]
@ -177,6 +197,21 @@
(fn [current]
(>= (gpt/distance start current) (/ drag-threshold zoom))))
(defn drag-stream [to-stream]
(let [start @ms/mouse-position
zoom (get-in @st/state [:workspace-local :zoom] 1)
mouse-up (->> st/stream (rx/filter #(ms/mouse-up? %)))]
(->> ms/mouse-position
(rx/take-until mouse-up)
(rx/filter (dragging? start zoom))
(rx/take 1)
(rx/merge-map (fn [] to-stream)))))
(defn position-stream []
(->> ms/mouse-position
(rx/with-latest merge (->> ms/mouse-position-shift (rx/map #(hash-map :shift? %))))
(rx/with-latest merge (->> ms/mouse-position-alt (rx/map #(hash-map :alt? %))))))
;; EVENTS
(defn init-path []
@ -190,24 +225,31 @@
(-> state
(update-in [:workspace-local :edit-path id] clean-edit-state))))))
(defn preview-next-point [{:keys [x y]}]
(defn preview-next-point [{:keys [x y shift?]}]
(ptk/reify ::preview-next-point
ptk/UpdateEvent
(update [_ state]
(let [id (get-path-id state)
position (gpt/point x y)
fix-angle? shift?
last-point (get-in state [:workspace-local :edit-path id :last-point])
position (cond-> (gpt/point x y)
fix-angle? (position-fixed-angle last-point))
shape (get-in state (get-path state))
{:keys [last-point prev-handler]} (get-in state [:workspace-local :edit-path id])
command (next-node shape position last-point prev-handler)]
(assoc-in state [:workspace-local :edit-path id :preview] command)))))
(defn add-node [{:keys [x y]}]
(defn add-node [{:keys [x y shift?]}]
(ptk/reify ::add-node
ptk/UpdateEvent
(update [_ state]
(let [id (get-path-id state)
position (gpt/point x y)
{:keys [last-point prev-handler]} (get-in state [:workspace-local :edit-path id])]
fix-angle? shift?
{:keys [last-point prev-handler]} (get-in state [:workspace-local :edit-path id])
position (cond-> (gpt/point x y)
fix-angle? (position-fixed-angle last-point))
]
(if-not (= last-point position)
(-> state
(assoc-in [:workspace-local :edit-path id :last-point] position)
@ -301,16 +343,12 @@
(rx/concat
(rx/of (add-node position))
(->> position-stream
(rx/filter (dragging? start-position zoom))
(rx/take 1)
(rx/merge-map
#(rx/concat
(rx/of (start-drag-handler))
drag-events-stream
(rx/of (finish-drag))
(rx/of (close-path-drag-end)))))
(drag-stream
(rx/concat
(rx/of (start-drag-handler))
drag-events-stream
(rx/of (finish-drag))
(rx/of (close-path-drag-end))))
(rx/of (finish-path "close-path")))))))
(defn close-path-drag-end []
@ -338,16 +376,21 @@
(ptk/reify ::start-path-from-point
ptk/WatchEvent
(watch [_ state stream]
(let [mouse-up (->> stream (rx/filter #(or (end-path-event? %)
(let [start-point @ms/mouse-position
zoom (get-in state [:workspace-local :zoom])
mouse-up (->> stream (rx/filter #(or (end-path-event? %)
(ms/mouse-up? %))))
drag-events (->> ms/mouse-position
(rx/take-until mouse-up)
(rx/map #(drag-handler %)))]
(rx/concat (rx/of (add-node position))
(rx/of (start-drag-handler))
drag-events
(rx/of (finish-drag)))))))
(rx/concat
(rx/of (add-node position))
(drag-stream
(rx/concat
(rx/of (start-drag-handler))
drag-events
(rx/of (finish-drag)))))))))
(defn make-corner []
(ptk/reify ::make-corner
@ -389,14 +432,6 @@
;; EVENT STREAMS
(defn make-click-stream
[stream down-event]
(->> stream
(rx/filter ms/mouse-click?)
#_(rx/debounce 200)
(rx/first)
(rx/map #(add-node down-event))))
(defn make-drag-stream
[stream down-event zoom]
(let [mouse-up (->> stream (rx/filter #(or (end-path-event? %)
@ -407,16 +442,11 @@
(rx/concat
(rx/of (add-node down-event))
(->> ms/mouse-position
(rx/take-until mouse-up)
(rx/filter (dragging? (gpt/point down-event) zoom))
(rx/take 1)
(rx/merge-map
#(rx/concat
(rx/of (start-drag-handler))
drag-events
(rx/of (finish-drag))))))))
(drag-stream
(rx/concat
(rx/of (start-drag-handler))
drag-events
(rx/of (finish-drag)))))))
(defn make-node-events-stream
[stream]
@ -444,7 +474,7 @@
;; Mouse move preview
mousemove-events
(->> ms/mouse-position
(->> (position-stream)
(rx/take-until end-path-events)
(rx/map #(preview-next-point %)))
@ -452,7 +482,7 @@
mousedown-events
(->> mouse-down
(rx/take-until end-path-events)
(rx/with-latest merge ms/mouse-position)
(rx/with-latest merge (position-stream))
;; We change to the stream that emits the first event
(rx/switch-map
@ -608,22 +638,14 @@
(watch [_ state stream]
(let [start-position @ms/mouse-position
stopper (->> stream (rx/filter ms/mouse-up?))
zoom (get-in state [:workspace-local :zoom])
zoom (get-in state [:workspace-local :zoom])]
move-point-stream
(fn [] (rx/concat
(->> ms/mouse-position
(rx/take-until stopper)
(rx/map #(move-path-point position %)))
(rx/of (apply-content-modifiers))))]
(->> ms/mouse-position
(rx/take-until stopper)
(rx/filter (dragging? start-position zoom))
(rx/take 1)
(rx/merge-map #(move-point-stream)))
))))
(drag-stream
(rx/concat
(->> ms/mouse-position
(rx/take-until stopper)
(rx/map #(move-path-point position %)))
(rx/of (apply-content-modifiers))))))))
(defn start-move-handler
[index prefix]
@ -636,21 +658,21 @@
start-delta-x (get-in state [:workspace-local :edit-path id :content-modifiers index cx] 0)
start-delta-y (get-in state [:workspace-local :edit-path id :content-modifiers index cy] 0)]
(rx/concat
(->> ms/mouse-position
(rx/take-until (->> stream (rx/filter ms/mouse-up?)))
(rx/with-latest vector ms/mouse-position-alt)
(rx/map
(fn [[pos alt?]]
(modify-handler
id
index
prefix
(+ start-delta-x (- (:x pos) (:x start-point)))
(+ start-delta-y (- (:y pos) (:y start-point)))
(not alt?))))
)
(rx/concat (rx/of (apply-content-modifiers))))))))
(drag-stream
(rx/concat
(->> ms/mouse-position
(rx/take-until (->> stream (rx/filter ms/mouse-up?)))
(rx/with-latest vector ms/mouse-position-alt)
(rx/map
(fn [[pos alt?]]
(modify-handler
id
index
prefix
(+ start-delta-x (- (:x pos) (:x start-point)))
(+ start-delta-y (- (:y pos) (:y start-point)))
(not alt?)))))
(rx/concat (rx/of (apply-content-modifiers)))))))))
(defn start-draw-mode []
(ptk/reify ::start-draw-mode

View file

@ -93,7 +93,7 @@
{:alt (t locale "workspace.toolbar.path")
:class (when (= selected-drawtool :path) "selected")
:on-click (partial select-drawtool :path)}
i/curve]
i/pen]
[:li.tooltip.tooltip-right
{:alt (t locale "workspace.toolbar.comments")

View file

@ -169,8 +169,7 @@
{:cx x
:cy y
:r (if (or selected? hover?) (/ 3.5 zoom) (/ 3 zoom))
:style {:cursor (when (= edit-mode :draw) cur/pen-node)
:stroke-width (/ 1 zoom)
:style {:stroke-width (/ 1 zoom)
:stroke (cond (or selected? hover?) black-color
preview? secondary-color
:else primary-color)
@ -183,7 +182,10 @@
:on-mouse-down on-mouse-down
:on-mouse-enter on-enter
:on-mouse-leave on-leave
:style {:fill "transparent"}}]]))
:style {:cursor (cond
(and (not last-p?) (= edit-mode :draw)) cur/pen-node
(= edit-mode :move) cur/pointer-node)
:fill "transparent"}}]]))
(mf/defc path-handler [{:keys [index prefix point handler zoom selected? hover? edit-mode]}]
(when (and point handler)
@ -227,8 +229,7 @@
:width (/ 6 zoom)
:height (/ 6 zoom)
:style {:cursor cur/pointer-move
:stroke-width (/ 1 zoom)
:style {:stroke-width (/ 1 zoom)
:stroke (cond (or selected? hover?) black-color
:else primary-color)
:fill (cond selected? primary-color
@ -240,7 +241,8 @@
:on-mouse-down on-mouse-down
:on-mouse-enter on-enter
:on-mouse-leave on-leave
:style {:fill "transparent"}}]])))
:style {:cursor (when (= edit-mode :move) cur/pointer-move)
:fill "transparent"}}]])))
(mf/defc path-preview [{:keys [zoom command from]}]
[:g.preview {:style {:pointer-events "none"}}