From bffc33dd3ffe56c72029eee6aca843d992bac7ab Mon Sep 17 00:00:00 2001 From: Alex Kim <45559664+alex-kim-dev@users.noreply.github.com> Date: Fri, 17 Feb 2023 16:01:45 +0300 Subject: [PATCH] fix: linear elements drifting away after multiple flips --- src/actions/actionFlip.ts | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/actions/actionFlip.ts b/src/actions/actionFlip.ts index 7a82fa85e..41376ea5b 100644 --- a/src/actions/actionFlip.ts +++ b/src/actions/actionFlip.ts @@ -7,7 +7,13 @@ import { AppState, PointerDownState } from "../types"; import { updateBoundElements } from "../element/binding"; import { arrayToMap } from "../utils"; import { KEYS } from "../keys"; -import { getCommonBoundingBox } from "../element/bounds"; +import { + getCommonBoundingBox, + getElementPointsCoords, +} from "../element/bounds"; +import { isLinearElement } from "../element/typeChecks"; +import { type ExcalidrawLinearElement } from "../element/types"; +import { mutateElement } from "../element/mutateElement"; const enableActionFlipHorizontal = ( elements: readonly ExcalidrawElement[], @@ -86,6 +92,15 @@ const flipElements = ( ): ExcalidrawElement[] => { const { minX, minY, maxX, maxY } = getCommonBoundingBox(elements); + const linearElements = elements + .filter((element): element is ExcalidrawLinearElement => + isLinearElement(element), + ) + .map((element) => { + const origCoords = getElementPointsCoords(element, element.points); + return [element, origCoords] as const; + }); + resizeMultipleElements( { originalElements: arrayToMap(elements) } as PointerDownState, elements, @@ -95,6 +110,19 @@ const flipElements = ( flipDirection === "horizontal" ? minY : maxY, ); + linearElements.forEach(([element, origCoords]) => { + const latestCoords = getElementPointsCoords(element, element.points); + const coordsDiffX = + origCoords[0] - latestCoords[0] + origCoords[2] - latestCoords[2]; + const coordsDiffY = + origCoords[1] - latestCoords[1] + origCoords[3] - latestCoords[3]; + + mutateElement(element, { + x: element.x + coordsDiffX * 0.5, + y: element.y + coordsDiffY * 0.5, + }); + }); + elements.forEach((element) => updateBoundElements(element)); return elements;