refactor: simplify code
This commit is contained in:
parent
dceaa53b0c
commit
7332e76d56
@ -8,7 +8,6 @@ import {
|
|||||||
pointDistance,
|
pointDistance,
|
||||||
vectorFromPoint,
|
vectorFromPoint,
|
||||||
line,
|
line,
|
||||||
linesIntersectAt,
|
|
||||||
curveLength,
|
curveLength,
|
||||||
curvePointAtLength,
|
curvePointAtLength,
|
||||||
} from "@excalidraw/math";
|
} from "@excalidraw/math";
|
||||||
@ -29,6 +28,7 @@ import {
|
|||||||
deconstructLinearOrFreeDrawElement,
|
deconstructLinearOrFreeDrawElement,
|
||||||
isPathALoop,
|
isPathALoop,
|
||||||
snapLinearElementPoint,
|
snapLinearElementPoint,
|
||||||
|
snapToDiscreteAngle,
|
||||||
type SnapLine,
|
type SnapLine,
|
||||||
type Store,
|
type Store,
|
||||||
} from "@excalidraw/element";
|
} from "@excalidraw/element";
|
||||||
@ -397,45 +397,16 @@ export class LinearElementEditor {
|
|||||||
pointFrom(referencePointCoords[0], referencePointCoords[1]),
|
pointFrom(referencePointCoords[0], referencePointCoords[1]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const firstSnapLine = snapLines[0];
|
const result = snapToDiscreteAngle(
|
||||||
if (
|
snapLines,
|
||||||
firstSnapLine.type === "points" &&
|
|
||||||
firstSnapLine.points.length > 1
|
|
||||||
) {
|
|
||||||
const snapLine = line(
|
|
||||||
firstSnapLine.points[0],
|
|
||||||
firstSnapLine.points[1],
|
|
||||||
);
|
|
||||||
const intersection = linesIntersectAt<GlobalPoint>(
|
|
||||||
angleLine,
|
angleLine,
|
||||||
snapLine,
|
pointFrom(gridX, gridY),
|
||||||
|
referencePointCoords,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (intersection) {
|
dxFromReference = result.dxFromReference;
|
||||||
dxFromReference = intersection[0] - referencePointCoords[0];
|
dyFromReference = result.dyFromReference;
|
||||||
dyFromReference = intersection[1] - referencePointCoords[1];
|
_snapLines = result.snapLines;
|
||||||
|
|
||||||
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 if (snapLines.length > 0) {
|
} else if (snapLines.length > 0) {
|
||||||
const snappedGridX = effectiveGridX + snapOffset.x;
|
const snappedGridX = effectiveGridX + snapOffset.x;
|
||||||
const snappedGridY = effectiveGridY + snapOffset.y;
|
const snappedGridY = effectiveGridY + snapOffset.y;
|
||||||
@ -1237,49 +1208,16 @@ export class LinearElementEditor {
|
|||||||
pointFrom(lastCommittedPointCoords[0], lastCommittedPointCoords[1]),
|
pointFrom(lastCommittedPointCoords[0], lastCommittedPointCoords[1]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const firstSnapLine = _snapLines[0];
|
const result = snapToDiscreteAngle(
|
||||||
if (
|
_snapLines,
|
||||||
firstSnapLine.type === "points" &&
|
|
||||||
firstSnapLine.points.length > 1
|
|
||||||
) {
|
|
||||||
const snapLine = line(
|
|
||||||
firstSnapLine.points[0],
|
|
||||||
firstSnapLine.points[1],
|
|
||||||
);
|
|
||||||
const intersection = linesIntersectAt<GlobalPoint>(
|
|
||||||
angleLine,
|
angleLine,
|
||||||
snapLine,
|
pointFrom(gridX, gridY),
|
||||||
|
lastCommittedPointCoords,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (intersection) {
|
dxFromLastCommitted = result.dxFromReference;
|
||||||
dxFromLastCommitted =
|
dyFromLastCommitted = result.dyFromReference;
|
||||||
intersection[0] - lastCommittedPointCoords[0];
|
snapLines = result.snapLines;
|
||||||
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 = [];
|
|
||||||
}
|
|
||||||
} else if (_snapLines.length > 0) {
|
} else if (_snapLines.length > 0) {
|
||||||
const snappedGridX = effectiveGridX + snapOffset.x;
|
const snappedGridX = effectiveGridX + snapOffset.x;
|
||||||
const snappedGridY = effectiveGridY + snapOffset.y;
|
const snappedGridY = effectiveGridY + snapOffset.y;
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
isCloseTo,
|
isCloseTo,
|
||||||
|
line,
|
||||||
|
linesIntersectAt,
|
||||||
|
pointDistance,
|
||||||
pointFrom,
|
pointFrom,
|
||||||
pointRotateRads,
|
pointRotateRads,
|
||||||
rangeInclusive,
|
rangeInclusive,
|
||||||
@ -1643,3 +1646,79 @@ export const isActiveToolNonLinearSnappable = (
|
|||||||
activeToolType === TOOL_TYPE.text
|
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,
|
vectorDot,
|
||||||
vectorNormalize,
|
vectorNormalize,
|
||||||
line,
|
line,
|
||||||
linesIntersectAt,
|
|
||||||
} from "@excalidraw/math";
|
} from "@excalidraw/math";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -240,6 +239,7 @@ import {
|
|||||||
isActiveToolNonLinearSnappable,
|
isActiveToolNonLinearSnappable,
|
||||||
getSnapLinesAtPointer,
|
getSnapLinesAtPointer,
|
||||||
snapLinearElementPoint,
|
snapLinearElementPoint,
|
||||||
|
snapToDiscreteAngle,
|
||||||
isSnappingEnabled,
|
isSnappingEnabled,
|
||||||
getReferenceSnapPoints,
|
getReferenceSnapPoints,
|
||||||
getVisibleGaps,
|
getVisibleGaps,
|
||||||
@ -6030,54 +6030,19 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
pointFrom(lastCommittedX + rx, lastCommittedY + ry),
|
pointFrom(lastCommittedX + rx, lastCommittedY + ry),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Find intersection with first snap line
|
const result = snapToDiscreteAngle(
|
||||||
const firstSnapLine = snapLines[0];
|
snapLines,
|
||||||
if (
|
|
||||||
firstSnapLine.type === "points" &&
|
|
||||||
firstSnapLine.points.length > 1
|
|
||||||
) {
|
|
||||||
const snapLine = line(
|
|
||||||
firstSnapLine.points[0],
|
|
||||||
firstSnapLine.points[1],
|
|
||||||
);
|
|
||||||
const intersection = linesIntersectAt<GlobalPoint>(
|
|
||||||
angleLine,
|
angleLine,
|
||||||
snapLine,
|
pointFrom(gridX, gridY),
|
||||||
|
pointFrom(lastCommittedX + rx, lastCommittedY + ry),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (intersection) {
|
dxFromLastCommitted = result.dxFromReference;
|
||||||
dxFromLastCommitted = intersection[0] - rx - lastCommittedX;
|
dyFromLastCommitted = result.dyFromReference;
|
||||||
dyFromLastCommitted = intersection[1] - ry - lastCommittedY;
|
|
||||||
|
|
||||||
// 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({
|
this.setState({
|
||||||
snapLines: [firstSnapLine],
|
snapLines: result.snapLines,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({
|
|
||||||
snapLines: [firstSnapLine],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const snappedGridX = effectiveGridX + snapOffset.x;
|
const snappedGridX = effectiveGridX + snapOffset.x;
|
||||||
const snappedGridY = effectiveGridY + snapOffset.y;
|
const snappedGridY = effectiveGridY + snapOffset.y;
|
||||||
@ -8814,52 +8779,19 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
pointFrom(newElement.x, newElement.y),
|
pointFrom(newElement.x, newElement.y),
|
||||||
);
|
);
|
||||||
|
|
||||||
const firstSnapLine = snapLines.find(
|
const result = snapToDiscreteAngle(
|
||||||
(snapLine) =>
|
snapLines,
|
||||||
snapLine.type === "points" && snapLine.points.length > 2,
|
|
||||||
);
|
|
||||||
if (firstSnapLine && firstSnapLine.points.length > 1) {
|
|
||||||
const snapLine = line(
|
|
||||||
firstSnapLine.points[0],
|
|
||||||
firstSnapLine.points[1],
|
|
||||||
);
|
|
||||||
const intersection = linesIntersectAt<GlobalPoint>(
|
|
||||||
angleLine,
|
angleLine,
|
||||||
snapLine,
|
pointFrom(gridX, gridY),
|
||||||
);
|
pointFrom(newElement.x, newElement.y),
|
||||||
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],
|
|
||||||
),
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
firstSnapLine.points = [furthestPoint.point, intersection];
|
dx = result.dxFromReference;
|
||||||
|
dy = result.dyFromReference;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
snapLines: [firstSnapLine],
|
snapLines: result.snapLines,
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
this.setState({
|
|
||||||
snapLines: [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
dx = gridX + snapOffset.x - newElement.x;
|
dx = gridX + snapOffset.x - newElement.x;
|
||||||
dy = gridY + snapOffset.y - newElement.y;
|
dy = gridY + snapOffset.y - newElement.y;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user