Skip to content

Commit 8b3a2d4

Browse files
fix(library): keep a bend lane the user dragged close to a stub, don't snap it clear
Root cause of diagram 87's "drag jumps back": after the release preserved the dragged lane, the final `pushLanesClearOfStubs` pass enforced a 30px clearance between any lane and a parallel stub and shoved the lane straight back to the clearance line — so dragging the down-run of a narrow U to 15px from the up-stub snapped it from 665 back to 650. That clearance exists to keep a FRESH route from stair-stepping through a sliver next to a stub. It must not override geometry the user placed: a lane the stored/dragged route already has on THIS side of the stub is theirs, even a deliberately narrow U. Push now fires only for a lane with no stored side yet, or one that FLIPPED across the stub to the far side; a same-side stored lane is kept. diagram 87: the dragged lane now sticks at 665 (was snapping to 650); dragging it all the way onto the stub still folds and collapses the U. Unit test covers the narrow-U lane; 1527 unit + quality gate, node-move re-projection, fresh-bend, interactions, reset, anchoring, live-reflow e2e green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 0d160b7 commit 8b3a2d4

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

library/lib/utils/edgeUtils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,12 @@ const pushLanesClearOfStubs = (
19991999
previous !== line &&
20002000
Math.sign(start[lane] - line) !== Math.sign(previous - line)
20012001
)
2002-
if (isClear(start[lane]) && !flipped) continue
2002+
// A lane the stored route already placed on THIS side of the stub is the user's —
2003+
// even a deliberately narrow U that runs close to a parallel stub. Keep it. Only
2004+
// re-clear a lane that has no stored side yet (a fresh route) or one that FLIPPED
2005+
// across the stub to the far side. Otherwise dragging a lane toward a stub would be
2006+
// snapped straight back to the clearance line.
2007+
if (!flipped && (isClear(start[lane]) || previous !== undefined)) continue
20032008

20042009
const reference = previous ?? start[lane]
20052010
const candidates = lines

library/tests/unit/edgeUtils.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,27 @@ describe("removeDuplicatePoints", () => {
840840
// preserveOrthogonalEdgePoints
841841
// ---------------------------------------------------------------------------
842842
describe("preserveOrthogonalEdgePoints", () => {
843+
it("keeps a lane the user dragged close to a parallel stub (a narrow U), not snapped clear", () => {
844+
// diagram 87: the down-run (x=665) was dragged to 15px from the source up-stub
845+
// (x=680). It must STAY at 665 — pushing it to the 30px clearance line (650) snapped
846+
// the drag straight back. A lane already on this side of the stub is the user's.
847+
const dragged = [
848+
{ x: 680, y: 155 },
849+
{ x: 680, y: -150 },
850+
{ x: 665, y: -150 },
851+
{ x: 665, y: -10 },
852+
{ x: 575, y: -10 },
853+
]
854+
const result = preserveOrthogonalEdgePoints(
855+
dragged,
856+
{ x: 680, y: 155 },
857+
{ x: 575, y: -10 },
858+
Position.Top,
859+
Position.Right
860+
)
861+
expect(result).toEqual(dragged)
862+
})
863+
843864
it("keeps a manually moved bend when the target handle moves lower on the same side", () => {
844865
const result = preserveOrthogonalEdgePoints(
845866
[

0 commit comments

Comments
 (0)