feat(editor): implement overlap box selection (#11053)

Co-authored-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
David Luzar
2026-04-01 18:41:11 +02:00
committed by GitHub
parent 4be4cc0ed0
commit d9e8a33aa4
26 changed files with 1141 additions and 104 deletions
+28 -15
View File
@@ -154,14 +154,11 @@ export const hitElementItself = ({
// Hit test against the extended, rotated bounding box of the element first
const bounds = getElementBounds(element, elementsMap, true);
const hitBounds = isPointWithinBounds(
pointFrom(bounds[0] - threshold, bounds[1] - threshold),
pointRotateRads(
point,
getCenterForBounds(bounds),
-element.angle as Radians,
),
pointFrom(bounds[2] + threshold, bounds[3] + threshold),
const hitBounds = isPointInRotatedBounds(
point,
bounds,
element.angle,
threshold,
);
// PERF: Bail out early if the point is not even in the
@@ -192,18 +189,32 @@ export const hitElementItself = ({
return result;
};
const isPointInRotatedBounds = (
point: GlobalPoint,
bounds: Bounds,
angle: Radians,
tolerance = 0,
) => {
const adjustedPoint =
angle === 0
? point
: pointRotateRads(point, getCenterForBounds(bounds), -angle as Radians);
return isPointWithinBounds(
pointFrom(bounds[0] - tolerance, bounds[1] - tolerance),
adjustedPoint,
pointFrom(bounds[2] + tolerance, bounds[3] + tolerance),
);
};
export const hitElementBoundingBox = (
point: GlobalPoint,
element: ExcalidrawElement,
elementsMap: ElementsMap,
tolerance = 0,
) => {
let [x1, y1, x2, y2] = getElementBounds(element, elementsMap);
x1 -= tolerance;
y1 -= tolerance;
x2 += tolerance;
y2 += tolerance;
return isPointWithinBounds(pointFrom(x1, y1), point, pointFrom(x2, y2));
const bounds = getElementBounds(element, elementsMap, true);
return isPointInRotatedBounds(point, bounds, element.angle, tolerance);
};
export const hitElementBoundingBoxOnly = (
@@ -573,7 +584,9 @@ const intersectLinearOrFreeDrawWithLineSegment = (
continue;
}
const hits = curveIntersectLineSegment(c, segment);
const hits = curveIntersectLineSegment(c, segment, {
iterLimit: 10,
});
if (hits.length > 0) {
intersections.push(...hits);