fix: do not snap to each other when moving multiple points together
This commit is contained in:
parent
a0f7edadec
commit
0e197ef5c4
@ -370,17 +370,12 @@ export class LinearElementEditor {
|
|||||||
const effectiveGridX = referencePointCoords[0] + dxFromReference;
|
const effectiveGridX = referencePointCoords[0] + dxFromReference;
|
||||||
const effectiveGridY = referencePointCoords[1] + dyFromReference;
|
const effectiveGridY = referencePointCoords[1] + dyFromReference;
|
||||||
|
|
||||||
let newDraggingPointPosition = pointFrom(
|
|
||||||
effectiveGridX,
|
|
||||||
effectiveGridY,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isElbowArrow(element)) {
|
if (!isElbowArrow(element)) {
|
||||||
const { snapOffset, snapLines } = snapLinearElementPoint(
|
const { snapOffset, snapLines } = snapLinearElementPoint(
|
||||||
app.scene.getNonDeletedElements(),
|
app.scene.getNonDeletedElements(),
|
||||||
element,
|
element,
|
||||||
lastClickedPoint,
|
lastClickedPoint,
|
||||||
{ x: effectiveGridX, y: effectiveGridY },
|
pointFrom<GlobalPoint>(effectiveGridX, effectiveGridY),
|
||||||
app,
|
app,
|
||||||
event,
|
event,
|
||||||
elementsMap,
|
elementsMap,
|
||||||
@ -448,7 +443,7 @@ export class LinearElementEditor {
|
|||||||
-element.angle as Radians,
|
-element.angle as Radians,
|
||||||
);
|
);
|
||||||
|
|
||||||
newDraggingPointPosition = pointFrom(
|
const newDraggingPointPosition = pointFrom(
|
||||||
referencePoint[0] + rotatedX,
|
referencePoint[0] + rotatedX,
|
||||||
referencePoint[1] + rotatedY,
|
referencePoint[1] + rotatedY,
|
||||||
);
|
);
|
||||||
@ -477,11 +472,11 @@ export class LinearElementEditor {
|
|||||||
app.scene.getNonDeletedElements(),
|
app.scene.getNonDeletedElements(),
|
||||||
element,
|
element,
|
||||||
lastClickedPoint,
|
lastClickedPoint,
|
||||||
{ x: originalPointerX, y: originalPointerY },
|
pointFrom(originalPointerX, originalPointerY),
|
||||||
app,
|
app,
|
||||||
event,
|
event,
|
||||||
elementsMap,
|
elementsMap,
|
||||||
{ includeSelfPoints: true },
|
{ includeSelfPoints: true, selectedPointsIndices },
|
||||||
);
|
);
|
||||||
|
|
||||||
_snapLines = snapLines;
|
_snapLines = snapLines;
|
||||||
@ -1223,7 +1218,7 @@ export class LinearElementEditor {
|
|||||||
app.scene.getNonDeletedElements(),
|
app.scene.getNonDeletedElements(),
|
||||||
element,
|
element,
|
||||||
points.length - 1,
|
points.length - 1,
|
||||||
{ x: effectiveGridX, y: effectiveGridY },
|
pointFrom(effectiveGridX, effectiveGridY),
|
||||||
app,
|
app,
|
||||||
event,
|
event,
|
||||||
elementsMap,
|
elementsMap,
|
||||||
@ -1311,7 +1306,7 @@ export class LinearElementEditor {
|
|||||||
app.scene.getNonDeletedElements(),
|
app.scene.getNonDeletedElements(),
|
||||||
element,
|
element,
|
||||||
points.length - 1,
|
points.length - 1,
|
||||||
{ x: originalPointerX, y: originalPointerY },
|
pointFrom(originalPointerX, originalPointerY),
|
||||||
app,
|
app,
|
||||||
event,
|
event,
|
||||||
elementsMap,
|
elementsMap,
|
||||||
|
@ -2,7 +2,6 @@ import {
|
|||||||
isCloseTo,
|
isCloseTo,
|
||||||
pointFrom,
|
pointFrom,
|
||||||
pointRotateRads,
|
pointRotateRads,
|
||||||
pointsEqual,
|
|
||||||
rangeInclusive,
|
rangeInclusive,
|
||||||
rangeIntersection,
|
rangeIntersection,
|
||||||
rangesOverlap,
|
rangesOverlap,
|
||||||
@ -198,13 +197,12 @@ export const areRoughlyEqual = (a: number, b: number, precision = 0.01) => {
|
|||||||
|
|
||||||
export const getLinearElementPoints = (
|
export const getLinearElementPoints = (
|
||||||
element: ExcalidrawLinearElement,
|
element: ExcalidrawLinearElement,
|
||||||
elementsMap: ElementsMap,
|
|
||||||
options: {
|
options: {
|
||||||
dragOffset?: Vector2D;
|
dragOffset?: Vector2D;
|
||||||
excludePointIndex?: number;
|
excludePointsIndices?: readonly number[];
|
||||||
} = {},
|
} = {},
|
||||||
): GlobalPoint[] => {
|
): GlobalPoint[] => {
|
||||||
const { dragOffset, excludePointIndex } = options;
|
const { dragOffset, excludePointsIndices } = options;
|
||||||
|
|
||||||
if (isElbowArrow(element)) {
|
if (isElbowArrow(element)) {
|
||||||
return [];
|
return [];
|
||||||
@ -226,27 +224,25 @@ export const getLinearElementPoints = (
|
|||||||
|
|
||||||
for (let i = 0; i < element.points.length; i++) {
|
for (let i = 0; i < element.points.length; i++) {
|
||||||
// Skip the point being edited if specified
|
// Skip the point being edited if specified
|
||||||
if (excludePointIndex !== undefined && i === excludePointIndex) {
|
if (
|
||||||
|
excludePointsIndices?.length &&
|
||||||
|
excludePointsIndices.find((index) => index === i) !== undefined
|
||||||
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const localPoint = element.points[i];
|
const point = element.points[i];
|
||||||
const globalX = elementX + localPoint[0];
|
const globalX = elementX + point[0];
|
||||||
const globalY = elementY + localPoint[1];
|
const globalY = elementY + point[1];
|
||||||
|
|
||||||
// Apply rotation if element is rotated
|
const cx = elementX + element.width / 2;
|
||||||
if (element.angle !== 0) {
|
const cy = elementY + element.height / 2;
|
||||||
const cx = elementX + element.width / 2;
|
const rotated = pointRotateRads<GlobalPoint>(
|
||||||
const cy = elementY + element.height / 2;
|
pointFrom(globalX, globalY),
|
||||||
const rotated = pointRotateRads<GlobalPoint>(
|
pointFrom(cx, cy),
|
||||||
pointFrom(globalX, globalY),
|
element.angle,
|
||||||
pointFrom(cx, cy),
|
);
|
||||||
element.angle,
|
globalPoints.push(pointFrom(round(rotated[0]), round(rotated[1])));
|
||||||
);
|
|
||||||
globalPoints.push(pointFrom(round(rotated[0]), round(rotated[1])));
|
|
||||||
} else {
|
|
||||||
globalPoints.push(pointFrom(round(globalX), round(globalY)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return globalPoints;
|
return globalPoints;
|
||||||
@ -296,7 +292,7 @@ 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, elementsMap, {
|
const linearPoints = getLinearElementPoints(element, {
|
||||||
dragOffset,
|
dragOffset,
|
||||||
});
|
});
|
||||||
result = linearPoints;
|
result = linearPoints;
|
||||||
@ -714,6 +710,7 @@ export const getReferenceSnapPointsForLinearElementPoint = (
|
|||||||
elementsMap: ElementsMap,
|
elementsMap: ElementsMap,
|
||||||
options: {
|
options: {
|
||||||
includeSelfPoints?: boolean;
|
includeSelfPoints?: boolean;
|
||||||
|
selectedPointsIndices?: readonly number[];
|
||||||
} = {},
|
} = {},
|
||||||
) => {
|
) => {
|
||||||
const { includeSelfPoints = false } = options;
|
const { includeSelfPoints = false } = options;
|
||||||
@ -743,24 +740,9 @@ 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, elementsMap, {
|
const elementPoints = getLinearElementPoints(editingElement, {
|
||||||
excludePointIndex: editingPointIndex >= 0 ? editingPointIndex : undefined,
|
excludePointsIndices: options.selectedPointsIndices,
|
||||||
});
|
});
|
||||||
const shouldSkipFirstOrLast =
|
|
||||||
editingElement.points.length > 2 &&
|
|
||||||
pointsEqual(
|
|
||||||
editingElement.points[0],
|
|
||||||
editingElement.points[editingElement.points.length - 1],
|
|
||||||
);
|
|
||||||
|
|
||||||
if (shouldSkipFirstOrLast) {
|
|
||||||
if (editingPointIndex === 0) {
|
|
||||||
elementPoints.pop();
|
|
||||||
}
|
|
||||||
if (editingPointIndex === editingElement.points.length - 1) {
|
|
||||||
elementPoints.shift();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allSnapPoints.push(...elementPoints);
|
allSnapPoints.push(...elementPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,12 +753,13 @@ export const snapLinearElementPoint = (
|
|||||||
elements: readonly NonDeletedExcalidrawElement[],
|
elements: readonly NonDeletedExcalidrawElement[],
|
||||||
editingElement: ExcalidrawLinearElement,
|
editingElement: ExcalidrawLinearElement,
|
||||||
editingPointIndex: number,
|
editingPointIndex: number,
|
||||||
pointPosition: Vector2D,
|
pointerPosition: GlobalPoint,
|
||||||
app: AppClassProperties,
|
app: AppClassProperties,
|
||||||
event: KeyboardModifiersObject,
|
event: KeyboardModifiersObject,
|
||||||
elementsMap: ElementsMap,
|
elementsMap: ElementsMap,
|
||||||
options: {
|
options: {
|
||||||
includeSelfPoints?: boolean;
|
includeSelfPoints?: boolean;
|
||||||
|
selectedPointsIndices?: readonly number[];
|
||||||
} = {},
|
} = {},
|
||||||
) => {
|
) => {
|
||||||
if (
|
if (
|
||||||
@ -808,16 +791,10 @@ export const snapLinearElementPoint = (
|
|||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create a snap point for the current point position
|
|
||||||
const currentPointGlobal = pointFrom<GlobalPoint>(
|
|
||||||
pointPosition.x,
|
|
||||||
pointPosition.y,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Find nearest snaps
|
// Find nearest snaps
|
||||||
for (const referencePoint of referenceSnapPoints) {
|
for (const referencePoint of referenceSnapPoints) {
|
||||||
const offsetX = referencePoint[0] - currentPointGlobal[0];
|
const offsetX = referencePoint[0] - pointerPosition[0];
|
||||||
const offsetY = referencePoint[1] - currentPointGlobal[1];
|
const offsetY = referencePoint[1] - pointerPosition[1];
|
||||||
|
|
||||||
if (Math.abs(offsetX) <= minOffset.x) {
|
if (Math.abs(offsetX) <= minOffset.x) {
|
||||||
if (Math.abs(offsetX) < minOffset.x) {
|
if (Math.abs(offsetX) < minOffset.x) {
|
||||||
@ -826,7 +803,7 @@ export const snapLinearElementPoint = (
|
|||||||
|
|
||||||
nearestSnapsX.push({
|
nearestSnapsX.push({
|
||||||
type: "point",
|
type: "point",
|
||||||
points: [currentPointGlobal, referencePoint],
|
points: [pointerPosition, referencePoint],
|
||||||
offset: offsetX,
|
offset: offsetX,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -840,7 +817,7 @@ export const snapLinearElementPoint = (
|
|||||||
|
|
||||||
nearestSnapsY.push({
|
nearestSnapsY.push({
|
||||||
type: "point",
|
type: "point",
|
||||||
points: [currentPointGlobal, referencePoint],
|
points: [pointerPosition, referencePoint],
|
||||||
offset: offsetY,
|
offset: offsetY,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -859,8 +836,8 @@ export const snapLinearElementPoint = (
|
|||||||
if (snapOffset.x !== 0 || snapOffset.y !== 0) {
|
if (snapOffset.x !== 0 || snapOffset.y !== 0) {
|
||||||
// Recalculate snap lines with the snapped position
|
// Recalculate snap lines with the snapped position
|
||||||
const snappedPosition = pointFrom<GlobalPoint>(
|
const snappedPosition = pointFrom<GlobalPoint>(
|
||||||
pointPosition.x + snapOffset.x,
|
pointerPosition[0] + snapOffset.x,
|
||||||
pointPosition.y + snapOffset.y,
|
pointerPosition[1] + snapOffset.y,
|
||||||
);
|
);
|
||||||
|
|
||||||
const snappedSnapsX: Snaps = [];
|
const snappedSnapsX: Snaps = [];
|
||||||
|
@ -5992,7 +5992,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
this.scene.getNonDeletedElements(),
|
this.scene.getNonDeletedElements(),
|
||||||
multiElement,
|
multiElement,
|
||||||
points.length - 1,
|
points.length - 1,
|
||||||
{ x: effectiveGridX, y: effectiveGridY },
|
pointFrom(effectiveGridX, effectiveGridY),
|
||||||
this,
|
this,
|
||||||
event,
|
event,
|
||||||
this.scene.getNonDeletedElementsMap(),
|
this.scene.getNonDeletedElementsMap(),
|
||||||
@ -8795,7 +8795,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
this.scene.getNonDeletedElements(),
|
this.scene.getNonDeletedElements(),
|
||||||
newElement,
|
newElement,
|
||||||
points.length - 1,
|
points.length - 1,
|
||||||
{ x: effectiveGridX, y: effectiveGridY },
|
pointFrom(effectiveGridX, effectiveGridY),
|
||||||
this,
|
this,
|
||||||
event,
|
event,
|
||||||
this.scene.getNonDeletedElementsMap(),
|
this.scene.getNonDeletedElementsMap(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user