clean switch of arrows using app state

This commit is contained in:
Ryan Di 2025-04-22 23:07:15 +10:00
parent 67793860b4
commit c90cdb7b74
2 changed files with 50 additions and 9 deletions

View file

@ -38,6 +38,7 @@ export const mutateElement = <TElement extends Mutable<ExcalidrawElement>>(
// If true, the elbow arrow tries to bind to the nearest element. If false
// it tries to keep the same bound element, if any.
isDragging?: boolean;
propertiesToDrop?: string[];
},
): TElement => {
let didChange = false;
@ -128,6 +129,12 @@ export const mutateElement = <TElement extends Mutable<ExcalidrawElement>>(
}
}
if (options?.propertiesToDrop?.includes(key)) {
delete (element as any)[key];
didChange = true;
continue;
}
(element as any)[key] = value;
didChange = true;
}

View file

@ -35,6 +35,7 @@ import { LinearElementEditor } from "@excalidraw/element/linearElementEditor";
import type {
ElementsMap,
ExcalidrawArrowElement,
ExcalidrawElement,
ExcalidrawLinearElement,
ExcalidrawTextContainer,
@ -432,15 +433,48 @@ export const switchShapes = (
selectedLinearSwitchableElements.forEach((element) => {
ShapeCache.delete(element);
// TODO: maybe add a separate function for safe type conversion
// without overloading mutateElement
if (nextType === "arrow") {
mutateElement(
element as ExcalidrawLinearElement,
element as ExcalidrawArrowElement,
{
type: nextType as LinearSwitchableToolType,
startArrowhead: null,
endArrowhead: nextType === "arrow" ? "arrow" : null,
type: "arrow",
startArrowhead: app.state.currentItemStartArrowhead,
endArrowhead: app.state.currentItemEndArrowhead,
startBinding: null,
endBinding: null,
...(app.state.currentItemArrowType === "elbow"
? { elbowed: true }
: {}),
},
false,
);
}
if (nextType === "line") {
if (isElbowArrow(element)) {
mutateElement(
element as ExcalidrawLinearElement,
{
type: "line",
startArrowhead: null,
endArrowhead: null,
startBinding: null,
endBinding: null,
},
false,
{
propertiesToDrop: [
"elbowed",
"startIsSpecial",
"endIsSpecial",
"fixedSegments",
],
},
);
}
}
if (isElbowArrow(element)) {
const nextPoints = convertLineToElbow(element);