mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-09-25 02:10:38 +02:00
fix: Arrow eraser precision & lasso arrow selection
This commit is contained in:
@@ -42,6 +42,7 @@ import {
|
|||||||
isBoundToContainer,
|
isBoundToContainer,
|
||||||
isFreeDrawElement,
|
isFreeDrawElement,
|
||||||
isLinearElement,
|
isLinearElement,
|
||||||
|
isLineElement,
|
||||||
isTextElement,
|
isTextElement,
|
||||||
} from "./typeChecks";
|
} from "./typeChecks";
|
||||||
|
|
||||||
@@ -324,9 +325,28 @@ export const getElementLineSegments = (
|
|||||||
const points = curves
|
const points = curves
|
||||||
.map((curve) => pointsOnBezierCurves(curve, 10))
|
.map((curve) => pointsOnBezierCurves(curve, 10))
|
||||||
.flat();
|
.flat();
|
||||||
let i = 0;
|
|
||||||
const segments: LineSegment<GlobalPoint>[] = [];
|
const segments: LineSegment<GlobalPoint>[] = [];
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
while (i < points.length - 1) {
|
while (i < points.length - 1) {
|
||||||
|
const p1 = pointFrom(points[i + 1][0], points[i][1]);
|
||||||
|
const p2 = pointFrom(points[i][0], points[i + 1][1]);
|
||||||
|
const alignsWithStart = pointDistance(p1, points[0] as GlobalPoint) < 1;
|
||||||
|
const alignsWithEnd =
|
||||||
|
pointDistance(p2, points[points.length - 1] as GlobalPoint) < 1;
|
||||||
|
|
||||||
|
// Avoid closing the polycurve for non-polygon lines and arrows
|
||||||
|
if (
|
||||||
|
((isLineElement(element) && !element.polygon) ||
|
||||||
|
isArrowElement(element)) &&
|
||||||
|
alignsWithStart &&
|
||||||
|
alignsWithEnd
|
||||||
|
) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
segments.push(
|
segments.push(
|
||||||
lineSegment(
|
lineSegment(
|
||||||
pointFrom(points[i][0], points[i][1]),
|
pointFrom(points[i][0], points[i][1]),
|
||||||
|
@@ -2,10 +2,10 @@ import { arrayToMap, easeOut, THEME } from "@excalidraw/common";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
computeBoundTextPosition,
|
computeBoundTextPosition,
|
||||||
distanceToElement,
|
|
||||||
doBoundsIntersect,
|
doBoundsIntersect,
|
||||||
getBoundTextElement,
|
getBoundTextElement,
|
||||||
getElementBounds,
|
getElementBounds,
|
||||||
|
getElementLineSegments,
|
||||||
getFreedrawOutlineAsSegments,
|
getFreedrawOutlineAsSegments,
|
||||||
getFreedrawOutlinePoints,
|
getFreedrawOutlinePoints,
|
||||||
intersectElementWithLineSegment,
|
intersectElementWithLineSegment,
|
||||||
@@ -265,19 +265,28 @@ const eraserTest = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (
|
}
|
||||||
isArrowElement(element) ||
|
|
||||||
(isLineElement(element) && !element.polygon)
|
const boundTextElement = getBoundTextElement(element, elementsMap);
|
||||||
) {
|
|
||||||
|
if (isArrowElement(element) || (isLineElement(element) && !element.polygon)) {
|
||||||
const tolerance = Math.max(
|
const tolerance = Math.max(
|
||||||
element.strokeWidth,
|
element.strokeWidth,
|
||||||
(element.strokeWidth * 2) / zoom,
|
(element.strokeWidth * 2) / zoom,
|
||||||
);
|
);
|
||||||
|
|
||||||
return distanceToElement(element, elementsMap, lastPoint) <= tolerance;
|
// If the eraser movement is so fast that a large distance is covered
|
||||||
|
// between the last two points, the distanceToElement miss, so we test
|
||||||
|
// agaist each segment of the linear element
|
||||||
|
const segments = getElementLineSegments(element, elementsMap);
|
||||||
|
for (const seg of segments) {
|
||||||
|
if (lineSegmentsDistance(seg, pathSegment) <= tolerance) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const boundTextElement = getBoundTextElement(element, elementsMap);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
intersectElementWithLineSegment(element, elementsMap, pathSegment, 0, true)
|
intersectElementWithLineSegment(element, elementsMap, pathSegment, 0, true)
|
||||||
|
Reference in New Issue
Block a user