mirror of
https://github.com/penpot/penpot.git
synced 2025-07-18 05:57:14 +02:00
✨ Add minor improvements to get-segments-with-points
And rename it from `get-segments`
This commit is contained in:
parent
3a22545158
commit
60f754f172
3 changed files with 62 additions and 45 deletions
|
@ -507,76 +507,66 @@
|
||||||
(update next-i #(line->curve point %))))]
|
(update next-i #(line->curve point %))))]
|
||||||
(reduce add-curve content vectors)))))
|
(reduce add-curve content vectors)))))
|
||||||
|
|
||||||
;; FIXME: revisit the impl of this function
|
(defn get-segments-with-points
|
||||||
(defn get-segments
|
|
||||||
"Given a content and a set of points return all the segments in the path
|
"Given a content and a set of points return all the segments in the path
|
||||||
that uses the points"
|
that uses the points"
|
||||||
[content points]
|
[content points]
|
||||||
(let [point-set (set points)]
|
(let [point-set (set points)]
|
||||||
|
(loop [result (transient [])
|
||||||
(loop [segments []
|
|
||||||
prev-point nil
|
prev-point nil
|
||||||
start-point nil
|
start-point nil
|
||||||
index 0
|
index 0
|
||||||
cur-segment (first content)
|
content (seq content)]
|
||||||
content (rest content)]
|
(if-let [{:keys [command] :as segment} (first content)]
|
||||||
|
(let [close-path? (= command :close-path)
|
||||||
|
move-to? (= command :move-to)
|
||||||
|
|
||||||
(let [command (:command cur-segment)
|
cur-point (if close-path?
|
||||||
close-path? (= command :close-path)
|
start-point
|
||||||
move-to? (= command :move-to)
|
(helpers/segment->point segment))
|
||||||
|
|
||||||
;; Close-path makes a segment from the last point to the initial path point
|
;; If there is a move-to we don't have a segment
|
||||||
cur-point (if close-path?
|
prev-point (if move-to?
|
||||||
start-point
|
nil
|
||||||
(helpers/segment->point cur-segment))
|
prev-point)
|
||||||
|
|
||||||
;; If there is a move-to we don't have a segment
|
;; We update the start point
|
||||||
prev-point (if move-to?
|
start-point (if move-to?
|
||||||
nil
|
cur-point
|
||||||
prev-point)
|
start-point)
|
||||||
|
|
||||||
;; We update the start point
|
result (cond-> result
|
||||||
start-point (if move-to?
|
(and (some? prev-point)
|
||||||
cur-point
|
(contains? point-set prev-point)
|
||||||
start-point)
|
(contains? point-set cur-point))
|
||||||
|
|
||||||
is-segment? (and (some? prev-point)
|
(conj! (-> segment
|
||||||
(contains? point-set prev-point)
|
(assoc :start prev-point)
|
||||||
(contains? point-set cur-point))
|
(assoc :end cur-point)
|
||||||
|
(assoc :index index))))]
|
||||||
segments (cond-> segments
|
(recur result
|
||||||
is-segment?
|
|
||||||
(conj {:start prev-point
|
|
||||||
:end cur-point
|
|
||||||
:segment cur-segment
|
|
||||||
:index index}))]
|
|
||||||
|
|
||||||
(if (some? cur-segment)
|
|
||||||
(recur segments
|
|
||||||
cur-point
|
cur-point
|
||||||
start-point
|
start-point
|
||||||
(inc index)
|
(inc index)
|
||||||
(first content)
|
(rest content)))
|
||||||
(rest content))
|
|
||||||
|
|
||||||
segments)))))
|
(persistent! result)))))
|
||||||
|
|
||||||
(defn split-segments
|
(defn split-segments
|
||||||
"Given a content creates splits commands between points with new segments"
|
"Given a content creates splits commands between points with new segments"
|
||||||
[content points value]
|
[content points value]
|
||||||
|
|
||||||
(let [split-command
|
(let [split-command
|
||||||
(fn [{:keys [start end segment index]}]
|
(fn [{:keys [command start end index] :as segment}]
|
||||||
(case (:command segment)
|
(case command
|
||||||
:line-to [index (helpers/split-line-to start segment value)]
|
:line-to [index (helpers/split-line-to start segment value)]
|
||||||
:curve-to [index (helpers/split-curve-to start segment value)]
|
:curve-to [index (helpers/split-curve-to start segment value)]
|
||||||
:close-path [index [(helpers/make-line-to (gpt/lerp start end value)) segment]]
|
:close-path [index [(helpers/make-line-to (gpt/lerp start end value)) segment]]
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
segment-changes
|
segment-changes
|
||||||
(->> (get-segments content points)
|
(->> (get-segments-with-points content points)
|
||||||
(into {} (comp (map split-command)
|
(into {} (keep split-command)))
|
||||||
(filter (comp not nil?)))))
|
|
||||||
|
|
||||||
process-segments
|
process-segments
|
||||||
(fn [[index command]]
|
(fn [[index command]]
|
||||||
|
@ -680,7 +670,7 @@
|
||||||
|
|
||||||
(let [segments-set (into #{}
|
(let [segments-set (into #{}
|
||||||
(map (juxt :start :end))
|
(map (juxt :start :end))
|
||||||
(get-segments content points))
|
(get-segments-with-points content points))
|
||||||
|
|
||||||
create-line-command (fn [point other]
|
create-line-command (fn [point other]
|
||||||
[(helpers/make-move-to point)
|
[(helpers/make-move-to point)
|
||||||
|
@ -802,7 +792,7 @@
|
||||||
(defn merge-nodes
|
(defn merge-nodes
|
||||||
"Reduces the contiguous segments in points to a single point"
|
"Reduces the contiguous segments in points to a single point"
|
||||||
[content points]
|
[content points]
|
||||||
(let [segments (get-segments content points)]
|
(let [segments (get-segments-with-points content points)]
|
||||||
(if (seq segments)
|
(if (seq segments)
|
||||||
(let [point->merge-point (-> segments
|
(let [point->merge-point (-> segments
|
||||||
(group-segments)
|
(group-segments)
|
||||||
|
|
|
@ -276,3 +276,30 @@
|
||||||
(t/is (= result1 expect))
|
(t/is (= result1 expect))
|
||||||
(t/is (= result2 expect))
|
(t/is (= result2 expect))
|
||||||
(t/is (= result3 expect))))
|
(t/is (= result3 expect))))
|
||||||
|
|
||||||
|
(def sample-content-square
|
||||||
|
[{:command :move-to, :params {:x 0, :y 0}}
|
||||||
|
{:command :line-to, :params {:x 10, :y 0}}
|
||||||
|
{:command :line-to, :params {:x 10, :y 10}}
|
||||||
|
{:command :line-to, :params {:x 10, :y 0}}
|
||||||
|
{:command :line-to, :params {:x 0, :y 10}}
|
||||||
|
{:command :line-to, :params {:x 0, :y 0}}
|
||||||
|
{:command :close-path :params {}}])
|
||||||
|
|
||||||
|
(t/deftest get-segments
|
||||||
|
(let [content (path/content sample-content-square)
|
||||||
|
points #{(gpt/point 10.0 0.0)
|
||||||
|
(gpt/point 0.0 0.0)}
|
||||||
|
result (path.segment/get-segments-with-points content points)
|
||||||
|
expect [{:command :line-to,
|
||||||
|
:params {:x 10.0, :y 0.0},
|
||||||
|
:start (gpt/point 0.0 0.0)
|
||||||
|
:end (gpt/point 10.0 0.0)
|
||||||
|
:index 1}
|
||||||
|
{:command :close-path,
|
||||||
|
:params {},
|
||||||
|
:start (gpt/point 0.0 0.0)
|
||||||
|
:end (gpt/point 0.0 0.0)
|
||||||
|
:index 6}]]
|
||||||
|
|
||||||
|
(t/is (= result expect))))
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
|
|
||||||
(defn check-enabled [content selected-points]
|
(defn check-enabled [content selected-points]
|
||||||
(let [segments (path.segm/get-segments content selected-points)
|
(let [segments (path.segm/get-segments-with-points content selected-points)
|
||||||
num-segments (count segments)
|
num-segments (count segments)
|
||||||
num-points (count selected-points)
|
num-points (count selected-points)
|
||||||
points-selected? (seq selected-points)
|
points-selected? (seq selected-points)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue