Skip to content

Commit

Permalink
fix: element relative position when dragging multiple elements on grid (
Browse files Browse the repository at this point in the history
excalidraw#7107)

Co-authored-by: dwelle <[email protected]>
  • Loading branch information
zsviczian and dwelle authored Oct 25, 2023
1 parent f794b0b commit f098789
Showing 1 changed file with 39 additions and 26 deletions.
65 changes: 39 additions & 26 deletions src/element/dragElements.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { updateBoundElements } from "./binding";
import { getCommonBounds } from "./bounds";
import { Bounds, getCommonBounds } from "./bounds";
import { mutateElement } from "./mutateElement";
import { getPerfectElementSize } from "./sizeHelpers";
import { NonDeletedExcalidrawElement } from "./types";
Expand Down Expand Up @@ -41,14 +41,20 @@ export const dragSelectedElements = (
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) => {
updateElementCoords(
pointerDownState,
element,
offset,
snapOffset,
gridSize,
);
updateElementCoords(pointerDownState, element, adjustedOffset);
// update coords of bound text only if we're dragging the container directly
// (we don't drag the group that it's part of)
if (
Expand All @@ -66,13 +72,7 @@ export const dragSelectedElements = (
// updating its coords again
(!textElement.frameId || !frames.includes(textElement.frameId))
) {
updateElementCoords(
pointerDownState,
textElement,
offset,
snapOffset,
gridSize,
);
updateElementCoords(pointerDownState, textElement, adjustedOffset);
}
}
updateBoundElements(element, {
Expand All @@ -81,23 +81,20 @@ export const dragSelectedElements = (
});
};

const updateElementCoords = (
pointerDownState: PointerDownState,
element: NonDeletedExcalidrawElement,
const calculateOffset = (
commonBounds: Bounds,
dragOffset: { x: number; y: number },
snapOffset: { x: number; y: number },
gridSize: AppState["gridSize"],
) => {
const originalElement =
pointerDownState.originalElements.get(element.id) ?? element;

let nextX = originalElement.x + dragOffset.x + snapOffset.x;
let nextY = originalElement.y + dragOffset.y + snapOffset.y;
): { x: number; y: number } => {
const [x, y] = commonBounds;
let nextX = x + dragOffset.x + snapOffset.x;
let nextY = y + dragOffset.y + snapOffset.y;

if (snapOffset.x === 0 || snapOffset.y === 0) {
const [nextGridX, nextGridY] = getGridPoint(
originalElement.x + dragOffset.x,
originalElement.y + dragOffset.y,
x + dragOffset.x,
y + dragOffset.y,
gridSize,
);

Expand All @@ -109,6 +106,22 @@ const updateElementCoords = (
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, {
x: nextX,
Expand Down

0 comments on commit f098789

Please sign in to comment.