From de8207c5a63ce91cd3d7d1674e389d1bfb57dd52 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 12 Apr 2021 18:22:47 +0200 Subject: [PATCH] :sparkles: Snap on paths --- .../app/main/data/workspace/path/streams.cljs | 27 +++--- frontend/src/app/main/snap.cljs | 90 +++++-------------- .../main/ui/workspace/shapes/path/editor.cljs | 50 +++++------ 3 files changed, 56 insertions(+), 111 deletions(-) diff --git a/frontend/src/app/main/data/workspace/path/streams.cljs b/frontend/src/app/main/data/workspace/path/streams.cljs index 99cf0f298..4f0b2a5ef 100644 --- a/frontend/src/app/main/data/workspace/path/streams.cljs +++ b/frontend/src/app/main/data/workspace/path/streams.cljs @@ -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? %))))))) diff --git a/frontend/src/app/main/snap.cljs b/frontend/src/app/main/snap.cljs index 3831fb4f6..414cc0a6a 100644 --- a/frontend/src/app/main/snap.cljs +++ b/frontend/src/app/main/snap.cljs @@ -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)})))))) diff --git a/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs b/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs index 4299e681b..90a754787 100644 --- a/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/path/editor.cljs @@ -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