fix: element relative position when dragging multiple elements on grid (#7107)

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
zsviczian 2023-10-25 22:48:03 +02:00 committed by GitHub
parent f794b0bb90
commit f098789d16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,5 +1,5 @@
import { updateBoundElements } from "./binding"; import { updateBoundElements } from "./binding";
import { getCommonBounds } from "./bounds"; import { Bounds, getCommonBounds } from "./bounds";
import { mutateElement } from "./mutateElement"; import { mutateElement } from "./mutateElement";
import { getPerfectElementSize } from "./sizeHelpers"; import { getPerfectElementSize } from "./sizeHelpers";
import { NonDeletedExcalidrawElement } from "./types"; import { NonDeletedExcalidrawElement } from "./types";
@ -41,14 +41,20 @@ export const dragSelectedElements = (
elementsInFrames.forEach((element) => elementsToUpdate.add(element)); elementsInFrames.forEach((element) => elementsToUpdate.add(element));
} }
const commonBounds = getCommonBounds(
Array.from(elementsToUpdate).map(
(el) => pointerDownState.originalElements.get(el.id) ?? el,
),
);
const adjustedOffset = calculateOffset(
commonBounds,
offset,
snapOffset,
gridSize,
);
elementsToUpdate.forEach((element) => { elementsToUpdate.forEach((element) => {
updateElementCoords( updateElementCoords(pointerDownState, element, adjustedOffset);
pointerDownState,
element,
offset,
snapOffset,
gridSize,
);
// update coords of bound text only if we're dragging the container directly // update coords of bound text only if we're dragging the container directly
// (we don't drag the group that it's part of) // (we don't drag the group that it's part of)
if ( if (
@ -66,13 +72,7 @@ export const dragSelectedElements = (
// updating its coords again // updating its coords again
(!textElement.frameId || !frames.includes(textElement.frameId)) (!textElement.frameId || !frames.includes(textElement.frameId))
) { ) {
updateElementCoords( updateElementCoords(pointerDownState, textElement, adjustedOffset);
pointerDownState,
textElement,
offset,
snapOffset,
gridSize,
);
} }
} }
updateBoundElements(element, { updateBoundElements(element, {
@ -81,23 +81,20 @@ export const dragSelectedElements = (
}); });
}; };
const updateElementCoords = ( const calculateOffset = (
pointerDownState: PointerDownState, commonBounds: Bounds,
element: NonDeletedExcalidrawElement,
dragOffset: { x: number; y: number }, dragOffset: { x: number; y: number },
snapOffset: { x: number; y: number }, snapOffset: { x: number; y: number },
gridSize: AppState["gridSize"], gridSize: AppState["gridSize"],
) => { ): { x: number; y: number } => {
const originalElement = const [x, y] = commonBounds;
pointerDownState.originalElements.get(element.id) ?? element; let nextX = x + dragOffset.x + snapOffset.x;
let nextY = y + dragOffset.y + snapOffset.y;
let nextX = originalElement.x + dragOffset.x + snapOffset.x;
let nextY = originalElement.y + dragOffset.y + snapOffset.y;
if (snapOffset.x === 0 || snapOffset.y === 0) { if (snapOffset.x === 0 || snapOffset.y === 0) {
const [nextGridX, nextGridY] = getGridPoint( const [nextGridX, nextGridY] = getGridPoint(
originalElement.x + dragOffset.x, x + dragOffset.x,
originalElement.y + dragOffset.y, y + dragOffset.y,
gridSize, gridSize,
); );
@ -109,6 +106,22 @@ const updateElementCoords = (
nextY = nextGridY; nextY = nextGridY;
} }
} }
return {
x: nextX - x,
y: nextY - y,
};
};
const updateElementCoords = (
pointerDownState: PointerDownState,
element: NonDeletedExcalidrawElement,
dragOffset: { x: number; y: number },
) => {
const originalElement =
pointerDownState.originalElements.get(element.id) ?? element;
const nextX = originalElement.x + dragOffset.x;
const nextY = originalElement.y + dragOffset.y;
mutateElement(element, { mutateElement(element, {
x: nextX, x: nextX,