mirror of
https://github.com/penpot/penpot.git
synced 2025-05-12 10:26:39 +02:00
✨ Snap on paths
This commit is contained in:
parent
5f114163dc
commit
de8207c5a6
3 changed files with 56 additions and 111 deletions
|
@ -86,23 +86,26 @@
|
|||
(defn position-stream
|
||||
[points]
|
||||
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
|
||||
ranges (snap/create-ranges points)
|
||||
;; ranges (snap/create-ranges points)
|
||||
d-pos (/ snap/snap-accuracy zoom)
|
||||
get-content (fn [state] (get-in state (state/get-path state :content)))
|
||||
|
||||
content-stream (-> (l/derived get-content st/state)
|
||||
(rx/from-atom))
|
||||
]
|
||||
|
||||
(->> content-stream
|
||||
(rx/map ugp/content->points)
|
||||
(rx/subs #(prn "????" %)))
|
||||
content-stream
|
||||
(-> (l/derived get-content st/state)
|
||||
(rx/from-atom {:emit-current-value? true}))
|
||||
|
||||
ranges-stream
|
||||
(->> content-stream
|
||||
(rx/map ugp/content->points)
|
||||
(rx/map snap/create-ranges))]
|
||||
|
||||
(->> ms/mouse-position
|
||||
(rx/tap #(prn "pos" %))
|
||||
(rx/map #(let [snap (snap/get-snap-delta [%] ranges d-pos)]
|
||||
(prn ">>>" snap)
|
||||
(gpt/add % snap)))
|
||||
(rx/with-latest vector ranges-stream)
|
||||
(rx/map (fn [[position ranges]]
|
||||
(let [snap (snap/get-snap-delta [position] ranges d-pos)]
|
||||
#_(prn ">>>" snap)
|
||||
(gpt/add position snap))
|
||||
))
|
||||
|
||||
(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? %)))))))
|
||||
|
|
|
@ -267,33 +267,35 @@
|
|||
|
||||
(defn query-delta-point [ranges point precision]
|
||||
(let [query-coord
|
||||
(fn [coord]
|
||||
(fn [point coord]
|
||||
(let [pval (get point coord)]
|
||||
#_(prn "..." (rt/range-query (get ranges coord) (- pval precision) (+ pval precision)))
|
||||
|
||||
(->> (rt/range-query (get ranges coord) (- pval precision) (+ pval precision))
|
||||
|
||||
;; We save the distance to the point and add the matching point to the points
|
||||
(mapv (fn [[value points]]
|
||||
#_(prn "!! " value [(mth/abs (- value pval))
|
||||
(->> points (mapv #(vector point %)))])
|
||||
[(mth/abs (- value pval))
|
||||
(->> points (mapv #(vector point %)))])))))]
|
||||
|
||||
{:x (query-coord :x)
|
||||
:y (query-coord :y)}))
|
||||
{:x (query-coord point :x)
|
||||
:y (query-coord point :y)}))
|
||||
|
||||
(defn merge-matches [matches other]
|
||||
(let [merge-coord
|
||||
(fn [matches other]
|
||||
(prn "merge-coord" matches other)
|
||||
(into {}
|
||||
(map (fn [key] [key (d/concat [] (get matches key) (get other key))]))
|
||||
(set/union (keys matches) (keys other))))]
|
||||
(defn merge-matches
|
||||
([] {:x nil :y nil})
|
||||
([matches other]
|
||||
(let [merge-coord
|
||||
(fn [matches other]
|
||||
|
||||
(let [matches (into {} matches)
|
||||
other (into {} other)
|
||||
keys (set/union (keys matches) (keys other))]
|
||||
(into {}
|
||||
(map (fn [key]
|
||||
[key
|
||||
(d/concat [] (get matches key []) (get other key []))]))
|
||||
keys)))]
|
||||
|
||||
(-> matches
|
||||
(update :x merge-matches (:x other))
|
||||
(update :y merge-matches (:y other)))))
|
||||
(-> matches
|
||||
(update :x merge-coord (:x other))
|
||||
(update :y merge-coord (:y other))))))
|
||||
|
||||
(defn min-match
|
||||
[default matches]
|
||||
|
@ -329,55 +331,3 @@
|
|||
(update :y first)
|
||||
(gpt/point)))
|
||||
|
||||
#_(defn path-snap-points-delta [points-stream selected-points points zoom]
|
||||
|
||||
(let [ranges (create-ranges points selected-points)
|
||||
d-pos (/ snap-accuracy zoom)]
|
||||
|
||||
(->> points-stream
|
||||
(rx/map (fn [points]
|
||||
(get-snap-delta points ranges d-pos)))))
|
||||
|
||||
|
||||
)
|
||||
|
||||
#_(defn path-snap [position-stream points selected-points zoom]
|
||||
(let [ranges (create-ranges points selected-points)
|
||||
d-pos (/ snap-accuracy zoom)]
|
||||
|
||||
(->> position-stream
|
||||
(rx/map (fn [position]
|
||||
(gpt/add
|
||||
position
|
||||
(get-snap-delta position ranges d-pos)))))))
|
||||
|
||||
|
||||
#_(defn path-snap [position-stream points selected-points zoom]
|
||||
(let [selected-points (or selected-points #{})
|
||||
into-tree (fn [coord]
|
||||
(fn [tree point]
|
||||
(rt/insert tree (get point coord) point)))
|
||||
|
||||
ranges-x (->> points
|
||||
(filter (comp not selected-points))
|
||||
(reduce (into-tree :x) (rt/make-tree)))
|
||||
|
||||
ranges-y (->> points
|
||||
(filter (comp not selected-points))
|
||||
(reduce (into-tree :y) (rt/make-tree)))
|
||||
|
||||
min-match (fn [matches]
|
||||
(->> matches
|
||||
(reduce (fn [[cur-val :as current] [other-val :as other]]
|
||||
(if (< cur-val other-val)
|
||||
current
|
||||
other)))))]
|
||||
|
||||
(->> position-stream
|
||||
(rx/map
|
||||
(fn [{:keys [x y]}]
|
||||
(let [d-pos (/ snap-accuracy zoom)
|
||||
x-match (rt/range-query ranges-x (- x d-pos) (+ x d-pos))
|
||||
y-match (rt/range-query ranges-y (- y d-pos) (+ y d-pos))]
|
||||
{:x (min-match x-match)
|
||||
:y (min-match y-match)}))))))
|
||||
|
|
|
@ -145,15 +145,19 @@
|
|||
:preview? true
|
||||
:zoom zoom}]])
|
||||
|
||||
(mf/defc snap-path-points [{:keys [snaps zoom]}]
|
||||
[:g.snap-paths
|
||||
(for [[from to] snaps]
|
||||
[:line {:x1 (:x from)
|
||||
:y1 (:y from)
|
||||
:x2 (:x to)
|
||||
:y2 (:y to)
|
||||
:style {:stroke pc/secondary-color
|
||||
:stroke-width (/ 1 zoom)}}])])
|
||||
(mf/defc snap-points [{:keys [selected points zoom]}]
|
||||
(let [ranges (mf/use-memo (mf/deps selected points) #(snap/create-ranges points selected))
|
||||
snap-matches (snap/get-snap-delta-match selected ranges (/ 1 zoom))
|
||||
matches (d/concat [] (second (:x snap-matches)) (second (:y snap-matches)))]
|
||||
|
||||
[:g.snap-paths
|
||||
(for [[from to] matches]
|
||||
[:line {:x1 (:x from)
|
||||
:y1 (:y from)
|
||||
:x2 (:x to)
|
||||
:y2 (:y to)
|
||||
:style {:stroke pc/secondary-color
|
||||
:stroke-width (/ 1 zoom)}}])]))
|
||||
|
||||
(mf/defc path-editor
|
||||
[{:keys [shape zoom]}]
|
||||
|
@ -193,28 +197,16 @@
|
|||
#(doseq [key keys]
|
||||
(events/unlistenByKey key)))))
|
||||
|
||||
#_(hooks/use-stream
|
||||
ms/mouse-position
|
||||
(mf/deps shape)
|
||||
(fn [position]
|
||||
(reset! hover-point (gshp/path-closest-point shape position))))
|
||||
|
||||
#_(hooks/use-stream
|
||||
(mf/use-memo
|
||||
(mf/deps base-content selected-points zoom)
|
||||
#(snap/path-snap ms/mouse-position points selected-points zoom))
|
||||
|
||||
(fn [result]
|
||||
(prn "??" result)))
|
||||
|
||||
[:g.path-editor {:ref editor-ref}
|
||||
#_[:& snap-points {}]
|
||||
|
||||
|
||||
(when (and preview (not drag-handler))
|
||||
[:& path-preview {:command preview
|
||||
:from last-p
|
||||
:zoom zoom}])
|
||||
[:*
|
||||
[:& snap-points {:selected #{(ugp/command->point preview)}
|
||||
:points points
|
||||
:zoom zoom}]
|
||||
|
||||
[:& path-preview {:command preview
|
||||
:from last-p
|
||||
:zoom zoom}]])
|
||||
|
||||
(when @hover-point
|
||||
[:g.hover-point
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue