From f8cf7103ca55085993d6dc81698460868712c9c3 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 26 Nov 2020 10:50:24 +0100 Subject: [PATCH] :sparkles: Improved opposite handler management --- .../app/main/data/workspace/drawing/path.cljs | 72 +++++++++++-------- .../app/main/ui/workspace/shapes/path.cljs | 4 -- frontend/src/app/util/geom/path.cljs | 2 +- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/frontend/src/app/main/data/workspace/drawing/path.cljs b/frontend/src/app/main/data/workspace/drawing/path.cljs index 9e31ee460d..4599e903b0 100644 --- a/frontend/src/app/main/data/workspace/drawing/path.cljs +++ b/frontend/src/app/main/data/workspace/drawing/path.cljs @@ -62,9 +62,6 @@ (s/def ::content (s/coll-of ::content-entry :kind vector?)) -(s/def ::path-shape - (s/keys :req-un [::content])) - ;; CONSTANTS (defonce enter-keycode 13) @@ -234,7 +231,6 @@ 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)] @@ -278,21 +274,22 @@ (= command :line-to) (update-in (get-path state :content index) make-curve)))))) -(defn drag-handler [{:keys [x y]}] +(defn drag-handler [{:keys [x y alt? shift?]}] (ptk/reify ::drag-handler ptk/UpdateEvent (update [_ state] (let [id (get-path-id state) - handler-position (gpt/point x y) shape (get-in state (get-path state)) content (:content shape) index (dec (count content)) node-position (ugp/command->point (nth content index)) + handler-position (cond-> (gpt/point x y) + shift? (position-fixed-angle node-position)) {dx :x dy :y} (gpt/subtract handler-position node-position) - match-opposite? true + match-opposite? (not alt?) modifiers (move-handler-modifiers content (inc index) :c1 match-opposite? dx dy)] (-> state - (assoc-in [:workspace-local :edit-path id :content-modifiers] modifiers) + (update-in [:workspace-local :edit-path id :content-modifiers] merge modifiers) (assoc-in [:workspace-local :edit-path id :prev-handler] handler-position) (assoc-in [:workspace-local :edit-path id :drag-handler] handler-position)))))) @@ -331,16 +328,11 @@ (->> stream (rx/filter #(or (end-path-event? %) (ms/mouse-up? %)))) - position-stream - (->> ms/mouse-position - (rx/take-until stop-stream) - (rx/throttle 50)) - drag-events-stream - (->> position-stream + (->> (position-stream) + (rx/take-until stop-stream) (rx/map #(drag-handler %)))] - (rx/concat (rx/of (add-node position)) (drag-stream @@ -436,7 +428,7 @@ [stream down-event zoom] (let [mouse-up (->> stream (rx/filter #(or (end-path-event? %) (ms/mouse-up? %)))) - drag-events (->> ms/mouse-position + drag-events (->> (position-stream) (rx/take-until mouse-up) (rx/map #(drag-handler %)))] @@ -567,6 +559,14 @@ (defn save-path-content [] (ptk/reify ::save-path-content + ptk/UpdateEvent + (update [_ state] + (let [content (get-in state (get-path state :content)) + content (if (= (-> content last :command) :move-to) + (into [] (take (dec (count content)) content)) + content)] + (assoc-in state (get-path state :content) content))) + ptk/WatchEvent (watch [_ state stream] (let [id (get-in state [:workspace-local :edition]) @@ -653,25 +653,39 @@ ptk/WatchEvent (watch [_ state stream] (let [id (get-in state [:workspace-local :edition]) - [cx cy] (if (= prefix :c1) [:c1x :c1y] [:c2x :c2y]) + cx (ud/prefix-keyword prefix :x) + cy (ud/prefix-keyword prefix :y) start-point @ms/mouse-position - 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)] + modifiers (get-in state [:workspace-local :edit-path id :content-modifiers]) + start-delta-x (get-in modifiers [index cx] 0) + start-delta-y (get-in modifiers [index cy] 0) + + content (get-in state (get-path state :content)) + opposite-index (ugp/opposite-index content index prefix) + opposite-prefix (if (= prefix :c1) :c2 :c1) + opposite-handler (-> content (get opposite-index) (ugp/get-handler opposite-prefix)) + + point (-> content (get (if (= prefix :c1) (dec index) index)) (ugp/command->point)) + handler (-> content (get index) (ugp/get-handler prefix)) + + current-distance (gpt/distance (ugp/opposite-handler point handler) opposite-handler) + match-opposite? (mth/almost-zero? current-distance)] (drag-stream (rx/concat - (->> ms/mouse-position + (->> (position-stream) (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?))))) + (fn [{:keys [x y alt? shift?]}] + (let [pos (cond-> (gpt/point x y) + shift? (position-fixed-angle point))] + (modify-handler + id + index + prefix + (+ start-delta-x (- (:x pos) (:x start-point))) + (+ start-delta-y (- (:y pos) (:y start-point))) + (and (not alt?) match-opposite?)))))) (rx/concat (rx/of (apply-content-modifiers))))))))) (defn start-draw-mode [] diff --git a/frontend/src/app/main/ui/workspace/shapes/path.cljs b/frontend/src/app/main/ui/workspace/shapes/path.cljs index 72a327f362..09a3ab9b2d 100644 --- a/frontend/src/app/main/ui/workspace/shapes/path.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/path.cljs @@ -333,10 +333,6 @@ (when drag-handler [:g.drag-handler {:pointer-events "none"} - (when (not= :move-to (:command last-command)) - [:& path-handler {:point last-p - :handler (ugp/opposite-handler last-p drag-handler) - :zoom zoom}]) [:& path-handler {:point last-p :handler drag-handler :zoom zoom}]])])) diff --git a/frontend/src/app/util/geom/path.cljs b/frontend/src/app/util/geom/path.cljs index 4e150f7a5d..5357563a78 100644 --- a/frontend/src/app/util/geom/path.cljs +++ b/frontend/src/app/util/geom/path.cljs @@ -368,7 +368,7 @@ calculate-vector (fn [point next prev] - (let [base-vector (if (or (nil? next) (nil? prev)) + (let [base-vector (if (or (nil? next) (nil? prev) (= next prev)) (-> (gpt/to-vec point (or next prev)) (gpt/normal-left)) (gpt/to-vec next prev))]