mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 16:21:57 -05:00
♻️ Refactor drawing effects
This commit is contained in:
parent
67ed1d89ac
commit
10a24d68c9
5 changed files with 187 additions and 164 deletions
|
@ -57,13 +57,13 @@
|
|||
(watch [_ state stream]
|
||||
(rx/of (case type
|
||||
:path
|
||||
path/handle-drawing-path
|
||||
(path/handle-drawing-path)
|
||||
|
||||
:curve
|
||||
curve/handle-drawing-curve
|
||||
(curve/handle-drawing-curve)
|
||||
|
||||
;; default
|
||||
box/handle-drawing-box)))))
|
||||
(box/handle-drawing-box))))))
|
||||
|
||||
;; Export
|
||||
(def close-drawing-path path/close-drawing-path)
|
||||
|
|
|
@ -20,72 +20,72 @@
|
|||
[app.main.streams :as ms]
|
||||
[app.main.data.workspace.drawing.common :as common]))
|
||||
|
||||
(def handle-drawing-box
|
||||
(letfn [(resize-shape [{:keys [x y width height] :as shape} point lock? point-snap]
|
||||
(let [;; The new shape behaves like a resize on the bottom-right corner
|
||||
initial (gpt/point (+ x width) (+ y height))
|
||||
shapev (gpt/point width height)
|
||||
deltav (gpt/to-vec initial point-snap)
|
||||
scalev (gpt/divide (gpt/add shapev deltav) shapev)
|
||||
scalev (if lock?
|
||||
(let [v (max (:x scalev) (:y scalev))]
|
||||
(gpt/point v v))
|
||||
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))))
|
||||
(defn resize-shape [{:keys [x y width height] :as shape} point lock? point-snap]
|
||||
(let [;; The new shape behaves like a resize on the bottom-right corner
|
||||
initial (gpt/point (+ x width) (+ y height))
|
||||
shapev (gpt/point width height)
|
||||
deltav (gpt/to-vec initial point-snap)
|
||||
scalev (gpt/divide (gpt/add shapev deltav) shapev)
|
||||
scalev (if lock?
|
||||
(let [v (max (:x scalev) (:y scalev))]
|
||||
(gpt/point v v))
|
||||
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))))
|
||||
|
||||
(update-drawing [state point lock? point-snap]
|
||||
(update-in state [:workspace-drawing :object] resize-shape point lock? point-snap))]
|
||||
(defn update-drawing [state point lock? point-snap]
|
||||
(update-in state [:workspace-drawing :object] resize-shape point lock? point-snap))
|
||||
|
||||
(ptk/reify ::handle-drawing-box
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [{:keys [flags]} (:workspace-local state)
|
||||
(defn handle-drawing-box []
|
||||
(ptk/reify ::handle-drawing-box
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [{:keys [flags]} (:workspace-local state)
|
||||
|
||||
stoper? #(or (ms/mouse-up? %) (= % :interrupt))
|
||||
stoper (rx/filter stoper? stream)
|
||||
initial @ms/mouse-position
|
||||
stoper? #(or (ms/mouse-up? %) (= % :interrupt))
|
||||
stoper (rx/filter stoper? stream)
|
||||
initial @ms/mouse-position
|
||||
|
||||
|
||||
page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
layout (get state :workspace-layout)
|
||||
page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
layout (get state :workspace-layout)
|
||||
|
||||
frames (cph/select-frames objects)
|
||||
fid (or (->> frames
|
||||
(filter #(gsh/has-point? % initial))
|
||||
first
|
||||
:id)
|
||||
uuid/zero)
|
||||
frames (cph/select-frames objects)
|
||||
fid (or (->> frames
|
||||
(filter #(gsh/has-point? % initial))
|
||||
first
|
||||
:id)
|
||||
uuid/zero)
|
||||
|
||||
shape (-> state
|
||||
(get-in [:workspace-drawing :object])
|
||||
(gsh/setup {:x (:x initial) :y (:y initial) :width 1 :height 1})
|
||||
(assoc :frame-id fid)
|
||||
(assoc :initialized? true)
|
||||
(assoc :click-draw? true))]
|
||||
(rx/concat
|
||||
;; Add shape to drawing state
|
||||
(rx/of #(assoc-in state [:workspace-drawing :object] shape))
|
||||
shape (-> state
|
||||
(get-in [:workspace-drawing :object])
|
||||
(gsh/setup {:x (:x initial) :y (:y initial) :width 1 :height 1})
|
||||
(assoc :frame-id fid)
|
||||
(assoc :initialized? true)
|
||||
(assoc :click-draw? true))]
|
||||
(rx/concat
|
||||
;; Add shape to drawing state
|
||||
(rx/of #(assoc-in state [:workspace-drawing :object] shape))
|
||||
|
||||
;; Initial SNAP
|
||||
(->> (snap/closest-snap-point page-id [shape] layout initial)
|
||||
(rx/map (fn [{:keys [x y]}]
|
||||
#(update-in % [:workspace-drawing :object] assoc :x x :y y))))
|
||||
;; Initial SNAP
|
||||
(->> (snap/closest-snap-point page-id [shape] layout initial)
|
||||
(rx/map (fn [{:keys [x y]}]
|
||||
#(update-in % [:workspace-drawing :object] assoc :x x :y y))))
|
||||
|
||||
(->> ms/mouse-position
|
||||
(rx/filter #(> (gpt/distance % initial) 2))
|
||||
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||
(rx/switch-map
|
||||
(fn [[point :as current]]
|
||||
(->> (snap/closest-snap-point page-id [shape] layout point)
|
||||
(rx/map #(conj current %)))))
|
||||
(rx/map
|
||||
(fn [[pt ctrl? point-snap]]
|
||||
#(update-drawing % pt ctrl? point-snap)))
|
||||
(->> ms/mouse-position
|
||||
(rx/filter #(> (gpt/distance % initial) 2))
|
||||
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||
(rx/switch-map
|
||||
(fn [[point :as current]]
|
||||
(->> (snap/closest-snap-point page-id [shape] layout point)
|
||||
(rx/map #(conj current %)))))
|
||||
(rx/map
|
||||
(fn [[pt ctrl? point-snap]]
|
||||
#(update-drawing % pt ctrl? point-snap)))
|
||||
|
||||
(rx/take-until stoper))
|
||||
(rx/of common/handle-finish-drawing)))))))
|
||||
(rx/take-until stoper))
|
||||
(rx/of common/handle-finish-drawing))))))
|
||||
|
|
|
@ -18,34 +18,34 @@
|
|||
|
||||
(def simplify-tolerance 0.3)
|
||||
|
||||
(def handle-drawing-curve
|
||||
(letfn [(stoper-event? [{:keys [type shift] :as event}]
|
||||
(ms/mouse-event? event) (= type :up))
|
||||
(defn stoper-event? [{:keys [type shift] :as event}]
|
||||
(ms/mouse-event? event) (= type :up))
|
||||
|
||||
(initialize-drawing [state]
|
||||
(assoc-in state [:workspace-drawing :object :initialized?] true))
|
||||
(defn initialize-drawing [state]
|
||||
(assoc-in state [:workspace-drawing :object :initialized?] true))
|
||||
|
||||
(insert-point-segment [state point]
|
||||
(update-in state [:workspace-drawing :object :segments] (fnil conj []) point))
|
||||
(defn insert-point-segment [state point]
|
||||
(update-in state [:workspace-drawing :object :segments] (fnil conj []) point))
|
||||
|
||||
(finish-drawing-curve [state]
|
||||
(update-in
|
||||
state [:workspace-drawing :object]
|
||||
(fn [shape]
|
||||
(-> shape
|
||||
(update :segments #(path/simplify % simplify-tolerance))
|
||||
(gsh/update-path-selrect)))))]
|
||||
(defn finish-drawing-curve [state]
|
||||
(update-in
|
||||
state [:workspace-drawing :object]
|
||||
(fn [shape]
|
||||
(-> shape
|
||||
(update :segments #(path/simplify % simplify-tolerance))
|
||||
(gsh/update-path-selrect)))))
|
||||
|
||||
(ptk/reify ::handle-drawing-curve
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [{:keys [flags]} (:workspace-local state)
|
||||
stoper (rx/filter stoper-event? stream)
|
||||
mouse (rx/sample 10 ms/mouse-position)]
|
||||
(rx/concat
|
||||
(rx/of initialize-drawing)
|
||||
(->> mouse
|
||||
(rx/map (fn [pt] #(insert-point-segment % pt)))
|
||||
(rx/take-until stoper))
|
||||
(rx/of finish-drawing-curve
|
||||
common/handle-finish-drawing)))))))
|
||||
(defn handle-drawing-curve []
|
||||
(ptk/reify ::handle-drawing-curve
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [{:keys [flags]} (:workspace-local state)
|
||||
stoper (rx/filter stoper-event? stream)
|
||||
mouse (rx/sample 10 ms/mouse-position)]
|
||||
(rx/concat
|
||||
(rx/of initialize-drawing)
|
||||
(->> mouse
|
||||
(rx/map (fn [pt] #(insert-point-segment % pt)))
|
||||
(rx/take-until stoper))
|
||||
(rx/of finish-drawing-curve
|
||||
common/handle-finish-drawing))))))
|
||||
|
|
|
@ -17,97 +17,115 @@
|
|||
[app.util.geom.path :as path]
|
||||
[app.main.data.workspace.drawing.common :as common]))
|
||||
|
||||
(def handle-drawing-path
|
||||
(letfn [(stoper-event? [{:keys [type shift] :as event}]
|
||||
(or (= event ::end-path-drawing)
|
||||
(= event :interrupt)
|
||||
(and (ms/mouse-event? event)
|
||||
(or (= type :double-click)
|
||||
(= type :context-menu)))
|
||||
(and (ms/keyboard-event? event)
|
||||
(= type :down)
|
||||
(= 13 (:key event)))))
|
||||
(defn stoper-event? [{:keys [type shift] :as event}]
|
||||
(or (= event ::end-path-drawing)
|
||||
(= event :interrupt)
|
||||
(and (ms/mouse-event? event)
|
||||
(or (= type :double-click)
|
||||
(= type :context-menu)))
|
||||
(and (ms/keyboard-event? event)
|
||||
(= type :down)
|
||||
(= 13 (:key event)))))
|
||||
|
||||
(initialize-drawing [state point]
|
||||
(-> state
|
||||
(assoc-in [:workspace-drawing :object :segments] [point point])
|
||||
(assoc-in [:workspace-drawing :object :initialized?] true)))
|
||||
(defn init-path []
|
||||
(fn [state]
|
||||
(update-in state [:workspace-drawing :object]
|
||||
assoc :content []
|
||||
:initialized? true)))
|
||||
|
||||
(insert-point-segment [state point]
|
||||
(-> state
|
||||
(update-in [:workspace-drawing :object :segments] (fnil conj []) point)))
|
||||
(defn add-path-command [command]
|
||||
(fn [state]
|
||||
(update-in state [:workspace-drawing :object :content] conj command)))
|
||||
|
||||
(update-point-segment [state index point]
|
||||
(let [segments (count (get-in state [:workspace-drawing :object :segments]))
|
||||
exists? (< -1 index segments)]
|
||||
(cond-> state
|
||||
exists? (assoc-in [:workspace-drawing :object :segments index] point))))
|
||||
#_(defn update-point-segment [state index point]
|
||||
(let [segments (count (get-in state [:workspace-drawing :object :segments]))
|
||||
exists? (< -1 index segments)]
|
||||
(cond-> state
|
||||
exists? (assoc-in [:workspace-drawing :object :segments index] point))))
|
||||
|
||||
(finish-drawing-path [state]
|
||||
(update-in
|
||||
state [:workspace-drawing :object]
|
||||
(fn [shape] (-> shape
|
||||
(update :segments #(vec (butlast %)))
|
||||
(gsh/update-path-selrect)))))]
|
||||
(defn finish-drawing-path []
|
||||
(fn [state]
|
||||
(update-in
|
||||
state [:workspace-drawing :object]
|
||||
(fn [shape] (-> shape
|
||||
(update :segments #(vec (butlast %)))
|
||||
(gsh/update-path-selrect))))))
|
||||
|
||||
(ptk/reify ::handle-drawing-path
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [{:keys [flags]} (:workspace-local state)
|
||||
|
||||
last-point (volatile! @ms/mouse-position)
|
||||
(defn handle-drawing-path []
|
||||
|
||||
stoper (->> (rx/filter stoper-event? stream)
|
||||
(rx/share))
|
||||
(ptk/reify ::handle-drawing-path
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
|
||||
mouse (rx/sample 10 ms/mouse-position)
|
||||
;; clicks stream<[MouseEvent, Position]>
|
||||
clicks (->> stream
|
||||
(rx/filter ms/mouse-click?)
|
||||
(rx/with-latest vector ms/mouse-position))
|
||||
|
||||
points (->> stream
|
||||
(rx/filter ms/mouse-click?)
|
||||
(rx/filter #(false? (:shift %)))
|
||||
(rx/with-latest vector mouse)
|
||||
(rx/map second))
|
||||
|
||||
|
||||
counter (rx/merge (rx/scan #(inc %) 1 points) (rx/of 1))
|
||||
)))
|
||||
|
||||
stream' (->> mouse
|
||||
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||
(rx/with-latest vector counter)
|
||||
(rx/map flatten))
|
||||
#_(def handle-drawing-path
|
||||
(ptk/reify ::handle-drawing-path
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [{:keys [flags]} (:workspace-local state)
|
||||
|
||||
imm-transform #(vector (- % 7) (+ % 7) %)
|
||||
immanted-zones (vec (concat
|
||||
(map imm-transform (range 0 181 15))
|
||||
(map (comp imm-transform -) (range 0 181 15))))
|
||||
last-point (volatile! @ms/mouse-position)
|
||||
|
||||
align-position (fn [angle pos]
|
||||
(reduce (fn [pos [a1 a2 v]]
|
||||
(if (< a1 angle a2)
|
||||
(reduced (gpt/update-angle pos v))
|
||||
pos))
|
||||
pos
|
||||
immanted-zones))]
|
||||
stoper (->> (rx/filter stoper-event? stream)
|
||||
(rx/share))
|
||||
|
||||
(rx/merge
|
||||
(rx/of #(initialize-drawing % @last-point))
|
||||
mouse (rx/sample 10 ms/mouse-position)
|
||||
|
||||
(->> points
|
||||
(rx/take-until stoper)
|
||||
(rx/map (fn [pt] #(insert-point-segment % pt))))
|
||||
points (->> stream
|
||||
(rx/filter ms/mouse-click?)
|
||||
(rx/filter #(false? (:shift %)))
|
||||
(rx/with-latest vector mouse)
|
||||
(rx/map second))
|
||||
|
||||
(rx/concat
|
||||
(->> stream'
|
||||
(rx/take-until stoper)
|
||||
(rx/map (fn [[point ctrl? index :as xxx]]
|
||||
(let [point (if ctrl?
|
||||
(as-> point $
|
||||
(gpt/subtract $ @last-point)
|
||||
(align-position (gpt/angle $) $)
|
||||
(gpt/add $ @last-point))
|
||||
point)]
|
||||
#(update-point-segment % index point)))))
|
||||
(rx/of finish-drawing-path
|
||||
common/handle-finish-drawing))))))))
|
||||
counter (rx/merge (rx/scan #(inc %) 1 points) (rx/of 1))
|
||||
|
||||
stream' (->> mouse
|
||||
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||
(rx/with-latest vector counter)
|
||||
(rx/map flatten))
|
||||
|
||||
imm-transform #(vector (- % 7) (+ % 7) %)
|
||||
immanted-zones (vec (concat
|
||||
(map imm-transform (range 0 181 15))
|
||||
(map (comp imm-transform -) (range 0 181 15))))
|
||||
|
||||
align-position (fn [angle pos]
|
||||
(reduce (fn [pos [a1 a2 v]]
|
||||
(if (< a1 angle a2)
|
||||
(reduced (gpt/update-angle pos v))
|
||||
pos))
|
||||
pos
|
||||
immanted-zones))]
|
||||
|
||||
(rx/merge
|
||||
(rx/of #(initialize-drawing % @last-point))
|
||||
|
||||
(->> points
|
||||
(rx/take-until stoper)
|
||||
(rx/map (fn [pt] #(insert-point-segment % pt))))
|
||||
|
||||
(rx/concat
|
||||
(->> stream'
|
||||
(rx/take-until stoper)
|
||||
(rx/map (fn [[point ctrl? index :as xxx]]
|
||||
(let [point (if ctrl?
|
||||
(as-> point $
|
||||
(gpt/subtract $ @last-point)
|
||||
(align-position (gpt/angle $) $)
|
||||
(gpt/add $ @last-point))
|
||||
point)]
|
||||
#(update-point-segment % index point)))))
|
||||
(rx/of finish-drawing-path
|
||||
common/handle-finish-drawing)))))))
|
||||
|
||||
(defn close-drawing-path []
|
||||
(ptk/reify ::close-drawing-path
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
[v]
|
||||
(instance? MouseEvent v))
|
||||
|
||||
(defn mouse-down?
|
||||
[v]
|
||||
(and (mouse-event? v)
|
||||
(= :down (:type v))))
|
||||
|
||||
(defn mouse-up?
|
||||
[v]
|
||||
(and (mouse-event? v)
|
||||
|
|
Loading…
Add table
Reference in a new issue