mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
One set of actionFinalize
This commit is contained in:
parent
b63cd86cd6
commit
64fa1c6948
3 changed files with 36 additions and 34 deletions
|
@ -3,10 +3,12 @@ import {
|
||||||
viewportCoordsToSceneCoords,
|
viewportCoordsToSceneCoords,
|
||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
|
|
||||||
|
import { pointsEqual } from "@excalidraw/math";
|
||||||
|
|
||||||
import type { AppState, Offsets, Zoom } from "@excalidraw/excalidraw/types";
|
import type { AppState, Offsets, Zoom } from "@excalidraw/excalidraw/types";
|
||||||
|
|
||||||
import { getCommonBounds, getElementBounds } from "./bounds";
|
import { getCommonBounds, getElementBounds } from "./bounds";
|
||||||
import { isFreeDrawElement, isLinearElement } from "./typeChecks";
|
import { isElbowArrow, isFreeDrawElement, isLinearElement } from "./typeChecks";
|
||||||
|
|
||||||
import type { ElementsMap, ExcalidrawElement } from "./types";
|
import type { ElementsMap, ExcalidrawElement } from "./types";
|
||||||
|
|
||||||
|
@ -16,6 +18,12 @@ import type { ElementsMap, ExcalidrawElement } from "./types";
|
||||||
export const isInvisiblySmallElement = (
|
export const isInvisiblySmallElement = (
|
||||||
element: ExcalidrawElement,
|
element: ExcalidrawElement,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
|
if (isElbowArrow(element)) {
|
||||||
|
return (
|
||||||
|
element.points.length < 2 ||
|
||||||
|
pointsEqual(element.points[0], element.points[element.points.length - 1])
|
||||||
|
);
|
||||||
|
}
|
||||||
if (isLinearElement(element) || isFreeDrawElement(element)) {
|
if (isLinearElement(element) || isFreeDrawElement(element)) {
|
||||||
return element.points.length < 2;
|
return element.points.length < 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor";
|
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
isArrowElement,
|
||||||
isBindingElement,
|
isBindingElement,
|
||||||
isLinearElement,
|
isLinearElement,
|
||||||
} from "@excalidraw/element/typeChecks";
|
} from "@excalidraw/element/typeChecks";
|
||||||
|
@ -62,6 +63,7 @@ export const actionFinalize = register({
|
||||||
captureUpdate: CaptureUpdateAction.IMMEDIATELY,
|
captureUpdate: CaptureUpdateAction.IMMEDIATELY,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
} else if (isArrowElement(appState.newElement)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let newElements = elements;
|
let newElements = elements;
|
||||||
|
@ -82,48 +84,46 @@ export const actionFinalize = register({
|
||||||
focusContainer();
|
focusContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
const multiPointElement = appState.multiElement
|
const element = appState.multiElement
|
||||||
? appState.multiElement
|
? appState.multiElement
|
||||||
: appState.newElement?.type === "freedraw"
|
: appState.newElement?.type === "freedraw"
|
||||||
? appState.newElement
|
? appState.newElement
|
||||||
|
: isBindingElement(appState.newElement)
|
||||||
|
? appState.newElement
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
if (multiPointElement) {
|
if (element) {
|
||||||
// pen and mouse have hover
|
// pen and mouse have hover
|
||||||
if (
|
if (
|
||||||
multiPointElement.type !== "freedraw" &&
|
appState.multiElement &&
|
||||||
|
element.type !== "freedraw" &&
|
||||||
appState.lastPointerDownWith !== "touch"
|
appState.lastPointerDownWith !== "touch"
|
||||||
) {
|
) {
|
||||||
const { points, lastCommittedPoint } = multiPointElement;
|
const { points, lastCommittedPoint } = element;
|
||||||
if (
|
if (
|
||||||
!lastCommittedPoint ||
|
!lastCommittedPoint ||
|
||||||
points[points.length - 1] !== lastCommittedPoint
|
points[points.length - 1] !== lastCommittedPoint
|
||||||
) {
|
) {
|
||||||
scene.mutateElement(multiPointElement, {
|
scene.mutateElement(element, {
|
||||||
points: multiPointElement.points.slice(0, -1),
|
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
|
// 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(
|
newElements = newElements.filter((el) => el.id !== element.id);
|
||||||
(el) => el.id !== multiPointElement.id,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the multi point line closes the loop,
|
// If the multi point line closes the loop,
|
||||||
// set the last point to first point.
|
// set the last point to first point.
|
||||||
// This ensures that loop remains closed at different scales.
|
// This ensures that loop remains closed at different scales.
|
||||||
const isLoop = isPathALoop(multiPointElement.points, appState.zoom.value);
|
const isLoop = isPathALoop(element.points, appState.zoom.value);
|
||||||
if (
|
if (element.type === "line" || element.type === "freedraw") {
|
||||||
multiPointElement.type === "line" ||
|
|
||||||
multiPointElement.type === "freedraw"
|
|
||||||
) {
|
|
||||||
if (isLoop) {
|
if (isLoop) {
|
||||||
const linePoints = multiPointElement.points;
|
const linePoints = element.points;
|
||||||
const firstPoint = linePoints[0];
|
const firstPoint = linePoints[0];
|
||||||
scene.mutateElement(multiPointElement, {
|
scene.mutateElement(element, {
|
||||||
points: linePoints.map((p, index) =>
|
points: linePoints.map((p, index) =>
|
||||||
index === linePoints.length - 1
|
index === linePoints.length - 1
|
||||||
? pointFrom(firstPoint[0], firstPoint[1])
|
? pointFrom(firstPoint[0], firstPoint[1])
|
||||||
|
@ -133,24 +133,20 @@ export const actionFinalize = register({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (isBindingElement(element) && !isLoop && element.points.length > 1) {
|
||||||
isBindingElement(multiPointElement) &&
|
|
||||||
!isLoop &&
|
|
||||||
multiPointElement.points.length > 1
|
|
||||||
) {
|
|
||||||
const [x, y] = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
const [x, y] = LinearElementEditor.getPointAtIndexGlobalCoordinates(
|
||||||
multiPointElement,
|
element,
|
||||||
-1,
|
-1,
|
||||||
arrayToMap(elements),
|
arrayToMap(elements),
|
||||||
);
|
);
|
||||||
maybeBindLinearElement(multiPointElement, appState, { x, y }, scene);
|
maybeBindLinearElement(element, appState, { x, y }, scene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(!appState.activeTool.locked &&
|
(!appState.activeTool.locked &&
|
||||||
appState.activeTool.type !== "freedraw") ||
|
appState.activeTool.type !== "freedraw") ||
|
||||||
!multiPointElement
|
!element
|
||||||
) {
|
) {
|
||||||
resetCursor(interactiveCanvas);
|
resetCursor(interactiveCanvas);
|
||||||
}
|
}
|
||||||
|
@ -177,7 +173,7 @@ export const actionFinalize = register({
|
||||||
activeTool:
|
activeTool:
|
||||||
(appState.activeTool.locked ||
|
(appState.activeTool.locked ||
|
||||||
appState.activeTool.type === "freedraw") &&
|
appState.activeTool.type === "freedraw") &&
|
||||||
multiPointElement
|
element
|
||||||
? appState.activeTool
|
? appState.activeTool
|
||||||
: activeTool,
|
: activeTool,
|
||||||
activeEmbeddable: null,
|
activeEmbeddable: null,
|
||||||
|
@ -188,21 +184,18 @@ export const actionFinalize = register({
|
||||||
startBoundElement: null,
|
startBoundElement: null,
|
||||||
suggestedBindings: [],
|
suggestedBindings: [],
|
||||||
selectedElementIds:
|
selectedElementIds:
|
||||||
multiPointElement &&
|
element &&
|
||||||
!appState.activeTool.locked &&
|
!appState.activeTool.locked &&
|
||||||
appState.activeTool.type !== "freedraw"
|
appState.activeTool.type !== "freedraw"
|
||||||
? {
|
? {
|
||||||
...appState.selectedElementIds,
|
...appState.selectedElementIds,
|
||||||
[multiPointElement.id]: true,
|
[element.id]: true,
|
||||||
}
|
}
|
||||||
: appState.selectedElementIds,
|
: appState.selectedElementIds,
|
||||||
// To select the linear element when user has finished mutipoint editing
|
// To select the linear element when user has finished mutipoint editing
|
||||||
selectedLinearElement:
|
selectedLinearElement:
|
||||||
multiPointElement && isLinearElement(multiPointElement)
|
element && isLinearElement(element)
|
||||||
? new LinearElementEditor(
|
? new LinearElementEditor(element, arrayToMap(newElements))
|
||||||
multiPointElement,
|
|
||||||
arrayToMap(newElements),
|
|
||||||
)
|
|
||||||
: appState.selectedLinearElement,
|
: appState.selectedLinearElement,
|
||||||
pendingImageElementId: null,
|
pendingImageElementId: null,
|
||||||
},
|
},
|
||||||
|
|
|
@ -9022,6 +9022,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||||
linearElementEditor;
|
linearElementEditor;
|
||||||
const element = this.scene.getElement(linearElementEditor.elementId);
|
const element = this.scene.getElement(linearElementEditor.elementId);
|
||||||
if (isBindingElement(element)) {
|
if (isBindingElement(element)) {
|
||||||
|
this.actionManager.executeAction(actionFinalize);
|
||||||
bindOrUnbindLinearElement(
|
bindOrUnbindLinearElement(
|
||||||
element,
|
element,
|
||||||
startBindingElement,
|
startBindingElement,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue