Type updates to support fixed binding for simple arrows

This commit is contained in:
Mark Tolmacs 2025-06-20 22:22:57 +02:00
parent 331790e9af
commit b696b7bf98
No known key found for this signature in database
5 changed files with 25 additions and 9 deletions

View File

@ -2356,16 +2356,18 @@ export const getGlobalFixedPointForBindableElement = (
}; };
export const getGlobalFixedPoints = ( export const getGlobalFixedPoints = (
arrow: ExcalidrawElbowArrowElement, arrow: ExcalidrawArrowElement,
elementsMap: ElementsMap, elementsMap: ElementsMap,
): [GlobalPoint, GlobalPoint] => { ): [GlobalPoint, GlobalPoint] => {
const startElement = const startElement =
arrow.startBinding && arrow.startBinding &&
isFixedPointBinding(arrow.startBinding) &&
(elementsMap.get(arrow.startBinding.elementId) as (elementsMap.get(arrow.startBinding.elementId) as
| ExcalidrawBindableElement | ExcalidrawBindableElement
| undefined); | undefined);
const endElement = const endElement =
arrow.endBinding && arrow.endBinding &&
isFixedPointBinding(arrow.endBinding) &&
(elementsMap.get(arrow.endBinding.elementId) as (elementsMap.get(arrow.endBinding.elementId) as
| ExcalidrawBindableElement | ExcalidrawBindableElement
| undefined); | undefined);

View File

@ -12,7 +12,7 @@ import { ShapeCache } from "./shape";
import { updateElbowArrowPoints } from "./elbowArrow"; import { updateElbowArrowPoints } from "./elbowArrow";
import { isElbowArrow } from "./typeChecks"; import { isElbowArrow, isFixedPointBinding } from "./typeChecks";
import type { import type {
ElementsMap, ElementsMap,
@ -54,8 +54,8 @@ export const mutateElement = <TElement extends Mutable<ExcalidrawElement>>(
(Object.keys(updates).length === 0 || // normalization case (Object.keys(updates).length === 0 || // normalization case
typeof points !== "undefined" || // repositioning typeof points !== "undefined" || // repositioning
typeof fixedSegments !== "undefined" || // segment fixing typeof fixedSegments !== "undefined" || // segment fixing
typeof startBinding !== "undefined" || isFixedPointBinding(startBinding) ||
typeof endBinding !== "undefined") // manual binding to element isFixedPointBinding(endBinding)) // manual binding to element
) { ) {
updates = { updates = {
...updates, ...updates,

View File

@ -323,8 +323,8 @@ export type ExcalidrawLinearElement = _ExcalidrawElementBase &
type: "line" | "arrow"; type: "line" | "arrow";
points: readonly LocalPoint[]; points: readonly LocalPoint[];
lastCommittedPoint: LocalPoint | null; lastCommittedPoint: LocalPoint | null;
startBinding: PointBinding | null; startBinding: FixedPointBinding | PointBinding | null;
endBinding: PointBinding | null; endBinding: FixedPointBinding | PointBinding | null;
startArrowhead: Arrowhead | null; startArrowhead: Arrowhead | null;
endArrowhead: Arrowhead | null; endArrowhead: Arrowhead | null;
}>; }>;
@ -351,9 +351,9 @@ export type ExcalidrawElbowArrowElement = Merge<
ExcalidrawArrowElement, ExcalidrawArrowElement,
{ {
elbowed: true; elbowed: true;
fixedSegments: readonly FixedSegment[] | null;
startBinding: FixedPointBinding | null; startBinding: FixedPointBinding | null;
endBinding: FixedPointBinding | null; endBinding: FixedPointBinding | null;
fixedSegments: readonly FixedSegment[] | null;
/** /**
* Marks that the 3rd point should be used as the 2nd point of the arrow in * Marks that the 3rd point should be used as the 2nd point of the arrow in
* order to temporarily hide the first segment of the arrow without losing * order to temporarily hide the first segment of the arrow without losing

View File

@ -27,6 +27,7 @@ import type {
ExcalidrawElbowArrowElement, ExcalidrawElbowArrowElement,
ExcalidrawFreeDrawElement, ExcalidrawFreeDrawElement,
ExcalidrawLinearElement, ExcalidrawLinearElement,
PointBinding,
} from "../src/types"; } from "../src/types";
unmountComponent(); unmountComponent();
@ -1023,8 +1024,20 @@ describe("multiple selection", () => {
1 - move[0] / selectionWidth, 1 - move[0] / selectionWidth,
1 - move[1] / selectionHeight, 1 - move[1] / selectionHeight,
); );
const leftArrowBinding = { ...leftBoundArrow.endBinding }; const leftArrowBinding: {
const rightArrowBinding = { ...rightBoundArrow.endBinding }; elementId: string;
gap?: number;
focus?: number;
} = {
...leftBoundArrow.endBinding,
} as PointBinding;
const rightArrowBinding: {
elementId: string;
gap?: number;
focus?: number;
} = {
...rightBoundArrow.endBinding,
} as PointBinding;
delete rightArrowBinding.gap; delete rightArrowBinding.gap;
UI.resize([rectangle, rightBoundArrow], "nw", move, { UI.resize([rectangle, rightBoundArrow], "nw", move, {

View File

@ -2,3 +2,4 @@ export * from "./export";
export * from "./withinBounds"; export * from "./withinBounds";
export * from "./bbox"; export * from "./bbox";
export { getCommonBounds } from "@excalidraw/element"; export { getCommonBounds } from "@excalidraw/element";
export * from "./visualdebug";