0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-10 00:58:26 -05:00

Merge pull request #885 from penpot/alotor/improve-snaps

Improve snaps performance
This commit is contained in:
Andrey Antukh 2021-04-29 15:43:50 +02:00 committed by GitHub
commit 92d1dcb3d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 25 deletions

View file

@ -14,7 +14,7 @@
[danlentz/clj-uuid "0.1.9"]
[frankiesardo/linked "1.3.0"]
[funcool/beicon "2021.04.12-1"]
[funcool/beicon "2021.04.27-2"]
[funcool/cuerdas "2020.03.26-3"]
[funcool/okulary "2020.04.14-0"]
[funcool/potok "3.2.0"]

View file

@ -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))))))

View file

@ -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,8 +94,9 @@
[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)]
;; snap-x is the second parameter because is the "source" to combine
(rx/combine-latest snap->vector snap-y snap-x)))
(->> (rx/combine-latest snap-x snap-y)
(rx/map snap->vector))))
(defn sr-distance [coord sr1 sr2]
(let [c1 (if (= coord :x) :x1 :y1)
@ -174,8 +175,7 @@
(if (mth/finite? min-snap) [0 min-snap] nil)))
(defn search-snap-distance [selrect coord shapes-lt shapes-gt zoom]
(->> shapes-lt
(rx/combine-latest vector shapes-gt)
(->> (rx/combine-latest shapes-lt shapes-gt)
(rx/map (fn [[shapes-lt shapes-gt]]
(calculate-snap coord selrect shapes-lt shapes-gt zoom)))))
@ -203,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->vector snap-y snap-x)))))))
(rx/combine-latest snap-x snap-y))))
(rx/map snap->vector))))
(defn closest-snap-point
[page-id shapes layout zoom point]
@ -331,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))))

View file

@ -233,9 +233,8 @@
(rx/map #(set/difference % selected))
(rx/map #(->> % (map (partial get @refs/workspace-page-objects)))))
(rx/of nil))))]
(->> (query-side lt-side)
(rx/combine-latest vector (query-side gt-side)))))
(rx/combine-latest (query-side lt-side)
(query-side gt-side))))
[lt-shapes gt-shapes] @to-measure

View file

@ -120,10 +120,10 @@
(mf/use-effect
(fn []
(let [sub (->> subject
(rx/switch-map #(rx/combine-latest
d/concat
(get-snap :y %)
(get-snap :x %)))
(rx/switch-map #(rx/combine-latest (get-snap :x %)
(get-snap :y %)))
(rx/map (fn [result]
(apply d/concat (seq result))))
(rx/subs #(let [rs (filter (fn [[_ snaps _]] (> (count snaps) 0)) %)]
(reset! state rs))))]