mirror of
https://github.com/penpot/penpot.git
synced 2025-06-10 12:51:38 +02:00
🐛 Fix snap imprecission.
This commit is contained in:
parent
1dfc604cf0
commit
d3951f7f8f
12 changed files with 108 additions and 86 deletions
|
@ -255,15 +255,17 @@
|
||||||
(declare transform-shape-point)
|
(declare transform-shape-point)
|
||||||
|
|
||||||
(defn shape->points [shape]
|
(defn shape->points [shape]
|
||||||
(let [points
|
(let [points (case (:type shape)
|
||||||
(case (:type shape)
|
(:curve :path) (:segments shape)
|
||||||
(:curve :path) (:segments shape)
|
(let [{:keys [x y width height]} shape]
|
||||||
(let [{:keys [x y width height]} shape]
|
[(gpt/point x y)
|
||||||
[(gpt/point x y)
|
(gpt/point (+ x width) y)
|
||||||
(gpt/point (+ x width) y)
|
(gpt/point (+ x width) (+ y height))
|
||||||
(gpt/point (+ x width) (+ y height))
|
(gpt/point x (+ y height))]))]
|
||||||
(gpt/point x (+ y height))]))]
|
(->> points
|
||||||
(mapv #(transform-shape-point % shape (:transform shape (gmt/matrix))) points)))
|
(map #(transform-shape-point % shape (:transform shape (gmt/matrix))))
|
||||||
|
(map gpt/round)
|
||||||
|
(vec))))
|
||||||
|
|
||||||
(defn points->selrect [points]
|
(defn points->selrect [points]
|
||||||
(let [minx (transduce (map :x) min ##Inf points)
|
(let [minx (transduce (map :x) min ##Inf points)
|
||||||
|
@ -756,8 +758,10 @@
|
||||||
|
|
||||||
new-shape (as-> shape $
|
new-shape (as-> shape $
|
||||||
(merge $ rec)
|
(merge $ rec)
|
||||||
(update $ :x #(mth/precision % 2))
|
(update $ :x #(mth/precision % 0))
|
||||||
(update $ :y #(mth/precision % 2))
|
(update $ :y #(mth/precision % 0))
|
||||||
|
(update $ :width #(mth/precision % 0))
|
||||||
|
(update $ :height #(mth/precision % 0))
|
||||||
(fix-invalid-rect-values $)
|
(fix-invalid-rect-values $)
|
||||||
(update $ :transform #(gmt/multiply (or % (gmt/matrix)) stretch-matrix))
|
(update $ :transform #(gmt/multiply (or % (gmt/matrix)) stretch-matrix))
|
||||||
(update $ :transform-inverse #(gmt/multiply stretch-matrix-inverse (or % (gmt/matrix))))
|
(update $ :transform-inverse #(gmt/multiply stretch-matrix-inverse (or % (gmt/matrix))))
|
||||||
|
@ -766,7 +770,6 @@
|
||||||
(update $ :rotation #(mod (+ % (get-in $ [:modifiers :rotation] 0)) 360))
|
(update $ :rotation #(mod (+ % (get-in $ [:modifiers :rotation] 0)) 360))
|
||||||
|
|
||||||
)]
|
)]
|
||||||
|
|
||||||
new-shape))
|
new-shape))
|
||||||
|
|
||||||
(declare update-path-selrect)
|
(declare update-path-selrect)
|
||||||
|
|
|
@ -98,8 +98,8 @@
|
||||||
(defn precision
|
(defn precision
|
||||||
[v n]
|
[v n]
|
||||||
(when (and (number? v) (number? n))
|
(when (and (number? v) (number? n))
|
||||||
#?(:cljs (js/parseFloat (.toFixed v n))
|
(let [d (pow 10 n)]
|
||||||
:clj (.. (BigDecimal/valueOf v) (setScale n java.math.RoundingMode/HALF_UP) (doubleValue)))))
|
(/ (round (* v d)) d))))
|
||||||
|
|
||||||
(defn radians
|
(defn radians
|
||||||
"Converts degrees to radians."
|
"Converts degrees to radians."
|
||||||
|
|
|
@ -211,7 +211,7 @@
|
||||||
(rx/filter #(> % 1))
|
(rx/filter #(> % 1))
|
||||||
(rx/take 1)
|
(rx/take 1)
|
||||||
(rx/with-latest vector ms/mouse-position-alt)
|
(rx/with-latest vector ms/mouse-position-alt)
|
||||||
(rx/flat-map
|
(rx/mapcat
|
||||||
(fn [[_ alt?]]
|
(fn [[_ alt?]]
|
||||||
(if alt?
|
(if alt?
|
||||||
;; When alt is down we start a duplicate+move
|
;; When alt is down we start a duplicate+move
|
||||||
|
@ -242,15 +242,16 @@
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [page-id (get state :current-page-id)
|
(let [page-id (get state :current-page-id)
|
||||||
objects (get-in state [:workspace-data page-id :objects])
|
objects (get-in state [:workspace-data page-id :objects])
|
||||||
ids (if (nil? ids) (get-in state [:workspace-local :selected]) ids)
|
ids (if (nil? ids) (get-in state [:workspace-local :selected]) ids)
|
||||||
shapes (mapv #(get-in state [:workspace-data page-id :objects %]) ids)
|
shapes (mapv #(get objects %) ids)
|
||||||
stopper (rx/filter ms/mouse-up? stream)
|
stopper (rx/filter ms/mouse-up? stream)
|
||||||
layout (get state :workspace-layout)]
|
layout (get state :workspace-layout)]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
(rx/take-until stopper)
|
(rx/take-until stopper)
|
||||||
(rx/map #(gpt/to-vec from-position %))
|
(rx/map #(gpt/to-vec from-position %))
|
||||||
(rx/switch-map #(snap/closest-snap-move page-id shapes objects layout %))
|
(rx/switch-map #(snap/closest-snap-move page-id shapes objects layout %))
|
||||||
|
(rx/map #(gpt/round % 0))
|
||||||
(rx/map gmt/translate-matrix)
|
(rx/map gmt/translate-matrix)
|
||||||
(rx/map #(set-modifiers ids {:displacement %})))
|
(rx/map #(set-modifiers ids {:displacement %})))
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
(def ^:private snap-accuracy 5)
|
(def ^:private snap-accuracy 5)
|
||||||
(def ^:private snap-distance-accuracy 10)
|
(def ^:private snap-distance-accuracy 10)
|
||||||
|
|
||||||
(defn- remove-from-snap-points [remove-id?]
|
(defn- remove-from-snap-points
|
||||||
|
[remove-id?]
|
||||||
(fn [query-result]
|
(fn [query-result]
|
||||||
(->> query-result
|
(->> query-result
|
||||||
(map (fn [[value data]] [value (remove (comp remove-id? second) data)]))
|
(map (fn [[value data]] [value (remove (comp remove-id? second) data)]))
|
||||||
|
@ -57,12 +58,12 @@
|
||||||
:else zero)))
|
:else zero)))
|
||||||
|
|
||||||
(defn get-snap-points [page-id frame-id filter-shapes point coord]
|
(defn get-snap-points [page-id frame-id filter-shapes point coord]
|
||||||
(let [value (coord point)]
|
(let [value (get point coord)]
|
||||||
(->> (uw/ask! {:cmd :snaps/range-query
|
(->> (uw/ask! {:cmd :snaps/range-query
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:frame-id frame-id
|
:frame-id frame-id
|
||||||
:coord coord
|
:coord coord
|
||||||
:ranges [[(- value 1) (+ value 1)]]})
|
:ranges [[value value]]})
|
||||||
(rx/first)
|
(rx/first)
|
||||||
(rx/map (remove-from-snap-points filter-shapes))
|
(rx/map (remove-from-snap-points filter-shapes))
|
||||||
(rx/map flatten-to-points))))
|
(rx/map flatten-to-points))))
|
||||||
|
@ -147,7 +148,8 @@
|
||||||
|
|
||||||
(if (mth/finite? min-snap) [0 min-snap] nil)))))))
|
(if (mth/finite? min-snap) [0 min-snap] nil)))))))
|
||||||
|
|
||||||
(defn select-shapes-area [page-id shapes objects area-selrect]
|
(defn select-shapes-area
|
||||||
|
[page-id shapes objects area-selrect]
|
||||||
(->> (uw/ask! {:cmd :selection/query
|
(->> (uw/ask! {:cmd :selection/query
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:frame-id (->> shapes first :frame-id)
|
:frame-id (->> shapes first :frame-id)
|
||||||
|
@ -155,13 +157,15 @@
|
||||||
(rx/map #(set/difference % (into #{} (map :id shapes))))
|
(rx/map #(set/difference % (into #{} (map :id shapes))))
|
||||||
(rx/map (fn [ids] (map #(get objects %) ids)))))
|
(rx/map (fn [ids] (map #(get objects %) ids)))))
|
||||||
|
|
||||||
(defn closest-distance-snap [page-id shapes objects movev]
|
(defn closest-distance-snap
|
||||||
|
[page-id shapes objects movev]
|
||||||
(->> (rx/of shapes)
|
(->> (rx/of shapes)
|
||||||
(rx/map #(vector (->> % first :frame-id (get objects))
|
(rx/map #(vector (->> % first :frame-id (get objects))
|
||||||
(-> % gsh/selection-rect (gsh/move movev))))
|
(-> % gsh/selection-rect (gsh/move movev))))
|
||||||
(rx/merge-map
|
(rx/merge-map
|
||||||
(fn [[frame selrect]]
|
(fn [[frame selrect]]
|
||||||
(let [areas (->> (gsh/selrect->areas (or (:selrect frame) (gsh/rect->rect-shape @refs/vbox)) selrect)
|
(let [areas (->> (gsh/selrect->areas (or (:selrect frame)
|
||||||
|
(gsh/rect->rect-shape @refs/vbox)) selrect)
|
||||||
(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))
|
snap-x (search-snap-distance selrect :x (:left areas) (:right areas))
|
||||||
snap-y (search-snap-distance selrect :y (:top areas) (:bottom areas))]
|
snap-y (search-snap-distance selrect :y (:top areas) (:bottom areas))]
|
||||||
|
@ -178,8 +182,7 @@
|
||||||
(not (contains? layout :dynamic-alignment)))))]
|
(not (contains? layout :dynamic-alignment)))))]
|
||||||
(->> (closest-snap page-id frame-id [point] filter-shapes)
|
(->> (closest-snap page-id frame-id [point] filter-shapes)
|
||||||
(rx/map #(or % (gpt/point 0 0)))
|
(rx/map #(or % (gpt/point 0 0)))
|
||||||
(rx/map #(gpt/add point %))
|
(rx/map #(gpt/add point %)))))
|
||||||
)))
|
|
||||||
|
|
||||||
(defn closest-snap-move
|
(defn closest-snap-move
|
||||||
[page-id shapes objects layout movev]
|
[page-id shapes objects layout movev]
|
||||||
|
@ -201,4 +204,7 @@
|
||||||
(closest-distance-snap page-id shapes objects movev)))
|
(closest-distance-snap page-id shapes objects movev)))
|
||||||
(rx/reduce gpt/min)
|
(rx/reduce gpt/min)
|
||||||
(rx/map #(or % (gpt/point 0 0)))
|
(rx/map #(or % (gpt/point 0 0)))
|
||||||
(rx/map #(gpt/add movev %)))))
|
(rx/map #(gpt/add movev %))
|
||||||
|
(rx/map #(gpt/round % 0))
|
||||||
|
)))
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,6 @@
|
||||||
on-pos-x-change #(on-position-change % :x)
|
on-pos-x-change #(on-position-change % :x)
|
||||||
on-pos-y-change #(on-position-change % :y)
|
on-pos-y-change #(on-position-change % :y)
|
||||||
select-all #(-> % (dom/get-target) (.select))]
|
select-all #(-> % (dom/get-target) (.select))]
|
||||||
|
|
||||||
[:div.element-set
|
[:div.element-set
|
||||||
[:div.element-set-content
|
[:div.element-set-content
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
(get sr2 (if (= :x coord) :x1 :y1)))
|
(get sr2 (if (= :x coord) :x1 :y1)))
|
||||||
|
|
||||||
distance (- to-c from-c)
|
distance (- to-c from-c)
|
||||||
distance-str (-> distance (mth/precision 2) str)
|
distance-str (-> distance (mth/precision 0) str)
|
||||||
half-point (half-point coord sr1 sr2)
|
half-point (half-point coord sr1 sr2)
|
||||||
width (-> distance-str
|
width (-> distance-str
|
||||||
count
|
count
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
:font-size (/ pill-text-font-size zoom)
|
:font-size (/ pill-text-font-size zoom)
|
||||||
:fill "white"
|
:fill "white"
|
||||||
:text-anchor "middle"}
|
:text-anchor "middle"}
|
||||||
(mth/precision distance 2)]])
|
(mth/precision distance 0)]])
|
||||||
|
|
||||||
(let [p1 [(+ from-c (/ segment-gap zoom)) (+ half-point (/ segment-gap-side zoom))]
|
(let [p1 [(+ from-c (/ segment-gap zoom)) (+ half-point (/ segment-gap-side zoom))]
|
||||||
p2 [(+ from-c (/ segment-gap zoom)) (- half-point (/ segment-gap-side zoom))]
|
p2 [(+ from-c (/ segment-gap zoom)) (- half-point (/ segment-gap-side zoom))]
|
||||||
|
@ -110,7 +110,7 @@
|
||||||
|
|
||||||
pair->distance+pair
|
pair->distance+pair
|
||||||
(fn [[sh1 sh2]]
|
(fn [[sh1 sh2]]
|
||||||
[(-> (gsh/distance-shapes sh1 sh2) coord (mth/precision 2)) [sh1 sh2]])
|
[(-> (gsh/distance-shapes sh1 sh2) coord (mth/precision 0)) [sh1 sh2]])
|
||||||
|
|
||||||
contains-selected?
|
contains-selected?
|
||||||
(fn [selected pairs]
|
(fn [selected pairs]
|
||||||
|
@ -136,7 +136,7 @@
|
||||||
|
|
||||||
(->> (query-side lt-side)
|
(->> (query-side lt-side)
|
||||||
(rx/combine-latest vector (query-side gt-side)))))
|
(rx/combine-latest vector (query-side gt-side)))))
|
||||||
|
|
||||||
distance-to-selrect
|
distance-to-selrect
|
||||||
(fn [shape]
|
(fn [shape]
|
||||||
(let [sr (:selrect shape)]
|
(let [sr (:selrect shape)]
|
||||||
|
@ -144,11 +144,11 @@
|
||||||
(gsh/distance-selrect sr selrect)
|
(gsh/distance-selrect sr selrect)
|
||||||
(gsh/distance-selrect selrect sr))
|
(gsh/distance-selrect selrect sr))
|
||||||
coord
|
coord
|
||||||
(mth/precision 2))))
|
(mth/precision 0))))
|
||||||
|
|
||||||
get-shapes-match
|
get-shapes-match
|
||||||
(fn [pred? shapes]
|
(fn [pred? shapes]
|
||||||
(->> shapes
|
(->> shapes
|
||||||
(sort-by coord)
|
(sort-by coord)
|
||||||
(d/map-perm vector)
|
(d/map-perm vector)
|
||||||
(filter (fn [[sh1 sh2]] (gsh/overlap-coord? coord sh1 sh2)))
|
(filter (fn [[sh1 sh2]] (gsh/overlap-coord? coord sh1 sh2)))
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
(def ^:private line-color "#D383DA")
|
(def ^:private line-color "#D383DA")
|
||||||
|
|
||||||
(mf/defc snap-point [{:keys [point zoom]}]
|
(mf/defc snap-point
|
||||||
|
[{:keys [point zoom]}]
|
||||||
(let [{:keys [x y]} point
|
(let [{:keys [x y]} point
|
||||||
cross-width (/ 3 zoom)]
|
cross-width (/ 3 zoom)]
|
||||||
[:g
|
[:g
|
||||||
|
@ -24,7 +25,8 @@
|
||||||
:y2 (- y cross-width)
|
:y2 (- y cross-width)
|
||||||
:style {:stroke line-color :stroke-width (str (/ 1 zoom))}}]]))
|
:style {:stroke line-color :stroke-width (str (/ 1 zoom))}}]]))
|
||||||
|
|
||||||
(mf/defc snap-line [{:keys [snap point zoom]}]
|
(mf/defc snap-line
|
||||||
|
[{:keys [snap point zoom]}]
|
||||||
[:line {:x1 (:x snap)
|
[:line {:x1 (:x snap)
|
||||||
:y1 (:y snap)
|
:y1 (:y snap)
|
||||||
:x2 (:x point)
|
:x2 (:x point)
|
||||||
|
@ -32,7 +34,8 @@
|
||||||
:style {:stroke line-color :stroke-width (str (/ 1 zoom))}
|
:style {:stroke line-color :stroke-width (str (/ 1 zoom))}
|
||||||
:opacity 0.4}])
|
:opacity 0.4}])
|
||||||
|
|
||||||
(defn get-snap [coord {:keys [shapes page-id filter-shapes]}]
|
(defn get-snap
|
||||||
|
[coord {:keys [shapes page-id filter-shapes]}]
|
||||||
(->> (rx/from shapes)
|
(->> (rx/from shapes)
|
||||||
(rx/flat-map (fn [shape]
|
(rx/flat-map (fn [shape]
|
||||||
(->> (sp/shape-snap-points shape)
|
(->> (sp/shape-snap-points shape)
|
||||||
|
@ -50,10 +53,11 @@
|
||||||
;; We use sets to store points/lines so there are no points/lines repeated
|
;; We use sets to store points/lines so there are no points/lines repeated
|
||||||
;; can cause problems with react keys
|
;; can cause problems with react keys
|
||||||
snap-points (into #{} (mapcat (fn [[point snaps coord]]
|
snap-points (into #{} (mapcat (fn [[point snaps coord]]
|
||||||
(when (not-empty snaps) (concat [point] snaps))) @state))
|
(cons point snaps))
|
||||||
|
@state))
|
||||||
snap-lines (into #{} (mapcat (fn [[point snaps coord]]
|
snap-lines (into #{} (mapcat (fn [[point snaps coord]]
|
||||||
(when (not-empty snaps) (map #(vector point %) snaps))) @state))]
|
(when (not-empty snaps) (map #(vector point %) snaps))) @state))]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(let [sub
|
(let [sub
|
||||||
|
@ -63,7 +67,7 @@
|
||||||
(get-snap :y %)
|
(get-snap :y %)
|
||||||
(get-snap :x %)))
|
(get-snap :x %)))
|
||||||
(rx/subs #(reset! state %)))]
|
(rx/subs #(reset! state %)))]
|
||||||
|
|
||||||
;; On unmount callback
|
;; On unmount callback
|
||||||
#(rx/dispose! sub))))
|
#(rx/dispose! sub))))
|
||||||
|
|
||||||
|
@ -72,35 +76,36 @@
|
||||||
(fn []
|
(fn []
|
||||||
(rx/push! subject props)))
|
(rx/push! subject props)))
|
||||||
|
|
||||||
|
|
||||||
[:g.snap-feedback
|
[:g.snap-feedback
|
||||||
(for [[from-point to-point] snap-lines]
|
(for [[from-point to-point] snap-lines]
|
||||||
[:& snap-line {:key (str "line-" (:x from-point) "-" (:y from-point) "-" (:x to-point) "-" (:y to-point) "-")
|
[:& snap-line {:key (str "line-" (:x from-point)
|
||||||
|
"-" (:y from-point)
|
||||||
|
"-" (:x to-point)
|
||||||
|
"-" (:y to-point) "-")
|
||||||
:snap from-point
|
:snap from-point
|
||||||
:point to-point
|
:point to-point
|
||||||
:zoom zoom}])
|
:zoom zoom}])
|
||||||
(for [point snap-points]
|
(for [point snap-points]
|
||||||
[:& snap-point {:key (str "point-" (:x point) "-" (:y point))
|
[:& snap-point {:key (str "point-" (:x point)
|
||||||
|
"-" (:y point))
|
||||||
:point point
|
:point point
|
||||||
:zoom zoom}])]))
|
:zoom zoom}])]))
|
||||||
|
|
||||||
(mf/defc snap-points [{:keys [layout]}]
|
(mf/defc snap-points
|
||||||
(let [page-id (mf/deref refs/workspace-page-id)
|
{::mf/wrap [mf/memo]}
|
||||||
selected (mf/deref refs/selected-shapes)
|
[{:keys [layout zoom selected page-id drawing transform] :as props}]
|
||||||
selected-shapes (mf/deref (refs/objects-by-id selected))
|
(let [shapes (mf/deref (refs/objects-by-id selected))
|
||||||
drawing (mf/deref refs/current-drawing-shape)
|
|
||||||
filter-shapes (mf/deref refs/selected-shapes-with-children)
|
filter-shapes (mf/deref refs/selected-shapes-with-children)
|
||||||
filter-shapes (fn [id] (if (= id :layout)
|
filter-shapes (fn [id]
|
||||||
(or (not (contains? layout :display-grid))
|
(if (= id :layout)
|
||||||
(not (contains? layout :snap-grid)))
|
(or (not (contains? layout :display-grid))
|
||||||
(or (filter-shapes id)
|
(not (contains? layout :snap-grid)))
|
||||||
(not (contains? layout :dynamic-alignment)))))
|
(or (filter-shapes id)
|
||||||
current-transform (mf/deref refs/current-transform)
|
(not (contains? layout :dynamic-alignment)))))
|
||||||
snap-data (mf/deref refs/workspace-snap-data)
|
;; current-transform (mf/deref refs/current-transform)
|
||||||
shapes (if drawing [drawing] selected-shapes)
|
;; snap-data (mf/deref refs/workspace-snap-data)
|
||||||
zoom (mf/deref refs/selected-zoom)]
|
shapes (if drawing [drawing] shapes)]
|
||||||
|
(when (or drawing transform)
|
||||||
(when (or drawing current-transform)
|
|
||||||
[:& snap-feedback {:shapes shapes
|
[:& snap-feedback {:shapes shapes
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:filter-shapes filter-shapes
|
:filter-shapes filter-shapes
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
(mf/defc coordinates
|
(mf/defc coordinates
|
||||||
[]
|
[]
|
||||||
(let [coords (some-> (hooks/use-rxsub ms/mouse-position)
|
(let [coords (some-> (hooks/use-rxsub ms/mouse-position)
|
||||||
(gpt/round 0))]
|
(gpt/round))]
|
||||||
[:ul.coordinates
|
[:ul.coordinates
|
||||||
[:span {:alt "x"}
|
[:span {:alt "x"}
|
||||||
(str "X: " (:x coords "-"))]
|
(str "X: " (:x coords "-"))]
|
||||||
|
@ -290,12 +290,13 @@
|
||||||
]
|
]
|
||||||
(-> (gpt/subtract pt brect)
|
(-> (gpt/subtract pt brect)
|
||||||
(gpt/divide (gpt/point @refs/selected-zoom))
|
(gpt/divide (gpt/point @refs/selected-zoom))
|
||||||
(gpt/add box))))
|
(gpt/add box)
|
||||||
|
(gpt/round 0))))
|
||||||
|
|
||||||
on-mouse-move
|
on-mouse-move
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(let [event (.getBrowserEvent event)
|
(let [event (.getBrowserEvent event)
|
||||||
pt (gpt/point (.-clientX event) (.-clientY event))
|
pt (dom/get-client-position event)
|
||||||
pt (translate-point-to-viewport pt)
|
pt (translate-point-to-viewport pt)
|
||||||
delta (gpt/point (.-movementX event)
|
delta (gpt/point (.-movementX event)
|
||||||
(.-movementY event))]
|
(.-movementY event))]
|
||||||
|
@ -457,7 +458,13 @@
|
||||||
(when (contains? layout :display-grid)
|
(when (contains? layout :display-grid)
|
||||||
[:& frame-grid {:zoom zoom}])
|
[:& frame-grid {:zoom zoom}])
|
||||||
|
|
||||||
[:& snap-points {:layout layout}]
|
[:& snap-points {:layout layout
|
||||||
|
:transform (:transform local)
|
||||||
|
:drawing (:drawing local)
|
||||||
|
:zoom zoom
|
||||||
|
:page-id (:id page)
|
||||||
|
:selected selected}]
|
||||||
|
|
||||||
[:& snap-distances {:layout layout}]
|
[:& snap-distances {:layout layout}]
|
||||||
|
|
||||||
(when tooltip
|
(when tooltip
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
[shape]
|
[shape]
|
||||||
(let [shape (gsh/transform-shape shape)
|
(let [shape (gsh/transform-shape shape)
|
||||||
shape-center (gsh/center shape)]
|
shape-center (gsh/center shape)]
|
||||||
(case (:type shape)
|
(if (= :frame (:type shape))
|
||||||
:frame (-> shape gsh/shape->rect-shape frame-snap-points)
|
(-> shape
|
||||||
(into #{shape-center} (-> shape :points)))))
|
(gsh/shape->rect-shape)
|
||||||
|
(frame-snap-points))
|
||||||
|
(into #{shape-center} (:points shape)))))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Balanced Binary Search Tree based on the red-black BST
|
* Balanced Binary Search Tree based on the red-black BST
|
||||||
* described at "Algorithms" by Robert Sedwick & Kevin Wayne
|
* described at "Algorithms" by Robert Sedwick & Kevin Wayne
|
||||||
*/
|
*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
@ -27,7 +27,7 @@ goog.scope(function() {
|
||||||
RED: 1,
|
RED: 1,
|
||||||
BLACK: 2
|
BLACK: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
class Node {
|
class Node {
|
||||||
constructor(value, data) {
|
constructor(value, data) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
@ -37,7 +37,7 @@ goog.scope(function() {
|
||||||
this.color = Color.BLACK;
|
this.color = Color.BLACK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will store a map from key to list of data
|
// Will store a map from key to list of data
|
||||||
// value => [ data ]
|
// value => [ data ]
|
||||||
// The values can be queried in range and the data stored will be retrived whole
|
// The values can be queried in range and the data stored will be retrived whole
|
||||||
|
@ -46,13 +46,13 @@ goog.scope(function() {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.root = null;
|
this.root = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
insert(value, data) {
|
insert(value, data) {
|
||||||
this.root = recInsert(this.root, value, data);
|
this.root = recInsert(this.root, value, data);
|
||||||
this.root.color = Color.BLACK;
|
this.root.color = Color.BLACK;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(value, data) {
|
remove(value, data) {
|
||||||
if (!this.root) {
|
if (!this.root) {
|
||||||
return this;
|
return this;
|
||||||
|
@ -76,16 +76,16 @@ goog.scope(function() {
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
update (value, oldData, newData) {
|
update (value, oldData, newData) {
|
||||||
this.root = recUpdate(this.root, value, oldData, newData);
|
this.root = recUpdate(this.root, value, oldData, newData);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(value) {
|
get(value) {
|
||||||
return recGet(this.root, value);
|
return recGet(this.root, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
rangeQuery (fromValue, toValue) {
|
rangeQuery (fromValue, toValue) {
|
||||||
return recRangeQuery(this.root, fromValue, toValue, []);
|
return recRangeQuery(this.root, fromValue, toValue, []);
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ goog.scope(function() {
|
||||||
return recGet(branch.right, value);
|
return recGet(branch.right, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function recUpdate(branch, value, oldData, newData) {
|
function recUpdate(branch, value, oldData, newData) {
|
||||||
if (branch === null) {
|
if (branch === null) {
|
||||||
return branch;
|
return branch;
|
||||||
|
|
|
@ -31,9 +31,9 @@
|
||||||
(map #(vector % (:id shape)) points))
|
(map #(vector % (:id shape)) points))
|
||||||
|
|
||||||
;; The grid points are only added by the "root" of the coord-dat
|
;; The grid points are only added by the "root" of the coord-dat
|
||||||
(if (= (:id shape) frame-id)
|
(when (= (:id shape) frame-id)
|
||||||
(let [points (gg/grid-snap-points shape coord)]
|
(let [points (gg/grid-snap-points shape coord)]
|
||||||
(map #(vector % :layout) points))))))
|
(map #(vector % :layout) points))))))
|
||||||
into-tree (fn [tree [point _ :as data]]
|
into-tree (fn [tree [point _ :as data]]
|
||||||
(rt/insert tree (coord point) data))]
|
(rt/insert tree (coord point) data))]
|
||||||
(->> shapes
|
(->> shapes
|
||||||
|
@ -48,9 +48,10 @@
|
||||||
(group-by :frame-id))
|
(group-by :frame-id))
|
||||||
frame-shapes (->> (cph/select-frames objects)
|
frame-shapes (->> (cph/select-frames objects)
|
||||||
(reduce #(update %1 (:id %2) conj %2) frame-shapes))]
|
(reduce #(update %1 (:id %2) conj %2) frame-shapes))]
|
||||||
|
|
||||||
(d/mapm (fn [frame-id shapes] {:x (create-coord-data frame-id shapes :x)
|
(d/mapm (fn [frame-id shapes] {:x (create-coord-data frame-id shapes :x)
|
||||||
:y (create-coord-data frame-id shapes :y)})
|
:y (create-coord-data frame-id shapes :y)})
|
||||||
frame-shapes)))
|
frame-shapes)))
|
||||||
|
|
||||||
(defn- log-state
|
(defn- log-state
|
||||||
"Helper function to print a friendly version of the snap tree. Debugging purposes"
|
"Helper function to print a friendly version of the snap tree. Debugging purposes"
|
||||||
|
@ -74,7 +75,7 @@
|
||||||
(index-page state id objects)))]
|
(index-page state id objects)))]
|
||||||
(swap! state #(reduce process-page % pages)))
|
(swap! state #(reduce process-page % pages)))
|
||||||
|
|
||||||
#_(log-state)
|
;; (log-state)
|
||||||
;; Return nil so the worker will not answer anything back
|
;; Return nil so the worker will not answer anything back
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@
|
||||||
[{:keys [page-id objects] :as message}]
|
[{:keys [page-id objects] :as message}]
|
||||||
;; TODO: Check the difference and update the index acordingly
|
;; TODO: Check the difference and update the index acordingly
|
||||||
(swap! state index-page page-id objects)
|
(swap! state index-page page-id objects)
|
||||||
#_(log-state)
|
;; (log-state)
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defmethod impl/handler :snaps/range-query
|
(defmethod impl/handler :snaps/range-query
|
||||||
|
@ -96,3 +97,4 @@
|
||||||
set ;; unique
|
set ;; unique
|
||||||
(into []))))
|
(into []))))
|
||||||
|
|
||||||
|
|
||||||
|
|
3
package-lock.json
generated
3
package-lock.json
generated
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"lockfileVersion": 1
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue