mirror of
https://github.com/penpot/penpot.git
synced 2025-06-05 23:21:38 +02:00
✨ Improved dynaic alignment
This commit is contained in:
parent
f45d3f9c65
commit
3bb4fcb28f
4 changed files with 79 additions and 27 deletions
|
@ -406,6 +406,10 @@
|
||||||
:y miny
|
:y miny
|
||||||
:width (- maxx minx)
|
:width (- maxx minx)
|
||||||
:height (- maxy miny)
|
:height (- maxy miny)
|
||||||
|
:points [(gpt/point minx miny)
|
||||||
|
(gpt/point maxx miny)
|
||||||
|
(gpt/point maxx maxy)
|
||||||
|
(gpt/point minx maxy)]
|
||||||
:type :rect}))
|
:type :rect}))
|
||||||
|
|
||||||
(defn translate-to-frame
|
(defn translate-to-frame
|
||||||
|
@ -674,7 +678,7 @@
|
||||||
|
|
||||||
resize-transform (:resize-transform modifiers (gmt/matrix))
|
resize-transform (:resize-transform modifiers (gmt/matrix))
|
||||||
resize-transform-inverse (:resize-transform-inverse modifiers (gmt/matrix))
|
resize-transform-inverse (:resize-transform-inverse modifiers (gmt/matrix))
|
||||||
rt-modif (:rotation modifiers 0)
|
rt-modif (or (:rotation modifiers) 0)
|
||||||
|
|
||||||
shape (-> shape
|
shape (-> shape
|
||||||
(transform ds-modifier))
|
(transform ds-modifier))
|
||||||
|
@ -792,8 +796,8 @@
|
||||||
(assoc $ :points (shape->points $))
|
(assoc $ :points (shape->points $))
|
||||||
(assoc $ :selrect (points->selrect (:points $)))
|
(assoc $ :selrect (points->selrect (:points $)))
|
||||||
(update $ :selrect fix-invalid-rect-values)
|
(update $ :selrect fix-invalid-rect-values)
|
||||||
(update $ :rotation #(mod (+ (or % 0) (get-in $ [:modifiers :rotation] 0)) 360))
|
(update $ :rotation #(mod (+ (or % 0)
|
||||||
)]
|
(or (get-in $ [:modifiers :rotation]) 0)) 360)))]
|
||||||
new-shape))
|
new-shape))
|
||||||
|
|
||||||
(declare update-path-selrect)
|
(declare update-path-selrect)
|
||||||
|
|
|
@ -193,10 +193,12 @@
|
||||||
(not (contains? layout :snap-grid)))
|
(not (contains? layout :snap-grid)))
|
||||||
(or (filter-shapes id)
|
(or (filter-shapes id)
|
||||||
(not (contains? layout :dynamic-alignment)))))
|
(not (contains? layout :dynamic-alignment)))))
|
||||||
shapes-points (->> shapes
|
shape (if (> (count shapes) 1)
|
||||||
;; Unroll all the possible snap-points
|
(->> shapes (map gsh/transform-shape) gsh/selection-rect)
|
||||||
(mapcat (partial sp/shape-snap-points))
|
(->> shapes (first)))
|
||||||
|
|
||||||
|
shapes-points (->> shape
|
||||||
|
(sp/shape-snap-points)
|
||||||
;; Move the points in the translation vector
|
;; Move the points in the translation vector
|
||||||
(map #(gpt/add % movev)))]
|
(map #(gpt/add % movev)))]
|
||||||
(->> (rx/merge (closest-snap page-id frame-id shapes-points filter-shapes)
|
(->> (rx/merge (closest-snap page-id frame-id shapes-points filter-shapes)
|
||||||
|
@ -205,6 +207,5 @@
|
||||||
(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))
|
(rx/map #(gpt/round % 0)))))
|
||||||
)))
|
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@
|
||||||
(map pair->distance+pair)
|
(map pair->distance+pair)
|
||||||
(filter (comp pred? first))))
|
(filter (comp pred? first))))
|
||||||
|
|
||||||
;; Checks if the value is in a set of numbers with an error margin of 0.1
|
;; Checks if the value is in a set of numbers with an error margin
|
||||||
check-in-set
|
check-in-set
|
||||||
(fn [value number-set]
|
(fn [value number-set]
|
||||||
(->> number-set
|
(->> number-set
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.snap :as snap]
|
[app.main.snap :as snap]
|
||||||
[app.util.geom.snap-points :as sp]
|
[app.util.geom.snap-points :as sp]
|
||||||
|
@ -19,6 +20,13 @@
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
||||||
(def ^:private line-color "#D383DA")
|
(def ^:private line-color "#D383DA")
|
||||||
|
(def ^:private line-opacity 0.6)
|
||||||
|
(def ^:private line-width 1)
|
||||||
|
|
||||||
|
;; Configuration for debug
|
||||||
|
;; (def ^:private line-color "red")
|
||||||
|
;; (def ^:private line-opacity 1 )
|
||||||
|
;; (def ^:private line-width 2)
|
||||||
|
|
||||||
(mf/defc snap-point
|
(mf/defc snap-point
|
||||||
[{:keys [point zoom]}]
|
[{:keys [point zoom]}]
|
||||||
|
@ -31,12 +39,12 @@
|
||||||
:y1 (- y cross-width)
|
:y1 (- y cross-width)
|
||||||
:x2 (+ x cross-width)
|
:x2 (+ x cross-width)
|
||||||
:y2 (+ y cross-width)
|
:y2 (+ y cross-width)
|
||||||
:style {:stroke line-color :stroke-width (str (/ 1 zoom))}}]
|
:style {:stroke line-color :stroke-width (str (/ line-width zoom))}}]
|
||||||
[:line {:x1 (- x cross-width)
|
[:line {:x1 (- x cross-width)
|
||||||
:y1 (+ y cross-width)
|
:y1 (+ y cross-width)
|
||||||
:x2 (+ x cross-width)
|
:x2 (+ x cross-width)
|
||||||
:y2 (- y cross-width)
|
:y2 (- y cross-width)
|
||||||
:style {:stroke line-color :stroke-width (str (/ 1 zoom))}}]]))
|
:style {:stroke line-color :stroke-width (str (/ line-width zoom))}}]]))
|
||||||
|
|
||||||
(mf/defc snap-line
|
(mf/defc snap-line
|
||||||
[{:keys [snap point zoom]}]
|
[{:keys [snap point zoom]}]
|
||||||
|
@ -44,19 +52,56 @@
|
||||||
:y1 (mth/round (:y snap))
|
:y1 (mth/round (:y snap))
|
||||||
:x2 (mth/round (:x point))
|
:x2 (mth/round (:x point))
|
||||||
:y2 (mth/round (:y point))
|
:y2 (mth/round (:y point))
|
||||||
:style {:stroke line-color :stroke-width (str (/ 1 zoom))}
|
:style {:stroke line-color :stroke-width (str (/ line-width zoom))}
|
||||||
:opacity 0.4}])
|
:opacity line-opacity}])
|
||||||
|
|
||||||
(defn get-snap
|
(defn get-snap
|
||||||
[coord {:keys [shapes page-id filter-shapes]}]
|
[coord {:keys [shapes page-id filter-shapes]}]
|
||||||
(->> (rx/from shapes)
|
(let [shape (if (> (count shapes) 1)
|
||||||
(rx/flat-map (fn [shape]
|
(->> shapes (map gsh/transform-shape) gsh/selection-rect)
|
||||||
(->> (sp/shape-snap-points shape)
|
(->> shapes (first)))
|
||||||
(map #(vector (:frame-id shape) %)))))
|
|
||||||
(rx/flat-map (fn [[frame-id point]]
|
frame-id (snap/snap-frame-id shapes)]
|
||||||
(->> (snap/get-snap-points page-id frame-id filter-shapes point coord)
|
|
||||||
(rx/map #(vector point % coord)))))
|
(->> (rx/of shape)
|
||||||
(rx/reduce conj [])))
|
(rx/flat-map (fn [shape]
|
||||||
|
(->> (sp/shape-snap-points shape)
|
||||||
|
(map #(vector frame-id %)))))
|
||||||
|
(rx/flat-map (fn [[frame-id point]]
|
||||||
|
(->> (snap/get-snap-points page-id frame-id filter-shapes point coord)
|
||||||
|
(rx/map #(vector point % coord)))))
|
||||||
|
(rx/reduce conj []))))
|
||||||
|
|
||||||
|
(defn- flip
|
||||||
|
"Function that reverses the x/y coordinates to their counterpart"
|
||||||
|
[coord]
|
||||||
|
(if (= coord :x) :y :x))
|
||||||
|
|
||||||
|
(defn add-point-to-snaps
|
||||||
|
[[point snaps coord]]
|
||||||
|
(let [normalize-coord #(assoc % coord (get point coord))]
|
||||||
|
(cons point (map normalize-coord snaps))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn- process-snap-lines
|
||||||
|
"Gets the snaps for a coordinate and creates lines with a fixed coordinate"
|
||||||
|
[snaps coord]
|
||||||
|
(->> snaps
|
||||||
|
;; only snap on the `coord` coordinate
|
||||||
|
(filter #(= (nth % 2) coord))
|
||||||
|
;; we add the point so the line goes from the point to the snap
|
||||||
|
(mapcat add-point-to-snaps)
|
||||||
|
;; We flatten because it's a list of from-to points
|
||||||
|
(flatten)
|
||||||
|
;; Put together the points of the coordinate
|
||||||
|
(group-by coord)
|
||||||
|
;; Keep only the other coordinate
|
||||||
|
(d/mapm #(map (flip coord) %2))
|
||||||
|
;; Finally get the max/min and this will define the line to draw
|
||||||
|
(d/mapm #(vector (apply min %2) (apply max %2)))
|
||||||
|
;; Change the structure to retrieve a list of lines from/todo
|
||||||
|
(map (fn [[fixedv [minv maxv]]] [(hash-map coord fixedv (flip coord) minv)
|
||||||
|
(hash-map coord fixedv (flip coord) maxv)]))))
|
||||||
|
|
||||||
(mf/defc snap-feedback
|
(mf/defc snap-feedback
|
||||||
[{:keys [shapes page-id filter-shapes zoom] :as props}]
|
[{:keys [shapes page-id filter-shapes zoom] :as props}]
|
||||||
|
@ -65,11 +110,12 @@
|
||||||
|
|
||||||
;; 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 (->> @state
|
||||||
(cons point snaps))
|
(mapcat add-point-to-snaps)
|
||||||
@state))
|
(into #{}))
|
||||||
snap-lines (into #{} (mapcat (fn [[point snaps coord]]
|
|
||||||
(when (not-empty snaps) (map #(vector point %) snaps))) @state))]
|
snap-lines (into (process-snap-lines @state :x)
|
||||||
|
(process-snap-lines @state :y))]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -78,7 +124,8 @@
|
||||||
d/concat
|
d/concat
|
||||||
(get-snap :y %)
|
(get-snap :y %)
|
||||||
(get-snap :x %)))
|
(get-snap :x %)))
|
||||||
(rx/subs #(reset! state %)))]
|
(rx/subs #(let [rs (filter (fn [[_ snaps _]] (> (count snaps) 0)) %)]
|
||||||
|
(reset! state rs))))]
|
||||||
|
|
||||||
;; On unmount callback
|
;; On unmount callback
|
||||||
#(rx/dispose! sub))))
|
#(rx/dispose! sub))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue