From 6574fb616ecf035fc97a0cb16eaedb1154ffab74 Mon Sep 17 00:00:00 2001 From: Mark Tolmacs Date: Tue, 19 Aug 2025 09:32:00 +0200 Subject: [PATCH] fix(transform): Fix group resize and rotate --- packages/element/src/resizeElements.ts | 41 +++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/packages/element/src/resizeElements.ts b/packages/element/src/resizeElements.ts index feb52d177a..51e4836328 100644 --- a/packages/element/src/resizeElements.ts +++ b/packages/element/src/resizeElements.ts @@ -20,7 +20,11 @@ import type { PointerDownState } from "@excalidraw/excalidraw/types"; import type { Mutable } from "@excalidraw/common/utility-types"; -import { getArrowLocalFixedPoints, updateBoundElements } from "./binding"; +import { + getArrowLocalFixedPoints, + unbindBindingElement, + updateBoundElements, +} from "./binding"; import { getElementAbsoluteCoords, getCommonBounds, @@ -399,6 +403,11 @@ const rotateMultipleElements = ( centerAngle -= centerAngle % SHIFT_LOCKING_ANGLE; } + const rotatedElementsMap = new Map< + ExcalidrawElement["id"], + NonDeletedExcalidrawElement + >(elements.map((element) => [element.id, element])); + for (const element of elements) { if (!isFrameLikeElement(element)) { const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap); @@ -429,6 +438,19 @@ const rotateMultipleElements = ( simultaneouslyUpdated: elements, }); + if (isBindingElement(element)) { + if (element.startBinding) { + if (!rotatedElementsMap.has(element.startBinding.elementId)) { + unbindBindingElement(element, "start", scene); + } + } + if (element.endBinding) { + if (!rotatedElementsMap.has(element.endBinding.elementId)) { + unbindBindingElement(element, "end", scene); + } + } + } + const boundText = getBoundTextElement(element, elementsMap); if (boundText && !isArrowElement(element)) { scene.mutateElement(boundText, { @@ -1408,6 +1430,10 @@ export const resizeMultipleElements = ( } const elementsToUpdate = elementsAndUpdates.map(({ element }) => element); + const resizedElementsMap = new Map< + ExcalidrawElement["id"], + NonDeletedExcalidrawElement + >(elementsAndUpdates.map(({ element }) => [element.id, element])); for (const { element, @@ -1421,6 +1447,19 @@ export const resizeMultipleElements = ( simultaneouslyUpdated: elementsToUpdate, }); + if (isBindingElement(element)) { + if (element.startBinding) { + if (!resizedElementsMap.has(element.startBinding.elementId)) { + unbindBindingElement(element, "start", scene); + } + } + if (element.endBinding) { + if (!resizedElementsMap.has(element.endBinding.elementId)) { + unbindBindingElement(element, "end", scene); + } + } + } + const boundTextElement = getBoundTextElement(element, elementsMap); if (boundTextElement && boundTextFontSize) { scene.mutateElement(boundTextElement, {