refactor: remove points function from snapping and move to linear editor

This commit is contained in:
Ryan Di
2025-08-04 18:04:59 +10:00
parent 7332e76d56
commit 60a459b135
2 changed files with 57 additions and 64 deletions

View File

@@ -1319,18 +1319,53 @@ export class LinearElementEditor {
static getPointsGlobalCoordinates( static getPointsGlobalCoordinates(
element: NonDeleted<ExcalidrawLinearElement>, element: NonDeleted<ExcalidrawLinearElement>,
elementsMap: ElementsMap, elementsMap: ElementsMap,
options: {
dragOffset?: { x: number; y: number };
excludePointsIndices?: readonly number[];
} = {},
): GlobalPoint[] { ): GlobalPoint[] {
const { dragOffset, excludePointsIndices } = options;
if (!element.points || element.points.length === 0) {
return [];
}
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap); const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
const cx = (x1 + x2) / 2; const cx = (x1 + x2) / 2;
const cy = (y1 + y2) / 2; const cy = (y1 + y2) / 2;
return element.points.map((p) => {
const { x, y } = element; let elementX = element.x;
return pointRotateRads( let elementY = element.y;
pointFrom(x + p[0], y + p[1]),
if (dragOffset) {
elementX += dragOffset.x;
elementY += dragOffset.y;
}
const globalPoints: GlobalPoint[] = [];
for (let i = 0; i < element.points.length; i++) {
// Skip the point being edited if specified
if (
excludePointsIndices?.length &&
excludePointsIndices.find((index) => index === i) !== undefined
) {
continue;
}
const p = element.points[i];
const globalX = elementX + p[0];
const globalY = elementY + p[1];
const rotated = pointRotateRads<GlobalPoint>(
pointFrom(globalX, globalY),
pointFrom(cx, cy), pointFrom(cx, cy),
element.angle, element.angle,
); );
}); globalPoints.push(rotated);
}
return globalPoints;
} }
static getPointAtIndexGlobalCoordinates( static getPointAtIndexGlobalCoordinates(

View File

@@ -35,6 +35,7 @@ import type {
ExcalidrawElement, ExcalidrawElement,
ExcalidrawLinearElement, ExcalidrawLinearElement,
NonDeletedExcalidrawElement, NonDeletedExcalidrawElement,
NonDeleted,
} from "@excalidraw/element/types"; } from "@excalidraw/element/types";
import type { import type {
@@ -43,6 +44,8 @@ import type {
KeyboardModifiersObject, KeyboardModifiersObject,
} from "@excalidraw/excalidraw/types"; } from "@excalidraw/excalidraw/types";
import { LinearElementEditor } from "./linearElementEditor";
const SNAP_DISTANCE = 8; const SNAP_DISTANCE = 8;
// do not comput more gaps per axis than this limit // do not comput more gaps per axis than this limit
@@ -194,59 +197,6 @@ export const areRoughlyEqual = (a: number, b: number, precision = 0.01) => {
return Math.abs(a - b) <= precision; return Math.abs(a - b) <= precision;
}; };
export const getLinearElementPoints = (
element: ExcalidrawLinearElement,
options: {
dragOffset?: Vector2D;
excludePointsIndices?: readonly number[];
} = {},
): GlobalPoint[] => {
const { dragOffset, excludePointsIndices } = options;
if (isElbowArrow(element)) {
return [];
}
if (!element.points || element.points.length === 0) {
return [];
}
let elementX = element.x;
let elementY = element.y;
if (dragOffset) {
elementX += dragOffset.x;
elementY += dragOffset.y;
}
const globalPoints: GlobalPoint[] = [];
for (let i = 0; i < element.points.length; i++) {
// Skip the point being edited if specified
if (
excludePointsIndices?.length &&
excludePointsIndices.find((index) => index === i) !== undefined
) {
continue;
}
const point = element.points[i];
const globalX = elementX + point[0];
const globalY = elementY + point[1];
const cx = elementX + element.width / 2;
const cy = elementY + element.height / 2;
const rotated = pointRotateRads<GlobalPoint>(
pointFrom(globalX, globalY),
pointFrom(cx, cy),
element.angle,
);
globalPoints.push(pointFrom(round(rotated[0]), round(rotated[1])));
}
return globalPoints;
};
export const getElementsCorners = ( export const getElementsCorners = (
elements: ExcalidrawElement[], elements: ExcalidrawElement[],
elementsMap: ElementsMap, elementsMap: ElementsMap,
@@ -291,9 +241,13 @@ export const getElementsCorners = (
!boundingBoxCorners !boundingBoxCorners
) { ) {
// For linear elements, use actual points instead of bounding box // For linear elements, use actual points instead of bounding box
const linearPoints = getLinearElementPoints(element, { const linearPoints = LinearElementEditor.getPointsGlobalCoordinates(
dragOffset, element as NonDeleted<ExcalidrawLinearElement>,
}); elementsMap,
{
dragOffset,
},
);
result = linearPoints; result = linearPoints;
} else if ( } else if (
(element.type === "diamond" || element.type === "ellipse") && (element.type === "diamond" || element.type === "ellipse") &&
@@ -732,9 +686,13 @@ export const getReferenceSnapPointsForLinearElementPoint = (
// Include other points from the same linear element when creating new points or in editing mode // Include other points from the same linear element when creating new points or in editing mode
if (includeSelfPoints) { if (includeSelfPoints) {
const elementPoints = getLinearElementPoints(editingElement, { const elementPoints = LinearElementEditor.getPointsGlobalCoordinates(
excludePointsIndices: options.selectedPointsIndices, editingElement as NonDeleted<ExcalidrawLinearElement>,
}); elementsMap,
{
excludePointsIndices: options.selectedPointsIndices,
},
);
allSnapPoints.push(...elementPoints); allSnapPoints.push(...elementPoints);
} }