From f44198629c8fdfe8bb4662c38668dbc8579cdac8 Mon Sep 17 00:00:00 2001 From: Mark Tolmacs Date: Thu, 13 Nov 2025 19:10:24 +0100 Subject: [PATCH] fix: Arrow angle reset --- packages/excalidraw/data/restore.ts | 43 +++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/packages/excalidraw/data/restore.ts b/packages/excalidraw/data/restore.ts index d06335bc99..de6027c58e 100644 --- a/packages/excalidraw/data/restore.ts +++ b/packages/excalidraw/data/restore.ts @@ -1,4 +1,4 @@ -import { isFiniteNumber, pointFrom } from "@excalidraw/math"; +import { isFiniteNumber, pointFrom, pointRotateRads } from "@excalidraw/math"; import { DEFAULT_FONT_FAMILY, @@ -20,6 +20,7 @@ import { } from "@excalidraw/common"; import { calculateFixedPointForNonElbowArrowBinding, + elementCenterPoint, getNonDeletedElements, isPointInElement, isValidPolygon, @@ -392,17 +393,33 @@ export const restoreElement = ( ...getSizeFromPoints(points), }); case "arrow": { - const { startArrowhead = null, endArrowhead = "arrow" } = element; - let x: number | undefined = element.x; - let y: number | undefined = element.y; + const { + startArrowhead = null, + endArrowhead = "arrow", + angle = 0, + } = element; + const x: number | undefined = element.x; + const y: number | undefined = element.y; let points: readonly LocalPoint[] | undefined = // migrate old arrow model to new one !Array.isArray(element.points) || element.points.length < 2 ? [pointFrom(0, 0), pointFrom(element.width, element.height)] : element.points; - if (points[0][0] !== 0 || points[0][1] !== 0) { - ({ points, x, y } = - LinearElementEditor.getNormalizeElementPointsAndCoords(element)); + if (angle !== 0) { + points = LinearElementEditor.getPointsGlobalCoordinates( + element, + elementsMap, + ).map((point) => + LinearElementEditor.pointFromAbsoluteCoords( + element as ExcalidrawArrowElement, + pointRotateRads( + point, + elementCenterPoint(element, elementsMap), + angle, + ), + elementsMap, + ), + ); } const base = { @@ -426,10 +443,11 @@ export const restoreElement = ( y, elbowed: (element as ExcalidrawArrowElement).elbowed, ...getSizeFromPoints(points), - } as const; + angle: 0 as Radians, + }; // TODO: Separate arrow from linear element - return isElbowArrow(element) + const restoredElement = isElbowArrow(element) ? restoreElementWithProperties(element as ExcalidrawElbowArrowElement, { ...base, elbowed: true, @@ -441,6 +459,13 @@ export const restoreElement = ( endIsSpecial: element.endIsSpecial, }) : restoreElementWithProperties(element as ExcalidrawArrowElement, base); + + return { + ...restoredElement, + ...LinearElementEditor.getNormalizeElementPointsAndCoords( + restoredElement, + ), + }; } // generic elements