mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-09-16 14:00:56 +02:00
refactor: simplify code
This commit is contained in:
@@ -8,7 +8,6 @@ import {
|
||||
pointDistance,
|
||||
vectorFromPoint,
|
||||
line,
|
||||
linesIntersectAt,
|
||||
curveLength,
|
||||
curvePointAtLength,
|
||||
} from "@excalidraw/math";
|
||||
@@ -29,6 +28,7 @@ import {
|
||||
deconstructLinearOrFreeDrawElement,
|
||||
isPathALoop,
|
||||
snapLinearElementPoint,
|
||||
snapToDiscreteAngle,
|
||||
type SnapLine,
|
||||
type Store,
|
||||
} from "@excalidraw/element";
|
||||
@@ -397,45 +397,16 @@ export class LinearElementEditor {
|
||||
pointFrom(referencePointCoords[0], referencePointCoords[1]),
|
||||
);
|
||||
|
||||
const firstSnapLine = snapLines[0];
|
||||
if (
|
||||
firstSnapLine.type === "points" &&
|
||||
firstSnapLine.points.length > 1
|
||||
) {
|
||||
const snapLine = line(
|
||||
firstSnapLine.points[0],
|
||||
firstSnapLine.points[1],
|
||||
);
|
||||
const intersection = linesIntersectAt<GlobalPoint>(
|
||||
angleLine,
|
||||
snapLine,
|
||||
);
|
||||
const result = snapToDiscreteAngle(
|
||||
snapLines,
|
||||
angleLine,
|
||||
pointFrom(gridX, gridY),
|
||||
referencePointCoords,
|
||||
);
|
||||
|
||||
if (intersection) {
|
||||
dxFromReference = intersection[0] - referencePointCoords[0];
|
||||
dyFromReference = intersection[1] - referencePointCoords[1];
|
||||
|
||||
const furthestPoint = firstSnapLine.points.reduce(
|
||||
(furthest, point) => {
|
||||
const distance = pointDistance(intersection, point);
|
||||
if (distance > furthest.distance) {
|
||||
return { point, distance };
|
||||
}
|
||||
return furthest;
|
||||
},
|
||||
{
|
||||
point: firstSnapLine.points[0],
|
||||
distance: pointDistance(
|
||||
intersection,
|
||||
firstSnapLine.points[0],
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
firstSnapLine.points = [furthestPoint.point, intersection];
|
||||
_snapLines = [firstSnapLine];
|
||||
}
|
||||
}
|
||||
dxFromReference = result.dxFromReference;
|
||||
dyFromReference = result.dyFromReference;
|
||||
_snapLines = result.snapLines;
|
||||
} else if (snapLines.length > 0) {
|
||||
const snappedGridX = effectiveGridX + snapOffset.x;
|
||||
const snappedGridY = effectiveGridY + snapOffset.y;
|
||||
@@ -1237,49 +1208,16 @@ export class LinearElementEditor {
|
||||
pointFrom(lastCommittedPointCoords[0], lastCommittedPointCoords[1]),
|
||||
);
|
||||
|
||||
const firstSnapLine = _snapLines[0];
|
||||
if (
|
||||
firstSnapLine.type === "points" &&
|
||||
firstSnapLine.points.length > 1
|
||||
) {
|
||||
const snapLine = line(
|
||||
firstSnapLine.points[0],
|
||||
firstSnapLine.points[1],
|
||||
);
|
||||
const intersection = linesIntersectAt<GlobalPoint>(
|
||||
angleLine,
|
||||
snapLine,
|
||||
);
|
||||
const result = snapToDiscreteAngle(
|
||||
_snapLines,
|
||||
angleLine,
|
||||
pointFrom(gridX, gridY),
|
||||
lastCommittedPointCoords,
|
||||
);
|
||||
|
||||
if (intersection) {
|
||||
dxFromLastCommitted =
|
||||
intersection[0] - lastCommittedPointCoords[0];
|
||||
dyFromLastCommitted =
|
||||
intersection[1] - lastCommittedPointCoords[1];
|
||||
|
||||
const furthestPoint = firstSnapLine.points.reduce(
|
||||
(furthest, point) => {
|
||||
const distance = pointDistance(intersection, point);
|
||||
if (distance > furthest.distance) {
|
||||
return { point, distance };
|
||||
}
|
||||
return furthest;
|
||||
},
|
||||
{
|
||||
point: firstSnapLine.points[0],
|
||||
distance: pointDistance(
|
||||
intersection,
|
||||
firstSnapLine.points[0],
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
firstSnapLine.points = [furthestPoint.point, intersection];
|
||||
snapLines = [firstSnapLine];
|
||||
}
|
||||
} else {
|
||||
snapLines = [];
|
||||
}
|
||||
dxFromLastCommitted = result.dxFromReference;
|
||||
dyFromLastCommitted = result.dyFromReference;
|
||||
snapLines = result.snapLines;
|
||||
} else if (_snapLines.length > 0) {
|
||||
const snappedGridX = effectiveGridX + snapOffset.x;
|
||||
const snappedGridY = effectiveGridY + snapOffset.y;
|
||||
|
@@ -1,5 +1,8 @@
|
||||
import {
|
||||
isCloseTo,
|
||||
line,
|
||||
linesIntersectAt,
|
||||
pointDistance,
|
||||
pointFrom,
|
||||
pointRotateRads,
|
||||
rangeInclusive,
|
||||
@@ -1643,3 +1646,79 @@ export const isActiveToolNonLinearSnappable = (
|
||||
activeToolType === TOOL_TYPE.text
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Snaps to discrete angle rotation logic.
|
||||
* This function handles the common pattern of finding intersections between
|
||||
* angle lines and snap lines, and updating the snap lines accordingly.
|
||||
*
|
||||
* @param snapLines - The original snap lines from snapping
|
||||
* @param angleLine - The line representing the discrete angle constraint
|
||||
* @param gridPosition - The grid position (original pointer position)
|
||||
* @param referencePosition - The reference position (usually the start point)
|
||||
* @returns Object containing updated snap lines and position deltas
|
||||
*/
|
||||
export const snapToDiscreteAngle = (
|
||||
snapLines: SnapLine[],
|
||||
angleLine: [GlobalPoint, GlobalPoint],
|
||||
gridPosition: GlobalPoint,
|
||||
referencePosition: GlobalPoint,
|
||||
): {
|
||||
snapLines: SnapLine[];
|
||||
dxFromReference: number;
|
||||
dyFromReference: number;
|
||||
} => {
|
||||
if (snapLines.length === 0) {
|
||||
return {
|
||||
snapLines: [],
|
||||
dxFromReference: gridPosition[0] - referencePosition[0],
|
||||
dyFromReference: gridPosition[1] - referencePosition[1],
|
||||
};
|
||||
}
|
||||
|
||||
const firstSnapLine = snapLines[0];
|
||||
if (firstSnapLine.type === "points" && firstSnapLine.points.length > 1) {
|
||||
const snapLine = line(firstSnapLine.points[0], firstSnapLine.points[1]);
|
||||
const intersection = linesIntersectAt<GlobalPoint>(
|
||||
line(angleLine[0], angleLine[1]),
|
||||
snapLine,
|
||||
);
|
||||
|
||||
if (intersection) {
|
||||
const dxFromReference = intersection[0] - referencePosition[0];
|
||||
const dyFromReference = intersection[1] - referencePosition[1];
|
||||
|
||||
const furthestPoint = firstSnapLine.points.reduce(
|
||||
(furthest, point) => {
|
||||
const distance = pointDistance(intersection, point);
|
||||
if (distance > furthest.distance) {
|
||||
return { point, distance };
|
||||
}
|
||||
return furthest;
|
||||
},
|
||||
{
|
||||
point: firstSnapLine.points[0],
|
||||
distance: pointDistance(intersection, firstSnapLine.points[0]),
|
||||
},
|
||||
);
|
||||
|
||||
const updatedSnapLine: PointSnapLine = {
|
||||
type: "points",
|
||||
points: [furthestPoint.point, intersection],
|
||||
};
|
||||
|
||||
return {
|
||||
snapLines: [updatedSnapLine],
|
||||
dxFromReference,
|
||||
dyFromReference,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// If no intersection found, return original snap lines with grid position
|
||||
return {
|
||||
snapLines,
|
||||
dxFromReference: gridPosition[0] - referencePosition[0],
|
||||
dyFromReference: gridPosition[1] - referencePosition[1],
|
||||
};
|
||||
};
|
||||
|
@@ -17,7 +17,6 @@ import {
|
||||
vectorDot,
|
||||
vectorNormalize,
|
||||
line,
|
||||
linesIntersectAt,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import {
|
||||
@@ -240,6 +239,7 @@ import {
|
||||
isActiveToolNonLinearSnappable,
|
||||
getSnapLinesAtPointer,
|
||||
snapLinearElementPoint,
|
||||
snapToDiscreteAngle,
|
||||
isSnappingEnabled,
|
||||
getReferenceSnapPoints,
|
||||
getVisibleGaps,
|
||||
@@ -6030,54 +6030,19 @@ class App extends React.Component<AppProps, AppState> {
|
||||
pointFrom(lastCommittedX + rx, lastCommittedY + ry),
|
||||
);
|
||||
|
||||
// Find intersection with first snap line
|
||||
const firstSnapLine = snapLines[0];
|
||||
if (
|
||||
firstSnapLine.type === "points" &&
|
||||
firstSnapLine.points.length > 1
|
||||
) {
|
||||
const snapLine = line(
|
||||
firstSnapLine.points[0],
|
||||
firstSnapLine.points[1],
|
||||
);
|
||||
const intersection = linesIntersectAt<GlobalPoint>(
|
||||
angleLine,
|
||||
snapLine,
|
||||
);
|
||||
const result = snapToDiscreteAngle(
|
||||
snapLines,
|
||||
angleLine,
|
||||
pointFrom(gridX, gridY),
|
||||
pointFrom(lastCommittedX + rx, lastCommittedY + ry),
|
||||
);
|
||||
|
||||
if (intersection) {
|
||||
dxFromLastCommitted = intersection[0] - rx - lastCommittedX;
|
||||
dyFromLastCommitted = intersection[1] - ry - lastCommittedY;
|
||||
dxFromLastCommitted = result.dxFromReference;
|
||||
dyFromLastCommitted = result.dyFromReference;
|
||||
|
||||
// Find the furthest point from the intersection
|
||||
const furthestPoint = firstSnapLine.points.reduce(
|
||||
(furthest, point) => {
|
||||
const distance = pointDistance(intersection, point);
|
||||
if (distance > furthest.distance) {
|
||||
return { point, distance };
|
||||
}
|
||||
return furthest;
|
||||
},
|
||||
{
|
||||
point: firstSnapLine.points[0],
|
||||
distance: pointDistance(
|
||||
intersection,
|
||||
firstSnapLine.points[0],
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
firstSnapLine.points = [furthestPoint.point, intersection];
|
||||
|
||||
this.setState({
|
||||
snapLines: [firstSnapLine],
|
||||
});
|
||||
|
||||
this.setState({
|
||||
snapLines: [firstSnapLine],
|
||||
});
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
snapLines: result.snapLines,
|
||||
});
|
||||
} else {
|
||||
const snappedGridX = effectiveGridX + snapOffset.x;
|
||||
const snappedGridY = effectiveGridY + snapOffset.y;
|
||||
@@ -8814,52 +8779,19 @@ class App extends React.Component<AppProps, AppState> {
|
||||
pointFrom(newElement.x, newElement.y),
|
||||
);
|
||||
|
||||
const firstSnapLine = snapLines.find(
|
||||
(snapLine) =>
|
||||
snapLine.type === "points" && snapLine.points.length > 2,
|
||||
const result = snapToDiscreteAngle(
|
||||
snapLines,
|
||||
angleLine,
|
||||
pointFrom(gridX, gridY),
|
||||
pointFrom(newElement.x, newElement.y),
|
||||
);
|
||||
if (firstSnapLine && firstSnapLine.points.length > 1) {
|
||||
const snapLine = line(
|
||||
firstSnapLine.points[0],
|
||||
firstSnapLine.points[1],
|
||||
);
|
||||
const intersection = linesIntersectAt<GlobalPoint>(
|
||||
angleLine,
|
||||
snapLine,
|
||||
);
|
||||
if (intersection) {
|
||||
dx = intersection[0] - newElement.x;
|
||||
dy = intersection[1] - newElement.y;
|
||||
|
||||
// Find the furthest point from the intersection
|
||||
const furthestPoint = firstSnapLine.points.reduce(
|
||||
(furthest, point) => {
|
||||
const distance = pointDistance(intersection, point);
|
||||
if (distance > furthest.distance) {
|
||||
return { point, distance };
|
||||
}
|
||||
return furthest;
|
||||
},
|
||||
{
|
||||
point: firstSnapLine.points[0],
|
||||
distance: pointDistance(
|
||||
intersection,
|
||||
firstSnapLine.points[0],
|
||||
),
|
||||
},
|
||||
);
|
||||
dx = result.dxFromReference;
|
||||
dy = result.dyFromReference;
|
||||
|
||||
firstSnapLine.points = [furthestPoint.point, intersection];
|
||||
|
||||
this.setState({
|
||||
snapLines: [firstSnapLine],
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
snapLines: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
snapLines: result.snapLines,
|
||||
});
|
||||
} else {
|
||||
dx = gridX + snapOffset.x - newElement.x;
|
||||
dy = gridY + snapOffset.y - newElement.y;
|
||||
|
Reference in New Issue
Block a user