From 373b940e75728fcf4fb9b0359b04728aad36c521 Mon Sep 17 00:00:00 2001 From: Mark Tolmacs Date: Sun, 2 Mar 2025 18:22:45 +0100 Subject: [PATCH] New simple arrows stick to outline as well --- packages/element/src/linearElementEditor.ts | 68 +++++++++++++-------- packages/excalidraw/components/App.tsx | 14 ++++- 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/packages/element/src/linearElementEditor.ts b/packages/element/src/linearElementEditor.ts index 40f066c812..79f4cc76ea 100644 --- a/packages/element/src/linearElementEditor.ts +++ b/packages/element/src/linearElementEditor.ts @@ -239,6 +239,43 @@ export class LinearElementEditor { }); } + static getOutlineAvoidingPoint( + element: NonDeleted, + coords: { x: number; y: number }, + pointIndex: number, + app: AppClassProperties, + ): GlobalPoint { + const elbowed = isElbowArrow(element); + const hoveredElement = getHoveredElementForBinding( + coords, + app.scene.getNonDeletedElements(), + app.scene.getNonDeletedElementsMap(), + app.state.zoom, + elbowed, + elbowed, + ); + const p = pointFrom(coords.x, coords.y); + + if (hoveredElement) { + const newPoints = Array.from(element.points); + newPoints[pointIndex] = pointFrom( + p[0] - element.x, + p[1] - element.y, + ); + + return bindPointToSnapToElementOutline( + { + ...element, + points: newPoints, + }, + hoveredElement, + pointIndex === 0 ? "start" : "end", + ); + } + + return p; + } + /** * @returns whether point was dragged */ @@ -352,33 +389,16 @@ export class LinearElementEditor { pointIndex === 0 || pointIndex === element.points.length - 1 ) { - const hoveredElement = getHoveredElementForBinding( - { - x: scenePointerX, - y: scenePointerY, - }, - app.scene.getNonDeletedElements(), - app.scene.getNonDeletedElementsMap(), - app.state.zoom, - elbowed, - elbowed, - ); - - if (hoveredElement) { - const newPoints = Array.from(element.points); - newPoints[pointIndex] = pointFrom( - element.points[pointIndex][0] + deltaX, - element.points[pointIndex][1] + deltaY, - ); - globalNewPointPosition = bindPointToSnapToElementOutline( + globalNewPointPosition = + LinearElementEditor.getOutlineAvoidingPoint( + element, { - ...element, - points: newPoints, + x: element.x + element.points[pointIndex][0] + deltaX, + y: element.y + element.points[pointIndex][1] + deltaY, }, - hoveredElement, - pointIndex === 0 ? "start" : "end", + pointIndex, + app, ); - } } newPointPosition = LinearElementEditor.createPointAt( diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index e50e02978f..3bf3abb76e 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -8683,10 +8683,22 @@ class App extends React.Component { points.length === 2 || (points.length > 1 && isElbowArrow(newElement)) ) { + const globalPoint = LinearElementEditor.getOutlineAvoidingPoint( + newElement, + { x: newElement.x + dx, y: newElement.y + dy }, + 1, + this, + ); mutateElement( newElement, { - points: [...points.slice(0, -1), pointFrom(dx, dy)], + points: [ + ...points.slice(0, -1), + pointFrom( + globalPoint[0] - newElement.x, + globalPoint[1] - newElement.y, + ), + ], }, false, { isDragging: true },