mirror of
				https://github.com/excalidraw/excalidraw.git
				synced 2025-10-31 02:44:50 +01:00 
			
		
		
		
	fix: Arrow eraser precision arrow selection (#10006)
This commit is contained in:
		| @@ -42,6 +42,7 @@ import { | |||||||
|   isBoundToContainer, |   isBoundToContainer, | ||||||
|   isFreeDrawElement, |   isFreeDrawElement, | ||||||
|   isLinearElement, |   isLinearElement, | ||||||
|  |   isLineElement, | ||||||
|   isTextElement, |   isTextElement, | ||||||
| } from "./typeChecks"; | } from "./typeChecks"; | ||||||
|  |  | ||||||
| @@ -321,11 +322,19 @@ export const getElementLineSegments = ( | |||||||
|  |  | ||||||
|   if (shape.type === "polycurve") { |   if (shape.type === "polycurve") { | ||||||
|     const curves = shape.data; |     const curves = shape.data; | ||||||
|     const points = curves |     const pointsOnCurves = curves.map((curve) => | ||||||
|       .map((curve) => pointsOnBezierCurves(curve, 10)) |       pointsOnBezierCurves(curve, 10), | ||||||
|       .flat(); |     ); | ||||||
|     let i = 0; |  | ||||||
|     const segments: LineSegment<GlobalPoint>[] = []; |     const segments: LineSegment<GlobalPoint>[] = []; | ||||||
|  |  | ||||||
|  |     if ( | ||||||
|  |       (isLineElement(element) && !element.polygon) || | ||||||
|  |       isArrowElement(element) | ||||||
|  |     ) { | ||||||
|  |       for (const points of pointsOnCurves) { | ||||||
|  |         let i = 0; | ||||||
|  |  | ||||||
|         while (i < points.length - 1) { |         while (i < points.length - 1) { | ||||||
|           segments.push( |           segments.push( | ||||||
|             lineSegment( |             lineSegment( | ||||||
| @@ -335,6 +344,21 @@ export const getElementLineSegments = ( | |||||||
|           ); |           ); | ||||||
|           i++; |           i++; | ||||||
|         } |         } | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       const points = pointsOnCurves.flat(); | ||||||
|  |       let i = 0; | ||||||
|  |  | ||||||
|  |       while (i < points.length - 1) { | ||||||
|  |         segments.push( | ||||||
|  |           lineSegment( | ||||||
|  |             pointFrom(points[i][0], points[i][1]), | ||||||
|  |             pointFrom(points[i + 1][0], points[i + 1][1]), | ||||||
|  |           ), | ||||||
|  |         ); | ||||||
|  |         i++; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     return segments; |     return segments; | ||||||
|   } else if (shape.type === "polyline") { |   } else if (shape.type === "polyline") { | ||||||
|   | |||||||
| @@ -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
	 Márk Tolmács
					Márk Tolmács