refactor: change movePoints pointUpdates type (#9499)
This commit is contained in:
parent
e058a08b33
commit
ff2ed5d26a
@ -73,3 +73,7 @@ export type AllPossibleKeys<T> = T extends any ? keyof T : never;
|
|||||||
export type DTO<T> = {
|
export type DTO<T> = {
|
||||||
[K in keyof T as T[K] extends Function ? never : K]: T[K];
|
[K in keyof T as T[K] extends Function ? never : K]: T[K];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MapEntry<M extends Map<any, any>> = M extends Map<infer K, infer V>
|
||||||
|
? [K, V]
|
||||||
|
: never;
|
||||||
|
@ -33,7 +33,7 @@ import type { LocalPoint, Radians } from "@excalidraw/math";
|
|||||||
|
|
||||||
import type { AppState } from "@excalidraw/excalidraw/types";
|
import type { AppState } from "@excalidraw/excalidraw/types";
|
||||||
|
|
||||||
import type { Mutable } from "@excalidraw/common/utility-types";
|
import type { MapEntry, Mutable } from "@excalidraw/common/utility-types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getCenterForBounds,
|
getCenterForBounds,
|
||||||
@ -84,6 +84,7 @@ import type {
|
|||||||
ExcalidrawElbowArrowElement,
|
ExcalidrawElbowArrowElement,
|
||||||
FixedPoint,
|
FixedPoint,
|
||||||
FixedPointBinding,
|
FixedPointBinding,
|
||||||
|
PointsPositionUpdates,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export type SuggestedBinding =
|
export type SuggestedBinding =
|
||||||
@ -801,28 +802,22 @@ export const updateBoundElements = (
|
|||||||
bindableElement,
|
bindableElement,
|
||||||
elementsMap,
|
elementsMap,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (point) {
|
if (point) {
|
||||||
return {
|
return [
|
||||||
index:
|
bindingProp === "startBinding" ? 0 : element.points.length - 1,
|
||||||
bindingProp === "startBinding" ? 0 : element.points.length - 1,
|
{ point },
|
||||||
point,
|
] as MapEntry<PointsPositionUpdates>;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
).filter(
|
).filter(
|
||||||
(
|
(update): update is MapEntry<PointsPositionUpdates> => update !== null,
|
||||||
update,
|
|
||||||
): update is NonNullable<{
|
|
||||||
index: number;
|
|
||||||
point: LocalPoint;
|
|
||||||
isDragging?: boolean;
|
|
||||||
}> => update !== null,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
LinearElementEditor.movePoints(element, scene, updates, {
|
LinearElementEditor.movePoints(element, scene, new Map(updates), {
|
||||||
...(changedElement.id === element.startBinding?.elementId
|
...(changedElement.id === element.startBinding?.elementId
|
||||||
? { startBinding: bindings.startBinding }
|
? { startBinding: bindings.startBinding }
|
||||||
: {}),
|
: {}),
|
||||||
|
@ -462,12 +462,18 @@ const createBindingArrow = (
|
|||||||
bindingArrow as OrderedExcalidrawElement,
|
bindingArrow as OrderedExcalidrawElement,
|
||||||
);
|
);
|
||||||
|
|
||||||
LinearElementEditor.movePoints(bindingArrow, scene, [
|
LinearElementEditor.movePoints(
|
||||||
{
|
bindingArrow,
|
||||||
index: 1,
|
scene,
|
||||||
point: bindingArrow.points[1],
|
new Map([
|
||||||
},
|
[
|
||||||
]);
|
1,
|
||||||
|
{
|
||||||
|
point: bindingArrow.points[1],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
const update = updateElbowArrowPoints(
|
const update = updateElbowArrowPoints(
|
||||||
bindingArrow,
|
bindingArrow,
|
||||||
|
@ -82,6 +82,7 @@ import type {
|
|||||||
FixedPointBinding,
|
FixedPointBinding,
|
||||||
FixedSegment,
|
FixedSegment,
|
||||||
ExcalidrawElbowArrowElement,
|
ExcalidrawElbowArrowElement,
|
||||||
|
PointsPositionUpdates,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
const editorMidPointsCache: {
|
const editorMidPointsCache: {
|
||||||
@ -306,16 +307,22 @@ export class LinearElementEditor {
|
|||||||
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
|
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
|
||||||
);
|
);
|
||||||
|
|
||||||
LinearElementEditor.movePoints(element, scene, [
|
LinearElementEditor.movePoints(
|
||||||
{
|
element,
|
||||||
index: selectedIndex,
|
scene,
|
||||||
point: pointFrom(
|
new Map([
|
||||||
width + referencePoint[0],
|
[
|
||||||
height + referencePoint[1],
|
selectedIndex,
|
||||||
),
|
{
|
||||||
isDragging: selectedIndex === lastClickedPoint,
|
point: pointFrom(
|
||||||
},
|
width + referencePoint[0],
|
||||||
]);
|
height + referencePoint[1],
|
||||||
|
),
|
||||||
|
isDragging: selectedIndex === lastClickedPoint,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
const newDraggingPointPosition = LinearElementEditor.createPointAt(
|
const newDraggingPointPosition = LinearElementEditor.createPointAt(
|
||||||
element,
|
element,
|
||||||
@ -331,26 +338,32 @@ export class LinearElementEditor {
|
|||||||
LinearElementEditor.movePoints(
|
LinearElementEditor.movePoints(
|
||||||
element,
|
element,
|
||||||
scene,
|
scene,
|
||||||
selectedPointsIndices.map((pointIndex) => {
|
new Map(
|
||||||
const newPointPosition: LocalPoint =
|
selectedPointsIndices.map((pointIndex) => {
|
||||||
pointIndex === lastClickedPoint
|
const newPointPosition: LocalPoint =
|
||||||
? LinearElementEditor.createPointAt(
|
pointIndex === lastClickedPoint
|
||||||
element,
|
? LinearElementEditor.createPointAt(
|
||||||
elementsMap,
|
element,
|
||||||
scenePointerX - linearElementEditor.pointerOffset.x,
|
elementsMap,
|
||||||
scenePointerY - linearElementEditor.pointerOffset.y,
|
scenePointerX - linearElementEditor.pointerOffset.x,
|
||||||
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
|
scenePointerY - linearElementEditor.pointerOffset.y,
|
||||||
)
|
event[KEYS.CTRL_OR_CMD]
|
||||||
: pointFrom(
|
? null
|
||||||
element.points[pointIndex][0] + deltaX,
|
: app.getEffectiveGridSize(),
|
||||||
element.points[pointIndex][1] + deltaY,
|
)
|
||||||
);
|
: pointFrom(
|
||||||
return {
|
element.points[pointIndex][0] + deltaX,
|
||||||
index: pointIndex,
|
element.points[pointIndex][1] + deltaY,
|
||||||
point: newPointPosition,
|
);
|
||||||
isDragging: pointIndex === lastClickedPoint,
|
return [
|
||||||
};
|
pointIndex,
|
||||||
}),
|
{
|
||||||
|
point: newPointPosition,
|
||||||
|
isDragging: pointIndex === lastClickedPoint,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,15 +464,21 @@ export class LinearElementEditor {
|
|||||||
selectedPoint === element.points.length - 1
|
selectedPoint === element.points.length - 1
|
||||||
) {
|
) {
|
||||||
if (isPathALoop(element.points, appState.zoom.value)) {
|
if (isPathALoop(element.points, appState.zoom.value)) {
|
||||||
LinearElementEditor.movePoints(element, scene, [
|
LinearElementEditor.movePoints(
|
||||||
{
|
element,
|
||||||
index: selectedPoint,
|
scene,
|
||||||
point:
|
new Map([
|
||||||
selectedPoint === 0
|
[
|
||||||
? element.points[element.points.length - 1]
|
selectedPoint,
|
||||||
: element.points[0],
|
{
|
||||||
},
|
point:
|
||||||
]);
|
selectedPoint === 0
|
||||||
|
? element.points[element.points.length - 1]
|
||||||
|
: element.points[0],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bindingElement = isBindingEnabled(appState)
|
const bindingElement = isBindingEnabled(appState)
|
||||||
@ -988,12 +1007,18 @@ export class LinearElementEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastPoint === lastUncommittedPoint) {
|
if (lastPoint === lastUncommittedPoint) {
|
||||||
LinearElementEditor.movePoints(element, app.scene, [
|
LinearElementEditor.movePoints(
|
||||||
{
|
element,
|
||||||
index: element.points.length - 1,
|
app.scene,
|
||||||
point: newPoint,
|
new Map([
|
||||||
},
|
[
|
||||||
]);
|
element.points.length - 1,
|
||||||
|
{
|
||||||
|
point: newPoint,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
LinearElementEditor.addPoints(element, app.scene, [{ point: newPoint }]);
|
LinearElementEditor.addPoints(element, app.scene, [{ point: newPoint }]);
|
||||||
}
|
}
|
||||||
@ -1227,12 +1252,16 @@ export class LinearElementEditor {
|
|||||||
// potentially expanding the bounding box
|
// potentially expanding the bounding box
|
||||||
if (pointAddedToEnd) {
|
if (pointAddedToEnd) {
|
||||||
const lastPoint = element.points[element.points.length - 1];
|
const lastPoint = element.points[element.points.length - 1];
|
||||||
LinearElementEditor.movePoints(element, scene, [
|
LinearElementEditor.movePoints(
|
||||||
{
|
element,
|
||||||
index: element.points.length - 1,
|
scene,
|
||||||
point: pointFrom(lastPoint[0] + 30, lastPoint[1] + 30),
|
new Map([
|
||||||
},
|
[
|
||||||
]);
|
element.points.length - 1,
|
||||||
|
{ point: pointFrom(lastPoint[0] + 30, lastPoint[1] + 30) },
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -1307,7 +1336,7 @@ export class LinearElementEditor {
|
|||||||
static movePoints(
|
static movePoints(
|
||||||
element: NonDeleted<ExcalidrawLinearElement>,
|
element: NonDeleted<ExcalidrawLinearElement>,
|
||||||
scene: Scene,
|
scene: Scene,
|
||||||
targetPoints: { index: number; point: LocalPoint; isDragging?: boolean }[],
|
pointUpdates: PointsPositionUpdates,
|
||||||
otherUpdates?: {
|
otherUpdates?: {
|
||||||
startBinding?: PointBinding | null;
|
startBinding?: PointBinding | null;
|
||||||
endBinding?: PointBinding | null;
|
endBinding?: PointBinding | null;
|
||||||
@ -1321,8 +1350,7 @@ export class LinearElementEditor {
|
|||||||
// offset it. We do the same with actual element.x/y position, so
|
// offset it. We do the same with actual element.x/y position, so
|
||||||
// this hacks are completely transparent to the user.
|
// this hacks are completely transparent to the user.
|
||||||
const [deltaX, deltaY] =
|
const [deltaX, deltaY] =
|
||||||
targetPoints.find(({ index }) => index === 0)?.point ??
|
pointUpdates.get(0)?.point ?? pointFrom<LocalPoint>(0, 0);
|
||||||
pointFrom<LocalPoint>(0, 0);
|
|
||||||
const [offsetX, offsetY] = pointFrom<LocalPoint>(
|
const [offsetX, offsetY] = pointFrom<LocalPoint>(
|
||||||
deltaX - points[0][0],
|
deltaX - points[0][0],
|
||||||
deltaY - points[0][1],
|
deltaY - points[0][1],
|
||||||
@ -1330,12 +1358,12 @@ export class LinearElementEditor {
|
|||||||
|
|
||||||
const nextPoints = isElbowArrow(element)
|
const nextPoints = isElbowArrow(element)
|
||||||
? [
|
? [
|
||||||
targetPoints.find((t) => t.index === 0)?.point ?? points[0],
|
pointUpdates.get(0)?.point ?? points[0],
|
||||||
targetPoints.find((t) => t.index === points.length - 1)?.point ??
|
pointUpdates.get(points.length - 1)?.point ??
|
||||||
points[points.length - 1],
|
points[points.length - 1],
|
||||||
]
|
]
|
||||||
: points.map((p, idx) => {
|
: points.map((p, idx) => {
|
||||||
const current = targetPoints.find((t) => t.index === idx)?.point ?? p;
|
const current = pointUpdates.get(idx)?.point ?? p;
|
||||||
|
|
||||||
return pointFrom<LocalPoint>(
|
return pointFrom<LocalPoint>(
|
||||||
current[0] - offsetX,
|
current[0] - offsetX,
|
||||||
@ -1351,11 +1379,7 @@ export class LinearElementEditor {
|
|||||||
offsetY,
|
offsetY,
|
||||||
otherUpdates,
|
otherUpdates,
|
||||||
{
|
{
|
||||||
isDragging: targetPoints.reduce(
|
isDragging: Array.from(pointUpdates.values()).some((t) => t.isDragging),
|
||||||
(dragging, targetPoint): boolean =>
|
|
||||||
dragging || targetPoint.isDragging === true,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -296,6 +296,11 @@ export type FixedPointBinding = Merge<
|
|||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
export type PointsPositionUpdates = Map<
|
||||||
|
number,
|
||||||
|
{ point: LocalPoint; isDragging?: boolean }
|
||||||
|
>;
|
||||||
|
|
||||||
export type Arrowhead =
|
export type Arrowhead =
|
||||||
| "arrow"
|
| "arrow"
|
||||||
| "bar"
|
| "bar"
|
||||||
|
@ -1384,19 +1384,30 @@ describe("Test Linear Elements", () => {
|
|||||||
const [origStartX, origStartY] = [line.x, line.y];
|
const [origStartX, origStartY] = [line.x, line.y];
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
LinearElementEditor.movePoints(line, h.app.scene, [
|
LinearElementEditor.movePoints(
|
||||||
{
|
line,
|
||||||
index: 0,
|
h.app.scene,
|
||||||
point: pointFrom(line.points[0][0] + 10, line.points[0][1] + 10),
|
new Map([
|
||||||
},
|
[
|
||||||
{
|
0,
|
||||||
index: line.points.length - 1,
|
{
|
||||||
point: pointFrom(
|
point: pointFrom(
|
||||||
line.points[line.points.length - 1][0] - 10,
|
line.points[0][0] + 10,
|
||||||
line.points[line.points.length - 1][1] - 10,
|
line.points[0][1] + 10,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]);
|
],
|
||||||
|
[
|
||||||
|
line.points.length - 1,
|
||||||
|
{
|
||||||
|
point: pointFrom(
|
||||||
|
line.points[line.points.length - 1][0] - 10,
|
||||||
|
line.points[line.points.length - 1][1] - 10,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
expect(line.x).toBe(origStartX + 10);
|
expect(line.x).toBe(origStartX + 10);
|
||||||
expect(line.y).toBe(origStartY + 10);
|
expect(line.y).toBe(origStartY + 10);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user