mirror of
https://github.com/penpot/penpot.git
synced 2025-05-14 22:16:38 +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
|
(defn position-stream
|
||||||
[points]
|
[points]
|
||||||
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
|
(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)
|
d-pos (/ snap/snap-accuracy zoom)
|
||||||
get-content (fn [state] (get-in state (state/get-path state :content)))
|
get-content (fn [state] (get-in state (state/get-path state :content)))
|
||||||
|
|
||||||
content-stream (-> (l/derived get-content st/state)
|
content-stream
|
||||||
(rx/from-atom))
|
(-> (l/derived get-content st/state)
|
||||||
]
|
(rx/from-atom {:emit-current-value? true}))
|
||||||
|
|
||||||
(->> content-stream
|
|
||||||
(rx/map ugp/content->points)
|
|
||||||
(rx/subs #(prn "????" %)))
|
|
||||||
|
|
||||||
|
ranges-stream
|
||||||
|
(->> content-stream
|
||||||
|
(rx/map ugp/content->points)
|
||||||
|
(rx/map snap/create-ranges))]
|
||||||
|
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
(rx/tap #(prn "pos" %))
|
(rx/with-latest vector ranges-stream)
|
||||||
(rx/map #(let [snap (snap/get-snap-delta [%] ranges d-pos)]
|
(rx/map (fn [[position ranges]]
|
||||||
(prn ">>>" snap)
|
(let [snap (snap/get-snap-delta [position] ranges d-pos)]
|
||||||
(gpt/add % snap)))
|
#_(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-shift (rx/map #(hash-map :shift? %))))
|
||||||
(rx/with-latest merge (->> ms/mouse-position-alt (rx/map #(hash-map :alt? %)))))))
|
(rx/with-latest merge (->> ms/mouse-position-alt (rx/map #(hash-map :alt? %)))))))
|
||||||
|
|
|
@ -267,33 +267,35 @@
|
||||||
|
|
||||||
(defn query-delta-point [ranges point precision]
|
(defn query-delta-point [ranges point precision]
|
||||||
(let [query-coord
|
(let [query-coord
|
||||||
(fn [coord]
|
(fn [point coord]
|
||||||
(let [pval (get 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))
|
(->> (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
|
;; We save the distance to the point and add the matching point to the points
|
||||||
(mapv (fn [[value points]]
|
(mapv (fn [[value points]]
|
||||||
#_(prn "!! " value [(mth/abs (- value pval))
|
|
||||||
(->> points (mapv #(vector point %)))])
|
|
||||||
[(mth/abs (- value pval))
|
[(mth/abs (- value pval))
|
||||||
(->> points (mapv #(vector point %)))])))))]
|
(->> points (mapv #(vector point %)))])))))]
|
||||||
|
|
||||||
{:x (query-coord :x)
|
{:x (query-coord point :x)
|
||||||
:y (query-coord :y)}))
|
:y (query-coord point :y)}))
|
||||||
|
|
||||||
(defn merge-matches [matches other]
|
(defn merge-matches
|
||||||
(let [merge-coord
|
([] {:x nil :y nil})
|
||||||
(fn [matches other]
|
([matches other]
|
||||||
(prn "merge-coord" matches other)
|
(let [merge-coord
|
||||||
(into {}
|
(fn [matches other]
|
||||||
(map (fn [key] [key (d/concat [] (get matches key) (get other key))]))
|
|
||||||
(set/union (keys matches) (keys other))))]
|
|
||||||
|
|
||||||
(-> matches
|
(let [matches (into {} matches)
|
||||||
(update :x merge-matches (:x other))
|
other (into {} other)
|
||||||
(update :y merge-matches (:y 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-coord (:x other))
|
||||||
|
(update :y merge-coord (:y other))))))
|
||||||
|
|
||||||
(defn min-match
|
(defn min-match
|
||||||
[default matches]
|
[default matches]
|
||||||
|
@ -329,55 +331,3 @@
|
||||||
(update :y first)
|
(update :y first)
|
||||||
(gpt/point)))
|
(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
|
:preview? true
|
||||||
:zoom zoom}]])
|
:zoom zoom}]])
|
||||||
|
|
||||||
(mf/defc snap-path-points [{:keys [snaps zoom]}]
|
(mf/defc snap-points [{:keys [selected points zoom]}]
|
||||||
[:g.snap-paths
|
(let [ranges (mf/use-memo (mf/deps selected points) #(snap/create-ranges points selected))
|
||||||
(for [[from to] snaps]
|
snap-matches (snap/get-snap-delta-match selected ranges (/ 1 zoom))
|
||||||
[:line {:x1 (:x from)
|
matches (d/concat [] (second (:x snap-matches)) (second (:y snap-matches)))]
|
||||||
:y1 (:y from)
|
|
||||||
:x2 (:x to)
|
[:g.snap-paths
|
||||||
:y2 (:y to)
|
(for [[from to] matches]
|
||||||
:style {:stroke pc/secondary-color
|
[:line {:x1 (:x from)
|
||||||
:stroke-width (/ 1 zoom)}}])])
|
:y1 (:y from)
|
||||||
|
:x2 (:x to)
|
||||||
|
:y2 (:y to)
|
||||||
|
:style {:stroke pc/secondary-color
|
||||||
|
:stroke-width (/ 1 zoom)}}])]))
|
||||||
|
|
||||||
(mf/defc path-editor
|
(mf/defc path-editor
|
||||||
[{:keys [shape zoom]}]
|
[{:keys [shape zoom]}]
|
||||||
|
@ -193,28 +197,16 @@
|
||||||
#(doseq [key keys]
|
#(doseq [key keys]
|
||||||
(events/unlistenByKey key)))))
|
(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}
|
[:g.path-editor {:ref editor-ref}
|
||||||
#_[:& snap-points {}]
|
|
||||||
|
|
||||||
|
|
||||||
(when (and preview (not drag-handler))
|
(when (and preview (not drag-handler))
|
||||||
[:& path-preview {:command preview
|
[:*
|
||||||
:from last-p
|
[:& snap-points {:selected #{(ugp/command->point preview)}
|
||||||
:zoom zoom}])
|
:points points
|
||||||
|
:zoom zoom}]
|
||||||
|
|
||||||
|
[:& path-preview {:command preview
|
||||||
|
:from last-p
|
||||||
|
:zoom zoom}]])
|
||||||
|
|
||||||
(when @hover-point
|
(when @hover-point
|
||||||
[:g.hover-point
|
[:g.hover-point
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue