diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 65756a5d3..279682c2f 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -7,6 +7,7 @@ (ns app.main.data.workspace.transforms "Events related with shapes transformations" (:require + [app.common.math :as mth] [app.common.data :as d] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] @@ -70,8 +71,11 @@ :bottom-left [ex sy])] (gpt/point x y))) -(defn finish-transform [state] - (update state :workspace-local dissoc :transform)) +(defn finish-transform [] + (ptk/reify ::finish-transform + ptk/UpdateEvent + (update [_ state] + (update state :workspace-local dissoc :transform)))) ;; -- RESIZE (defn start-resize @@ -152,7 +156,7 @@ (rx/mapcat (partial resize shape initial-position resizing-shapes)) (rx/take-until stoper)) (rx/of (apply-modifiers ids) - finish-transform))))))) + (finish-transform)))))))) (defn start-rotate @@ -190,7 +194,7 @@ (set-rotation delta-angle shapes group-center)))) (rx/take-until stoper)) (rx/of (apply-modifiers (map :id shapes)) - finish-transform)))))) + (finish-transform))))))) ;; -- MOVE @@ -291,19 +295,23 @@ (rx/map #(gpt/to-vec from-position %))) snap-delta (->> position - (rx/switch-map #(snap/closest-snap-move page-id shapes objects layout zoom %)))] + (rx/throttle 20) + (rx/switch-map + (fn [pos] + (->> (snap/closest-snap-move page-id shapes objects layout zoom pos) + (rx/map #(vector pos %))))))] (if (empty? shapes) (rx/empty) (rx/concat - (->> snap-delta - (rx/with-latest vector position) - (rx/map (fn [[delta pos]] (-> (gpt/add pos delta) (gpt/round 0)))) + (->> position + (rx/with-latest vector snap-delta) + (rx/map snap/correct-snap-point) (rx/map start-local-displacement)) (rx/of (set-modifiers ids) (apply-modifiers ids) (calculate-frame-for-move ids) - finish-transform)))))))) + (finish-transform))))))))) (defn- get-displacement-with-grid "Retrieve the correct displacement delta point for the @@ -372,7 +380,7 @@ (rx/of (set-modifiers selected) (apply-modifiers selected) - finish-transform))) + (finish-transform)))) (rx/empty)))))) diff --git a/frontend/src/app/main/snap.cljs b/frontend/src/app/main/snap.cljs index 583a62fd0..e73f4c777 100644 --- a/frontend/src/app/main/snap.cljs +++ b/frontend/src/app/main/snap.cljs @@ -19,7 +19,7 @@ [beicon.core :as rx] [clojure.set :as set])) -(defonce ^:private snap-accuracy 5) +(defonce ^:private snap-accuracy 10) (defonce ^:private snap-path-accuracy 10) (defonce ^:private snap-distance-accuracy 10) @@ -84,7 +84,7 @@ (rx/map (remove-from-snap-points filter-shapes)) (rx/map (get-min-distance-snap points coord))))) -(defn snap->vector [[from-x to-x] [from-y to-y]] +(defn snap->vector [[[from-x to-x] [from-y to-y]]] (when (or from-x to-x from-y to-y) (let [from (gpt/point (or from-x 0) (or from-y 0)) to (gpt/point (or to-x 0) (or to-y 0))] @@ -94,7 +94,8 @@ [page-id frame-id points filter-shapes zoom] (let [snap-x (search-snap page-id frame-id points :x filter-shapes zoom) snap-y (search-snap page-id frame-id points :y filter-shapes zoom)] - (rx/combine-latest snap-x snap-y))) + (->> (rx/combine-latest snap-x snap-y) + (rx/map snap->vector)))) (defn sr-distance [coord sr1 sr2] @@ -202,7 +203,8 @@ (d/mapm #(select-shapes-area page-id shapes objects %2))) snap-x (search-snap-distance selrect :x (:left areas) (:right areas) zoom) snap-y (search-snap-distance selrect :y (:top areas) (:bottom areas) zoom)] - (rx/combine-latest snap-x snap-y))))))) + (rx/combine-latest snap-x snap-y)))) + (rx/map snap->vector)))) (defn closest-snap-point [page-id shapes layout zoom point] @@ -330,3 +332,18 @@ (update :y first) (gpt/point))) + +(defn correct-snap-point + "Snaps a position given an old snap to a different position. We use this to provide a temporal + snap while the new is being processed." + [[position [snap-pos snap-delta]]] + (let [dx (if (not= 0 (:x snap-delta)) + (- (+ (:x snap-pos) (:x snap-delta)) (:x position)) + 0) + dy (if (not= 0 (:y snap-delta)) + (- (+ (:y snap-pos) (:y snap-delta)) (:y position)) + 0)] + + (cond-> position + (<= (mth/abs dx) snap-accuracy) (update :x + dx) + (<= (mth/abs dy) snap-accuracy) (update :y + dy))))