mirror of
https://github.com/penpot/penpot.git
synced 2026-09-09 05:28:43 +00:00
🐛 Fix stroke caps misplaced when adding node in middle of path
This commit is contained in:
parent
6a0f24e691
commit
892869b039
@ -999,6 +999,35 @@
|
|||||||
;; result should have more segments than original (splits added)
|
;; result should have more segments than original (splits added)
|
||||||
(t/is (> (count result) (count sample-content-square)))))
|
(t/is (> (count result) (count sample-content-square)))))
|
||||||
|
|
||||||
|
;; Regression test for issue #8301: clicking a hover point on a path segment
|
||||||
|
;; must insert exactly one node. The bug caused two actions to fire together —
|
||||||
|
;; create-node-at-position (correct) and add-node (extra) — so the midpoint M
|
||||||
|
;; was appended again as a tail endpoint, giving [M A L M L B L M] instead of
|
||||||
|
;; the correct [M A L M L B]. The stroke markerEnd then landed in the middle.
|
||||||
|
;; The invariant: split-segments on a 2-command open path produces exactly 3
|
||||||
|
;; commands and does not repeat the inserted midpoint at the tail.
|
||||||
|
(t/deftest segment-split-segments-no-duplicate-endpoint
|
||||||
|
(let [;; Simple open path: A=(0,0) → B=(100,0)
|
||||||
|
segments [{:command :move-to :params {:x 0.0 :y 0.0}}
|
||||||
|
{:command :line-to :params {:x 100.0 :y 0.0}}]
|
||||||
|
from-p (gpt/point 0.0 0.0)
|
||||||
|
to-p (gpt/point 100.0 0.0)
|
||||||
|
content (path/content segments)
|
||||||
|
result (path.segment/split-segments content #{from-p to-p} 0.5)
|
||||||
|
cmds (mapv :command result)]
|
||||||
|
|
||||||
|
;; Must be exactly 3 commands: move-to A, line-to M, line-to B
|
||||||
|
(t/is (= 3 (count result)))
|
||||||
|
(t/is (= [:move-to :line-to :line-to] cmds))
|
||||||
|
|
||||||
|
;; Midpoint M must be at (50, 0)
|
||||||
|
(t/is (mth/close? 50.0 (get-in result [1 :params :x])))
|
||||||
|
(t/is (mth/close? 0.0 (get-in result [1 :params :y])))
|
||||||
|
|
||||||
|
;; Original endpoint B must still be at (100, 0) — not shadowed by a duplicate M
|
||||||
|
(t/is (mth/close? 100.0 (get-in result [2 :params :x])))
|
||||||
|
(t/is (mth/close? 0.0 (get-in result [2 :params :y])))))
|
||||||
|
|
||||||
(t/deftest segment-content->selrect
|
(t/deftest segment-content->selrect
|
||||||
(let [content (path/content sample-content-square)
|
(let [content (path/content sample-content-square)
|
||||||
rect (path.segment/content->selrect content)]
|
rect (path.segment/content->selrect content)]
|
||||||
|
|||||||
@ -68,31 +68,34 @@
|
|||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
|
|
||||||
|
;; When clicking on a hover point that lies on a segment (has metadata with
|
||||||
|
;; split params), only insert the node — don't also run draw-mode actions which
|
||||||
|
;; would add the same position as an extra endpoint, corrupting the path order
|
||||||
|
;; and misplacing stroke caps.
|
||||||
;; FIXME: revisit this, using meta here breaks equality checks
|
;; FIXME: revisit this, using meta here breaks equality checks
|
||||||
(when (and is-new (some? (meta position)))
|
(if (and is-new (some? (meta position)))
|
||||||
(st/emit! (drp/create-node-at-position (meta position))))
|
(st/emit! (drp/create-node-at-position (meta position)))
|
||||||
|
(let [is-shift (kbd/shift? event)
|
||||||
|
is-mod (kbd/mod? event)]
|
||||||
|
(cond
|
||||||
|
is-last
|
||||||
|
(st/emit! (drp/reset-last-handler))
|
||||||
|
|
||||||
(let [is-shift (kbd/shift? event)
|
(and is-move is-mod (not is-curve))
|
||||||
is-mod (kbd/mod? event)]
|
(st/emit! (drp/make-curve position))
|
||||||
(cond
|
|
||||||
is-last
|
|
||||||
(st/emit! (drp/reset-last-handler))
|
|
||||||
|
|
||||||
(and is-move is-mod (not is-curve))
|
(and is-move is-mod is-curve)
|
||||||
(st/emit! (drp/make-curve position))
|
(st/emit! (drp/make-corner position))
|
||||||
|
|
||||||
(and is-move is-mod is-curve)
|
is-move
|
||||||
(st/emit! (drp/make-corner position))
|
;; If we're dragging a selected item we don't change the selection
|
||||||
|
(st/emit! (drp/start-move-path-point position is-shift))
|
||||||
|
|
||||||
is-move
|
(and is-draw is-start-path)
|
||||||
;; If we're dragging a selected item we don't change the selection
|
(st/emit! (drp/start-path-from-point position))
|
||||||
(st/emit! (drp/start-move-path-point position is-shift))
|
|
||||||
|
|
||||||
(and is-draw is-start-path)
|
(and is-draw (not is-start-path))
|
||||||
(st/emit! (drp/start-path-from-point position))
|
(st/emit! (drp/close-path-drag-start position)))))))]
|
||||||
|
|
||||||
(and is-draw (not is-start-path))
|
|
||||||
(st/emit! (drp/close-path-drag-start position))))))]
|
|
||||||
|
|
||||||
[:g.path-point
|
[:g.path-point
|
||||||
[:circle.path-point
|
[:circle.path-point
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user