One set of actionFinalize

This commit is contained in:
Mark Tolmacs 2025-04-16 17:29:08 +02:00
parent b63cd86cd6
commit 64fa1c6948
No known key found for this signature in database
3 changed files with 36 additions and 34 deletions

View file

@ -3,10 +3,12 @@ import {
viewportCoordsToSceneCoords,
} from "@excalidraw/common";
import { pointsEqual } from "@excalidraw/math";
import type { AppState, Offsets, Zoom } from "@excalidraw/excalidraw/types";
import { getCommonBounds, getElementBounds } from "./bounds";
import { isFreeDrawElement, isLinearElement } from "./typeChecks";
import { isElbowArrow, isFreeDrawElement, isLinearElement } from "./typeChecks";
import type { ElementsMap, ExcalidrawElement } from "./types";
@ -16,6 +18,12 @@ import type { ElementsMap, ExcalidrawElement } from "./types";
export const isInvisiblySmallElement = (
element: ExcalidrawElement,
): boolean => {
if (isElbowArrow(element)) {
return (
element.points.length < 2 ||
pointsEqual(element.points[0], element.points[element.points.length - 1])
);
}
if (isLinearElement(element) || isFreeDrawElement(element)) {
return element.points.length < 2;
}

View file

@ -7,6 +7,7 @@ import {
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor";
import {
isArrowElement,
isBindingElement,
isLinearElement,
} from "@excalidraw/element/typeChecks";
@ -62,6 +63,7 @@ export const actionFinalize = register({
captureUpdate: CaptureUpdateAction.IMMEDIATELY,
};
}
} else if (isArrowElement(appState.newElement)) {
}
let newElements = elements;
@ -82,48 +84,46 @@ export const actionFinalize = register({
focusContainer();
}
const multiPointElement = appState.multiElement
const element = appState.multiElement
? appState.multiElement
: appState.newElement?.type === "freedraw"
? appState.newElement
: isBindingElement(appState.newElement)
? appState.newElement
: null;
if (multiPointElement) {
if (element) {
// pen and mouse have hover
if (
multiPointElement.type !== "freedraw" &&
appState.multiElement &&
element.type !== "freedraw" &&
appState.lastPointerDownWith !== "touch"
) {
const { points, lastCommittedPoint } = multiPointElement;
const { points, lastCommittedPoint } = element;
if (
!lastCommittedPoint ||
points[points.length - 1] !== lastCommittedPoint
) {
scene.mutateElement(multiPointElement, {
points: multiPointElement.points.slice(0, -1),
scene.mutateElement(element, {
points: element.points.slice(0, -1),
});
}
}
if (isInvisiblySmallElement(multiPointElement)) {
if (isInvisiblySmallElement(element)) {
// TODO: #7348 in theory this gets recorded by the store, so the invisible elements could be restored by the undo/redo, which might be not what we would want
newElements = newElements.filter(
(el) => el.id !== multiPointElement.id,
);
newElements = newElements.filter((el) => el.id !== element.id);
}
// If the multi point line closes the loop,
// set the last point to first point.
// This ensures that loop remains closed at different scales.
const isLoop = isPathALoop(multiPointElement.points, appState.zoom.value);
if (
multiPointElement.type === "line" ||
multiPointElement.type === "freedraw"
) {
const isLoop = isPathALoop(element.points, appState.zoom.value);
if (element.type === "line" || element.type === "freedraw") {
if (isLoop) {
const linePoints = multiPointElement.points;
const linePoints = element.points;
const firstPoint = linePoints[0];
scene.mutateElement(multiPointElement, {
scene.mutateElement(element, {
points: linePoints.map((p, index) =>
index === linePoints.length - 1
? pointFrom(firstPoint[0], firstPoint[1])
@ -133,24 +133,20 @@ export const actionFinalize = register({
}
}
if (
isBindingElement(multiPointElement) &&
!isLoop &&
multiPointElement.points.length > 1
) {
if (isBindingElement(element) && !isLoop && element.points.length > 1) {
const [x, y] = LinearElementEditor.getPointAtIndexGlobalCoordinates(
multiPointElement,
element,
-1,
arrayToMap(elements),
);
maybeBindLinearElement(multiPointElement, appState, { x, y }, scene);
maybeBindLinearElement(element, appState, { x, y }, scene);
}
}
if (
(!appState.activeTool.locked &&
appState.activeTool.type !== "freedraw") ||
!multiPointElement
!element
) {
resetCursor(interactiveCanvas);
}
@ -177,7 +173,7 @@ export const actionFinalize = register({
activeTool:
(appState.activeTool.locked ||
appState.activeTool.type === "freedraw") &&
multiPointElement
element
? appState.activeTool
: activeTool,
activeEmbeddable: null,
@ -188,21 +184,18 @@ export const actionFinalize = register({
startBoundElement: null,
suggestedBindings: [],
selectedElementIds:
multiPointElement &&
element &&
!appState.activeTool.locked &&
appState.activeTool.type !== "freedraw"
? {
...appState.selectedElementIds,
[multiPointElement.id]: true,
[element.id]: true,
}
: appState.selectedElementIds,
// To select the linear element when user has finished mutipoint editing
selectedLinearElement:
multiPointElement && isLinearElement(multiPointElement)
? new LinearElementEditor(
multiPointElement,
arrayToMap(newElements),
)
element && isLinearElement(element)
? new LinearElementEditor(element, arrayToMap(newElements))
: appState.selectedLinearElement,
pendingImageElementId: null,
},

View file

@ -9022,6 +9022,7 @@ class App extends React.Component<AppProps, AppState> {
linearElementEditor;
const element = this.scene.getElement(linearElementEditor.elementId);
if (isBindingElement(element)) {
this.actionManager.executeAction(actionFinalize);
bindOrUnbindLinearElement(
element,
startBindingElement,