fix: collision regressions from vector geometry rewrite (#7902)

pull/7908/head
Ryan Di 10 months ago committed by GitHub
parent f92f04c13c
commit bbcca06b94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -230,6 +230,7 @@ import {
getEllipseShape, getEllipseShape,
getFreedrawShape, getFreedrawShape,
getPolygonShape, getPolygonShape,
getSelectionBoxShape,
} from "../../utils/geometry/shape"; } from "../../utils/geometry/shape";
import { isPointInShape } from "../../utils/collision"; import { isPointInShape } from "../../utils/collision";
import { import {
@ -416,7 +417,6 @@ import { withBatchedUpdates, withBatchedUpdatesThrottled } from "../reactUtils";
import { getRenderOpacity } from "../renderer/renderElement"; import { getRenderOpacity } from "../renderer/renderElement";
import { import {
hitElementBoundText, hitElementBoundText,
hitElementBoundingBox,
hitElementBoundingBoxOnly, hitElementBoundingBoxOnly,
hitElementItself, hitElementItself,
shouldTestInside, shouldTestInside,
@ -4462,10 +4462,18 @@ class App extends React.Component<AppProps, AppState> {
// If we're hitting element with highest z-index only on its bounding box // If we're hitting element with highest z-index only on its bounding box
// while also hitting other element figure, the latter should be considered. // while also hitting other element figure, the latter should be considered.
return isPointInShape( return hitElementItself({
[x, y], x,
this.getElementShape(elementWithHighestZIndex), y,
) element: elementWithHighestZIndex,
shape: this.getElementShape(elementWithHighestZIndex),
// when overlapping, we would like to be more precise
// this also avoids the need to update past tests
threshold: this.getHitThreshold() / 2,
frameNameBound: isFrameLikeElement(elementWithHighestZIndex)
? this.frameNameBoundsCache.get(elementWithHighestZIndex)
: null,
})
? elementWithHighestZIndex ? elementWithHighestZIndex
: allHitElements[allHitElements.length - 2]; : allHitElements[allHitElements.length - 2];
} }
@ -4540,13 +4548,13 @@ class App extends React.Component<AppProps, AppState> {
this.state.selectedElementIds[element.id] && this.state.selectedElementIds[element.id] &&
shouldShowBoundingBox([element], this.state) shouldShowBoundingBox([element], this.state)
) { ) {
return hitElementBoundingBox( const selectionShape = getSelectionBoxShape(
x,
y,
element, element,
this.scene.getNonDeletedElementsMap(), this.scene.getNonDeletedElementsMap(),
this.getHitThreshold(), this.getHitThreshold(),
); );
return isPointInShape([x, y], selectionShape);
} }
// take bound text element into consideration for hit collision as well // take bound text element into consideration for hit collision as well

@ -12,8 +12,11 @@
* to pure shapes * to pure shapes
*/ */
import { getElementAbsoluteCoords } from "../../excalidraw/element";
import { import {
ElementsMap,
ExcalidrawDiamondElement, ExcalidrawDiamondElement,
ExcalidrawElement,
ExcalidrawEllipseElement, ExcalidrawEllipseElement,
ExcalidrawEmbeddableElement, ExcalidrawEmbeddableElement,
ExcalidrawFrameLikeElement, ExcalidrawFrameLikeElement,
@ -133,6 +136,36 @@ export const getPolygonShape = (
}; };
}; };
// return the selection box for an element, possibly rotated as well
export const getSelectionBoxShape = (
element: ExcalidrawElement,
elementsMap: ElementsMap,
padding = 10,
) => {
let [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(
element,
elementsMap,
true,
);
x1 -= padding;
x2 += padding;
y1 -= padding;
y2 += padding;
const angleInDegrees = angleToDegrees(element.angle);
const center: Point = [cx, cy];
const topLeft = pointRotate([x1, y1], angleInDegrees, center);
const topRight = pointRotate([x2, y1], angleInDegrees, center);
const bottomLeft = pointRotate([x1, y2], angleInDegrees, center);
const bottomRight = pointRotate([x2, y2], angleInDegrees, center);
return {
type: "polygon",
data: [topLeft, topRight, bottomRight, bottomLeft],
} as GeometricShape;
};
// ellipse // ellipse
export const getEllipseShape = ( export const getEllipseShape = (
element: ExcalidrawEllipseElement, element: ExcalidrawEllipseElement,

Loading…
Cancel
Save