parent
d21c6a1bc6
commit
c5d3bb0b6a
@ -17,7 +17,11 @@ import type {
|
|||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
import type { Bounds } from "./bounds";
|
import type { Bounds } from "./bounds";
|
||||||
import { getCenterForBounds } from "./bounds";
|
import {
|
||||||
|
getCenterForBounds,
|
||||||
|
getElementBounds,
|
||||||
|
doBoundsIntersect,
|
||||||
|
} from "./bounds";
|
||||||
import type { AppState } from "../types";
|
import type { AppState } from "../types";
|
||||||
import { isPointOnShape } from "@excalidraw/utils/collision";
|
import { isPointOnShape } from "@excalidraw/utils/collision";
|
||||||
import {
|
import {
|
||||||
@ -743,6 +747,21 @@ export const updateBoundElements = (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for intersections before updating bound elements incase connected elements overlap
|
||||||
|
const startBindingElement = element.startBinding
|
||||||
|
? elementsMap.get(element.startBinding.elementId)
|
||||||
|
: null;
|
||||||
|
const endBindingElement = element.endBinding
|
||||||
|
? elementsMap.get(element.endBinding.elementId)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
let startBounds: Bounds | null = null;
|
||||||
|
let endBounds: Bounds | null = null;
|
||||||
|
if (startBindingElement && endBindingElement) {
|
||||||
|
startBounds = getElementBounds(startBindingElement, elementsMap);
|
||||||
|
endBounds = getElementBounds(endBindingElement, elementsMap);
|
||||||
|
}
|
||||||
|
|
||||||
const bindings = {
|
const bindings = {
|
||||||
startBinding: maybeCalculateNewGapWhenScaling(
|
startBinding: maybeCalculateNewGapWhenScaling(
|
||||||
changedElement,
|
changedElement,
|
||||||
@ -770,7 +789,12 @@ export const updateBoundElements = (
|
|||||||
bindableElement &&
|
bindableElement &&
|
||||||
isBindableElement(bindableElement) &&
|
isBindableElement(bindableElement) &&
|
||||||
(bindingProp === "startBinding" || bindingProp === "endBinding") &&
|
(bindingProp === "startBinding" || bindingProp === "endBinding") &&
|
||||||
changedElement.id === element[bindingProp]?.elementId
|
(changedElement.id === element[bindingProp]?.elementId ||
|
||||||
|
(changedElement.id ===
|
||||||
|
element[
|
||||||
|
bindingProp === "startBinding" ? "endBinding" : "startBinding"
|
||||||
|
]?.elementId &&
|
||||||
|
!doBoundsIntersect(startBounds, endBounds)))
|
||||||
) {
|
) {
|
||||||
const point = updateBoundPoint(
|
const point = updateBoundPoint(
|
||||||
element,
|
element,
|
||||||
|
@ -1013,3 +1013,17 @@ export const getCenterForBounds = (bounds: Bounds): GlobalPoint =>
|
|||||||
bounds[0] + (bounds[2] - bounds[0]) / 2,
|
bounds[0] + (bounds[2] - bounds[0]) / 2,
|
||||||
bounds[1] + (bounds[3] - bounds[1]) / 2,
|
bounds[1] + (bounds[3] - bounds[1]) / 2,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const doBoundsIntersect = (
|
||||||
|
bounds1: Bounds | null,
|
||||||
|
bounds2: Bounds | null,
|
||||||
|
): boolean => {
|
||||||
|
if (bounds1 == null || bounds2 == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [minX1, minY1, maxX1, maxY1] = bounds1;
|
||||||
|
const [minX2, minY2, maxX2, maxY2] = bounds2;
|
||||||
|
|
||||||
|
return minX1 < maxX2 && maxX1 > minX2 && minY1 < maxY2 && maxY1 > minY2;
|
||||||
|
};
|
||||||
|
@ -219,7 +219,9 @@ export class LinearElementEditor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @returns whether point was dragged */
|
/**
|
||||||
|
* @returns whether point was dragged
|
||||||
|
*/
|
||||||
static handlePointDragging(
|
static handlePointDragging(
|
||||||
event: PointerEvent,
|
event: PointerEvent,
|
||||||
app: AppClassProperties,
|
app: AppClassProperties,
|
||||||
|
@ -297,7 +297,7 @@ History {
|
|||||||
"focus": "0.00990",
|
"focus": "0.00990",
|
||||||
"gap": 1,
|
"gap": 1,
|
||||||
},
|
},
|
||||||
"height": "0.98597",
|
"height": "0.98586",
|
||||||
"points": [
|
"points": [
|
||||||
[
|
[
|
||||||
0,
|
0,
|
||||||
@ -305,7 +305,7 @@ History {
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
"98.58579",
|
"98.58579",
|
||||||
"-0.98597",
|
"-0.98586",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
"startBinding": {
|
"startBinding": {
|
||||||
@ -320,7 +320,7 @@ History {
|
|||||||
"focus": "-0.02000",
|
"focus": "-0.02000",
|
||||||
"gap": 1,
|
"gap": 1,
|
||||||
},
|
},
|
||||||
"height": "0.00119",
|
"height": "0.00000",
|
||||||
"points": [
|
"points": [
|
||||||
[
|
[
|
||||||
0,
|
0,
|
||||||
@ -328,7 +328,7 @@ History {
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
"98.58579",
|
"98.58579",
|
||||||
"0.00119",
|
"0.00000",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
"startBinding": {
|
"startBinding": {
|
||||||
@ -409,7 +409,7 @@ History {
|
|||||||
"focus": "0.00990",
|
"focus": "0.00990",
|
||||||
"gap": 1,
|
"gap": 1,
|
||||||
},
|
},
|
||||||
"height": "0.98700",
|
"height": "0.98586",
|
||||||
"points": [
|
"points": [
|
||||||
[
|
[
|
||||||
0,
|
0,
|
||||||
@ -417,7 +417,7 @@ History {
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
"98.58579",
|
"98.58579",
|
||||||
"-0.98700",
|
"-0.98586",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
"startBinding": {
|
"startBinding": {
|
||||||
@ -425,7 +425,7 @@ History {
|
|||||||
"focus": "0.02970",
|
"focus": "0.02970",
|
||||||
"gap": 1,
|
"gap": 1,
|
||||||
},
|
},
|
||||||
"y": "0.99465",
|
"y": "0.99364",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"id175" => Delta {
|
"id175" => Delta {
|
||||||
@ -1238,7 +1238,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
"fillStyle": "solid",
|
"fillStyle": "solid",
|
||||||
"frameId": null,
|
"frameId": null,
|
||||||
"groupIds": [],
|
"groupIds": [],
|
||||||
"height": "2.52823",
|
"height": "1.30038",
|
||||||
"id": "id178",
|
"id": "id178",
|
||||||
"index": "Zz",
|
"index": "Zz",
|
||||||
"isDeleted": false,
|
"isDeleted": false,
|
||||||
@ -1253,7 +1253,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
"98.58579",
|
"98.58579",
|
||||||
"-2.52823",
|
"1.30038",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
"roughness": 1,
|
"roughness": 1,
|
||||||
@ -1278,7 +1278,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
"version": 11,
|
"version": 11,
|
||||||
"width": "98.58579",
|
"width": "98.58579",
|
||||||
"x": "0.70711",
|
"x": "0.70711",
|
||||||
"y": "3.82861",
|
"y": 0,
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -1609,7 +1609,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
"fillStyle": "solid",
|
"fillStyle": "solid",
|
||||||
"frameId": null,
|
"frameId": null,
|
||||||
"groupIds": [],
|
"groupIds": [],
|
||||||
"height": "2.52823",
|
"height": "1.30038",
|
||||||
"id": "id181",
|
"id": "id181",
|
||||||
"index": "a0",
|
"index": "a0",
|
||||||
"isDeleted": false,
|
"isDeleted": false,
|
||||||
@ -1624,7 +1624,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
"98.58579",
|
"98.58579",
|
||||||
"-2.52823",
|
"1.30038",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
"roughness": 1,
|
"roughness": 1,
|
||||||
@ -1649,7 +1649,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
"version": 11,
|
"version": 11,
|
||||||
"width": "98.58579",
|
"width": "98.58579",
|
||||||
"x": "0.70711",
|
"x": "0.70711",
|
||||||
"y": "3.82861",
|
"y": 0,
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -1767,7 +1767,7 @@ History {
|
|||||||
"fillStyle": "solid",
|
"fillStyle": "solid",
|
||||||
"frameId": null,
|
"frameId": null,
|
||||||
"groupIds": [],
|
"groupIds": [],
|
||||||
"height": "22.07000",
|
"height": "11.27227",
|
||||||
"index": "a0",
|
"index": "a0",
|
||||||
"isDeleted": false,
|
"isDeleted": false,
|
||||||
"lastCommittedPoint": null,
|
"lastCommittedPoint": null,
|
||||||
@ -1780,8 +1780,8 @@ History {
|
|||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"99.27949",
|
"98.58579",
|
||||||
"-22.07000",
|
"11.27227",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
"roughness": 1,
|
"roughness": 1,
|
||||||
@ -1802,9 +1802,9 @@ History {
|
|||||||
"strokeStyle": "solid",
|
"strokeStyle": "solid",
|
||||||
"strokeWidth": 2,
|
"strokeWidth": 2,
|
||||||
"type": "arrow",
|
"type": "arrow",
|
||||||
"width": "99.27949",
|
"width": "98.58579",
|
||||||
"x": "0.01341",
|
"x": "0.70711",
|
||||||
"y": "33.34227",
|
"y": 0,
|
||||||
},
|
},
|
||||||
"inserted": {
|
"inserted": {
|
||||||
"isDeleted": true,
|
"isDeleted": true,
|
||||||
@ -2320,7 +2320,7 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
"fillStyle": "solid",
|
"fillStyle": "solid",
|
||||||
"frameId": null,
|
"frameId": null,
|
||||||
"groupIds": [],
|
"groupIds": [],
|
||||||
"height": "410.63965",
|
"height": "374.05754",
|
||||||
"id": "id186",
|
"id": "id186",
|
||||||
"index": "a2",
|
"index": "a2",
|
||||||
"isDeleted": false,
|
"isDeleted": false,
|
||||||
@ -2334,8 +2334,8 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"501.24760",
|
"502.78936",
|
||||||
"-410.63965",
|
"-374.05754",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
"roughness": 1,
|
"roughness": 1,
|
||||||
@ -2354,9 +2354,9 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
|||||||
"type": "arrow",
|
"type": "arrow",
|
||||||
"updated": 1,
|
"updated": 1,
|
||||||
"version": 10,
|
"version": 10,
|
||||||
"width": "501.24760",
|
"width": "502.78936",
|
||||||
"x": "0.70711",
|
"x": "-0.83465",
|
||||||
"y": 0,
|
"y": "-36.58211",
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
|||||||
"fillStyle": "solid",
|
"fillStyle": "solid",
|
||||||
"frameId": null,
|
"frameId": null,
|
||||||
"groupIds": [],
|
"groupIds": [],
|
||||||
"height": "84.41974",
|
"height": "87.29887",
|
||||||
"id": "id2",
|
"id": "id2",
|
||||||
"index": "a2",
|
"index": "a2",
|
||||||
"isDeleted": false,
|
"isDeleted": false,
|
||||||
@ -210,8 +210,8 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
|||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"83.92893",
|
"86.85786",
|
||||||
"84.41974",
|
"87.29887",
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
"roughness": 1,
|
"roughness": 1,
|
||||||
@ -232,8 +232,8 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
|||||||
"updated": 1,
|
"updated": 1,
|
||||||
"version": 11,
|
"version": 11,
|
||||||
"versionNonce": 1051383431,
|
"versionNonce": 1051383431,
|
||||||
"width": "83.92893",
|
"width": "86.85786",
|
||||||
"x": 110,
|
"x": "107.07107",
|
||||||
"y": 50,
|
"y": "47.07107",
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import "../../utils/test-utils";
|
||||||
import { render, fireEvent, act, unmountComponent } from "./test-utils";
|
import { render, fireEvent, act, unmountComponent } from "./test-utils";
|
||||||
import { Excalidraw } from "../index";
|
import { Excalidraw } from "../index";
|
||||||
import * as StaticScene from "../renderer/staticScene";
|
import * as StaticScene from "../renderer/staticScene";
|
||||||
@ -121,10 +122,8 @@ describe("move element", () => {
|
|||||||
expect(h.state.selectedElementIds[rectB.id]).toBeTruthy();
|
expect(h.state.selectedElementIds[rectB.id]).toBeTruthy();
|
||||||
expect([rectA.x, rectA.y]).toEqual([0, 0]);
|
expect([rectA.x, rectA.y]).toEqual([0, 0]);
|
||||||
expect([rectB.x, rectB.y]).toEqual([201, 2]);
|
expect([rectB.x, rectB.y]).toEqual([201, 2]);
|
||||||
expect([Math.round(arrow.x), Math.round(arrow.y)]).toEqual([110, 50]);
|
expect([[arrow.x, arrow.y]]).toCloselyEqualPoints([[107.07, 47.07]]);
|
||||||
expect([Math.round(arrow.width), Math.round(arrow.height)]).toEqual([
|
expect([[arrow.width, arrow.height]]).toCloselyEqualPoints([[86.86, 87.3]]);
|
||||||
84, 84,
|
|
||||||
]);
|
|
||||||
|
|
||||||
h.elements.forEach((element) => expect(element).toMatchSnapshot());
|
h.elements.forEach((element) => expect(element).toMatchSnapshot());
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user