0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-10 08:50:57 -05:00

Improve snap responsiveness

This commit is contained in:
alonso.torres 2021-04-29 15:08:47 +02:00
parent 056b80939e
commit a9e93a5ace
2 changed files with 39 additions and 14 deletions

View file

@ -7,6 +7,7 @@
(ns app.main.data.workspace.transforms (ns app.main.data.workspace.transforms
"Events related with shapes transformations" "Events related with shapes transformations"
(:require (:require
[app.common.math :as mth]
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.matrix :as gmt] [app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
@ -70,8 +71,11 @@
:bottom-left [ex sy])] :bottom-left [ex sy])]
(gpt/point x y))) (gpt/point x y)))
(defn finish-transform [state] (defn finish-transform []
(update state :workspace-local dissoc :transform)) (ptk/reify ::finish-transform
ptk/UpdateEvent
(update [_ state]
(update state :workspace-local dissoc :transform))))
;; -- RESIZE ;; -- RESIZE
(defn start-resize (defn start-resize
@ -152,7 +156,7 @@
(rx/mapcat (partial resize shape initial-position resizing-shapes)) (rx/mapcat (partial resize shape initial-position resizing-shapes))
(rx/take-until stoper)) (rx/take-until stoper))
(rx/of (apply-modifiers ids) (rx/of (apply-modifiers ids)
finish-transform))))))) (finish-transform))))))))
(defn start-rotate (defn start-rotate
@ -190,7 +194,7 @@
(set-rotation delta-angle shapes group-center)))) (set-rotation delta-angle shapes group-center))))
(rx/take-until stoper)) (rx/take-until stoper))
(rx/of (apply-modifiers (map :id shapes)) (rx/of (apply-modifiers (map :id shapes))
finish-transform)))))) (finish-transform)))))))
;; -- MOVE ;; -- MOVE
@ -291,19 +295,23 @@
(rx/map #(gpt/to-vec from-position %))) (rx/map #(gpt/to-vec from-position %)))
snap-delta (->> 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) (if (empty? shapes)
(rx/empty) (rx/empty)
(rx/concat (rx/concat
(->> snap-delta (->> position
(rx/with-latest vector position) (rx/with-latest vector snap-delta)
(rx/map (fn [[delta pos]] (-> (gpt/add pos delta) (gpt/round 0)))) (rx/map snap/correct-snap-point)
(rx/map start-local-displacement)) (rx/map start-local-displacement))
(rx/of (set-modifiers ids) (rx/of (set-modifiers ids)
(apply-modifiers ids) (apply-modifiers ids)
(calculate-frame-for-move ids) (calculate-frame-for-move ids)
finish-transform)))))))) (finish-transform)))))))))
(defn- get-displacement-with-grid (defn- get-displacement-with-grid
"Retrieve the correct displacement delta point for the "Retrieve the correct displacement delta point for the
@ -372,7 +380,7 @@
(rx/of (set-modifiers selected) (rx/of (set-modifiers selected)
(apply-modifiers selected) (apply-modifiers selected)
finish-transform))) (finish-transform))))
(rx/empty)))))) (rx/empty))))))

View file

@ -19,7 +19,7 @@
[beicon.core :as rx] [beicon.core :as rx]
[clojure.set :as set])) [clojure.set :as set]))
(defonce ^:private snap-accuracy 5) (defonce ^:private snap-accuracy 10)
(defonce ^:private snap-path-accuracy 10) (defonce ^:private snap-path-accuracy 10)
(defonce ^:private snap-distance-accuracy 10) (defonce ^:private snap-distance-accuracy 10)
@ -84,7 +84,7 @@
(rx/map (remove-from-snap-points filter-shapes)) (rx/map (remove-from-snap-points filter-shapes))
(rx/map (get-min-distance-snap points coord))))) (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) (when (or from-x to-x from-y to-y)
(let [from (gpt/point (or from-x 0) (or from-y 0)) (let [from (gpt/point (or from-x 0) (or from-y 0))
to (gpt/point (or to-x 0) (or to-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] [page-id frame-id points filter-shapes zoom]
(let [snap-x (search-snap page-id frame-id points :x 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)] 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] (defn sr-distance [coord sr1 sr2]
@ -202,7 +203,8 @@
(d/mapm #(select-shapes-area page-id shapes objects %2))) (d/mapm #(select-shapes-area page-id shapes objects %2)))
snap-x (search-snap-distance selrect :x (:left areas) (:right areas) zoom) snap-x (search-snap-distance selrect :x (:left areas) (:right areas) zoom)
snap-y (search-snap-distance selrect :y (:top areas) (:bottom 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 (defn closest-snap-point
[page-id shapes layout zoom point] [page-id shapes layout zoom point]
@ -330,3 +332,18 @@
(update :y first) (update :y first)
(gpt/point))) (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))))