support arrow bindings via start and end in api

This commit is contained in:
Aakansha Doshi
2023-05-22 21:22:36 +05:30
parent 0449cccc39
commit d8c901e0c1
4 changed files with 114 additions and 12 deletions

View File

@@ -1,5 +1,7 @@
import { import {
ExcalidrawBindableElement,
ExcalidrawElement, ExcalidrawElement,
ExcalidrawLinearElement,
FontFamilyValues, FontFamilyValues,
TextAlign, TextAlign,
VerticalAlign, VerticalAlign,
@@ -71,6 +73,22 @@ export interface ImportedDataState {
type: "text"; type: "text";
text: string; text: string;
} & ElementConstructorOpts) } & ElementConstructorOpts)
| ({
type: "arrow";
label?: {
text: string;
fontSize?: number;
fontFamily?: FontFamilyValues;
textAlign?: TextAlign;
verticalAlign?: VerticalAlign;
} & MarkOptional<ElementConstructorOpts, "x" | "y">;
start?: {
type: ExcalidrawBindableElement["type"] & ElementConstructorOpts;
};
end?: {
type: ExcalidrawBindableElement["type"] & ElementConstructorOpts;
};
} & ElementConstructorOpts)
)[] )[]
| null; | null;
appState?: Readonly< appState?: Readonly<

View File

@@ -190,7 +190,7 @@ export const maybeBindLinearElement = (
} }
}; };
const bindLinearElement = ( export const bindLinearElement = (
linearElement: NonDeleted<ExcalidrawLinearElement>, linearElement: NonDeleted<ExcalidrawLinearElement>,
hoveredElement: ExcalidrawBindableElement, hoveredElement: ExcalidrawBindableElement,
startOrEnd: "start" | "end", startOrEnd: "start" | "end",

View File

@@ -12,6 +12,7 @@ import {
ExcalidrawFreeDrawElement, ExcalidrawFreeDrawElement,
FontFamilyValues, FontFamilyValues,
ExcalidrawTextContainer, ExcalidrawTextContainer,
ExcalidrawBindableElement,
} from "../element/types"; } from "../element/types";
import { import {
arrayToMap, arrayToMap,
@@ -49,6 +50,7 @@ import {
import { isArrowElement } from "./typeChecks"; import { isArrowElement } from "./typeChecks";
import { MarkOptional, Merge, Mutable } from "../utility-types"; import { MarkOptional, Merge, Mutable } from "../utility-types";
import { ImportedDataState } from "../data/types"; import { ImportedDataState } from "../data/types";
import { bindLinearElement } from "./binding";
export const ELEMENTS_SUPPORTING_PROGRAMMATIC_API = [ export const ELEMENTS_SUPPORTING_PROGRAMMATIC_API = [
"rectangle", "rectangle",
@@ -670,30 +672,116 @@ export const convertToExcalidrawElements = (
res.push(element as ExcalidrawElement); res.push(element as ExcalidrawElement);
return; return;
} }
let startBoundElement;
let endBoundElement;
//@ts-ignore //@ts-ignore
if (VALID_CONTAINER_TYPES.has(element.type) && element?.label?.text) { if (VALID_CONTAINER_TYPES.has(element.type) && element?.label?.text) {
//@ts-ignore //@ts-ignore
const elements = bindTextToContainer(element, element.label); const elements = bindTextToContainer(element, element.label);
res.push(...elements); const [container, text] = elements;
if (container.type === "arrow") {
//@ts-ignore
const { start, end } = element;
if (start) {
const width = start?.width ?? 100;
const height = start?.height ?? 100;
startBoundElement = newElement({
x: start.x || container.x - width,
y: start.y || container.y - height / 2,
width,
height,
...start,
}) as ExcalidrawBindableElement;
bindLinearElement(
container as ExcalidrawLinearElement,
startBoundElement,
"start",
);
}
if (end) {
const height = end?.height ?? 100;
endBoundElement = newElement({
x: end.x || container.x + container.width,
y: end.y || container.y - height / 2,
width: end?.width ?? 100,
height,
...end,
}) as ExcalidrawBindableElement;
bindLinearElement(
container as ExcalidrawLinearElement,
endBoundElement,
"end",
);
}
}
res.push(container);
res.push(text);
if (startBoundElement) {
res.push(startBoundElement);
}
if (endBoundElement) {
res.push(endBoundElement);
}
} else { } else {
let excalidrawElement; let excalidrawElement;
const { type, ...rest } = element;
if (element.type === "text") { if (element.type === "text") {
excalidrawElement = { excalidrawElement = {
...element, ...element,
} as ExcalidrawTextElement; } as ExcalidrawTextElement;
} else if (type === "arrow" || type === "line") { res.push(excalidrawElement);
} else if (element.type === "arrow" || element.type === "line") {
//@ts-ignore
const { start, end, type, endArrowHead, ...rest } = element;
excalidrawElement = { excalidrawElement = {
type, type,
width: 200, width: 200,
height: 24, height: 24,
endArrowhead: element.type === "arrow" ? "arrow" : null,
points: [ points: [
[0, 0], [0, 0],
[200, 0], [200, 0],
], ],
endArrowhead: endArrowHead || type === "arrow" ? "arrow" : null,
...rest, ...rest,
} as ExcalidrawLinearElement; } as ExcalidrawLinearElement;
let startBoundElement;
let endBoundElement;
if (start) {
const width = start?.width ?? 100;
const height = start?.height ?? 100;
startBoundElement = newElement({
x: start.x || excalidrawElement.x - width,
y: start.y || excalidrawElement.y - height / 2,
width,
height,
...start,
}) as ExcalidrawBindableElement;
bindLinearElement(excalidrawElement, startBoundElement, "start");
}
if (end) {
const height = end?.height ?? 100;
endBoundElement = newElement({
x: end.x || excalidrawElement.x + excalidrawElement.width,
y: end.y || excalidrawElement.y - height / 2,
width: end?.width ?? 100,
height,
...end,
}) as ExcalidrawBindableElement;
bindLinearElement(excalidrawElement, endBoundElement, "end");
}
res.push(excalidrawElement);
if (startBoundElement) {
res.push(startBoundElement);
}
if (endBoundElement) {
res.push(endBoundElement);
}
} else { } else {
excalidrawElement = { excalidrawElement = {
...element, ...element,
@@ -708,9 +796,9 @@ export const convertToExcalidrawElements = (
? 100 ? 100
: 0), : 0),
} as ExcalidrawGenericElement; } as ExcalidrawGenericElement;
}
res.push(excalidrawElement); res.push(excalidrawElement);
} }
}
}); });
return res; return res;
}; };

View File

@@ -993,10 +993,8 @@ export const bindTextToContainer = (
let container; let container;
if (containerProps.type === "arrow") { if (containerProps.type === "arrow") {
container = newLinearElement({ container = newLinearElement({
//@ts-ignore width: containerProps.width || 300,
x: 0, height: containerProps.height || 24,
//@ts-ignore
y: 0,
//@ts-ignore //@ts-ignore
type: containerProps.type, type: containerProps.type,
//@ts-ignore, //@ts-ignore,
@@ -1011,8 +1009,6 @@ export const bindTextToContainer = (
} else { } else {
//@ts-ignore //@ts-ignore
container = newElement({ container = newElement({
x: 0,
y: 0,
...containerProps, ...containerProps,
}); });
} }