mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-09-21 08:20:24 +02:00
Fix delayed bind mode for multiElement arrows
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
shouldRotateWithDiscreteAngle,
|
||||
getGridPoint,
|
||||
invariant,
|
||||
isShallowEqual,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import {
|
||||
@@ -279,9 +280,105 @@ export class LinearElementEditor {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns whether point was dragged
|
||||
*/
|
||||
static handlePointerMove(
|
||||
event: PointerEvent,
|
||||
app: AppClassProperties,
|
||||
scenePointerX: number,
|
||||
scenePointerY: number,
|
||||
linearElementEditor: LinearElementEditor,
|
||||
): Pick<AppState, "suggestedBinding" | "selectedLinearElement"> | null {
|
||||
const elementsMap = app.scene.getNonDeletedElementsMap();
|
||||
const elements = app.scene.getNonDeletedElements();
|
||||
const { elementId } = linearElementEditor;
|
||||
|
||||
const element = LinearElementEditor.getElement(elementId, elementsMap);
|
||||
|
||||
invariant(element, "Element being dragged must exist in the scene");
|
||||
invariant(element.points.length > 1, "Element must have at least 2 points");
|
||||
|
||||
const idx = element.points.length - 1;
|
||||
const point = element.points[idx];
|
||||
const pivotPoint = element.points[idx - 1];
|
||||
const customLineAngle =
|
||||
linearElementEditor.customLineAngle ??
|
||||
determineCustomLinearAngle(pivotPoint, element.points[idx]);
|
||||
|
||||
// Determine if point movement should happen and how much
|
||||
let deltaX = 0;
|
||||
let deltaY = 0;
|
||||
if (shouldRotateWithDiscreteAngle(event)) {
|
||||
const [width, height] = LinearElementEditor._getShiftLockedDelta(
|
||||
element,
|
||||
elementsMap,
|
||||
pivotPoint,
|
||||
pointFrom(scenePointerX, scenePointerY),
|
||||
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
|
||||
customLineAngle,
|
||||
);
|
||||
const target = pointFrom<LocalPoint>(
|
||||
width + pivotPoint[0],
|
||||
height + pivotPoint[1],
|
||||
);
|
||||
|
||||
deltaX = target[0] - point[0];
|
||||
deltaY = target[1] - point[1];
|
||||
} else {
|
||||
const newDraggingPointPosition = LinearElementEditor.createPointAt(
|
||||
element,
|
||||
elementsMap,
|
||||
scenePointerX - linearElementEditor.pointerOffset.x,
|
||||
scenePointerY - linearElementEditor.pointerOffset.y,
|
||||
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
|
||||
);
|
||||
deltaX = newDraggingPointPosition[0] - point[0];
|
||||
deltaY = newDraggingPointPosition[1] - point[1];
|
||||
}
|
||||
|
||||
// Apply the point movement if needed
|
||||
if (deltaX || deltaY) {
|
||||
const { positions, updates } = pointDraggingUpdates(
|
||||
[idx],
|
||||
deltaX,
|
||||
deltaY,
|
||||
elementsMap,
|
||||
element,
|
||||
elements,
|
||||
app,
|
||||
);
|
||||
|
||||
LinearElementEditor.movePoints(element, app.scene, positions, updates);
|
||||
}
|
||||
|
||||
// Suggest bindings for first and last point if selected
|
||||
let suggestedBinding: AppState["suggestedBinding"] = null;
|
||||
if (isBindingElement(element, false)) {
|
||||
suggestedBinding = maybeSuggestBindingsForBindingElementAtCoords(
|
||||
element,
|
||||
"end",
|
||||
app.scene,
|
||||
pointFrom<GlobalPoint>(scenePointerX, scenePointerY),
|
||||
);
|
||||
}
|
||||
|
||||
const newLinearElementEditor = {
|
||||
...linearElementEditor,
|
||||
customLineAngle,
|
||||
};
|
||||
|
||||
if (
|
||||
app.state.selectedLinearElement?.customLineAngle === customLineAngle &&
|
||||
(!suggestedBinding ||
|
||||
isShallowEqual(app.state.suggestedBinding ?? [], suggestedBinding))
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
selectedLinearElement: newLinearElementEditor,
|
||||
suggestedBinding,
|
||||
};
|
||||
}
|
||||
|
||||
static handlePointDragging(
|
||||
event: PointerEvent,
|
||||
app: AppClassProperties,
|
||||
@@ -913,7 +1010,7 @@ export class LinearElementEditor {
|
||||
return pointsEqual(point1, point2);
|
||||
}
|
||||
|
||||
static handlePointerMove(
|
||||
static handlePointerMoveInEditMode(
|
||||
event: React.PointerEvent<HTMLCanvasElement>,
|
||||
scenePointerX: number,
|
||||
scenePointerY: number,
|
||||
|
Reference in New Issue
Block a user