respect initial type when switching between linears

This commit is contained in:
Ryan Di 2025-04-25 10:40:36 +10:00
parent 63dd599089
commit f99fe54797
2 changed files with 42 additions and 4 deletions

View file

@ -44,7 +44,6 @@ import type {
ExcalidrawIframeElement, ExcalidrawIframeElement,
ElementsMap, ElementsMap,
ExcalidrawArrowElement, ExcalidrawArrowElement,
FixedSegment,
ExcalidrawElbowArrowElement, ExcalidrawElbowArrowElement,
} from "./types"; } from "./types";
@ -478,7 +477,7 @@ export const newArrowElement = <T extends boolean>(
endArrowhead?: Arrowhead | null; endArrowhead?: Arrowhead | null;
points?: ExcalidrawArrowElement["points"]; points?: ExcalidrawArrowElement["points"];
elbowed?: T; elbowed?: T;
fixedSegments?: FixedSegment[] | null; fixedSegments?: ExcalidrawElbowArrowElement["fixedSegments"] | null;
} & ElementConstructorOpts, } & ElementConstructorOpts,
): T extends true ): T extends true
? NonDeleted<ExcalidrawElbowArrowElement> ? NonDeleted<ExcalidrawElbowArrowElement>

View file

@ -508,8 +508,47 @@ export const switchShapes = (
if (nextType && isConvertibleLinearType(nextType)) { if (nextType && isConvertibleLinearType(nextType)) {
const convertedElements: Record<string, ExcalidrawElement> = {}; const convertedElements: Record<string, ExcalidrawElement> = {};
for (const element of selectedLinearSwitchableElements) { for (const element of selectedLinearSwitchableElements) {
const converted = convertElementType(element, nextType, app); const { properties, initialType } =
convertedElements[converted.id] = converted; editorJotaiStore.get(shapeSwitchLinearAtom)?.[element.id] || {};
// If the initial type is not elbow, and when we switch to elbow,
// the linear line might be "bent" and the points would likely be different.
// When we then switch to other non elbow types from this converted elbow,
// we still want to use the original points instead.
if (
initialType &&
properties &&
isElbowArrow(element) &&
initialType !== "elbowArrow" &&
nextType !== "elbowArrow"
) {
// first convert back to the original type
const originalType = convertElementType(
element,
initialType,
app,
) as ExcalidrawLinearElement;
// then convert to the target type
const converted = convertElementType(
initialType === "line"
? newLinearElement({
...originalType,
...properties,
type: "line",
})
: newArrowElement({
...originalType,
...properties,
type: "arrow",
}),
nextType,
app,
);
convertedElements[converted.id] = converted;
} else {
const converted = convertElementType(element, nextType, app);
convertedElements[converted.id] = converted;
}
} }
const nextElements = []; const nextElements = [];