fix: normalize linear element points on restore (#3633)
This commit is contained in:
parent
d201d0be1b
commit
0bbb4535cf
@ -15,6 +15,7 @@ import {
|
|||||||
DEFAULT_VERTICAL_ALIGN,
|
DEFAULT_VERTICAL_ALIGN,
|
||||||
} from "../constants";
|
} from "../constants";
|
||||||
import { getDefaultAppState } from "../appState";
|
import { getDefaultAppState } from "../appState";
|
||||||
|
import { LinearElementEditor } from "../element/linearElementEditor";
|
||||||
|
|
||||||
type RestoredAppState = Omit<
|
type RestoredAppState = Omit<
|
||||||
AppState,
|
AppState,
|
||||||
@ -49,14 +50,18 @@ const getFontFamilyByName = (fontFamilyName: string): FontFamily => {
|
|||||||
return DEFAULT_FONT_FAMILY;
|
return DEFAULT_FONT_FAMILY;
|
||||||
};
|
};
|
||||||
|
|
||||||
const restoreElementWithProperties = <T extends ExcalidrawElement>(
|
const restoreElementWithProperties = <
|
||||||
|
T extends ExcalidrawElement,
|
||||||
|
K extends keyof Omit<
|
||||||
|
Required<T>,
|
||||||
|
Exclude<keyof ExcalidrawElement, "type" | "x" | "y">
|
||||||
|
>
|
||||||
|
>(
|
||||||
element: Required<T>,
|
element: Required<T>,
|
||||||
extra: Omit<Required<T>, keyof ExcalidrawElement> & {
|
extra: Pick<T, K>,
|
||||||
type?: ExcalidrawElement["type"];
|
|
||||||
},
|
|
||||||
): T => {
|
): T => {
|
||||||
const base: Pick<T, keyof ExcalidrawElement> = {
|
const base: Pick<T, keyof ExcalidrawElement> = {
|
||||||
type: extra.type || element.type,
|
type: (extra as Partial<T>).type || element.type,
|
||||||
// all elements must have version > 0 so getSceneVersion() will pick up
|
// all elements must have version > 0 so getSceneVersion() will pick up
|
||||||
// newly added elements
|
// newly added elements
|
||||||
version: element.version || 1,
|
version: element.version || 1,
|
||||||
@ -69,8 +74,8 @@ const restoreElementWithProperties = <T extends ExcalidrawElement>(
|
|||||||
roughness: element.roughness ?? 1,
|
roughness: element.roughness ?? 1,
|
||||||
opacity: element.opacity == null ? 100 : element.opacity,
|
opacity: element.opacity == null ? 100 : element.opacity,
|
||||||
angle: element.angle || 0,
|
angle: element.angle || 0,
|
||||||
x: element.x || 0,
|
x: (extra as Partial<T>).x ?? element.x ?? 0,
|
||||||
y: element.y || 0,
|
y: (extra as Partial<T>).y ?? element.y ?? 0,
|
||||||
strokeColor: element.strokeColor,
|
strokeColor: element.strokeColor,
|
||||||
backgroundColor: element.backgroundColor,
|
backgroundColor: element.backgroundColor,
|
||||||
width: element.width || 0,
|
width: element.width || 0,
|
||||||
@ -131,6 +136,20 @@ const restoreElement = (
|
|||||||
endArrowhead = element.type === "arrow" ? "arrow" : null,
|
endArrowhead = element.type === "arrow" ? "arrow" : null,
|
||||||
} = element;
|
} = element;
|
||||||
|
|
||||||
|
let x = element.x;
|
||||||
|
let y = element.y;
|
||||||
|
let points = // migrate old arrow model to new one
|
||||||
|
!Array.isArray(element.points) || element.points.length < 2
|
||||||
|
? [
|
||||||
|
[0, 0],
|
||||||
|
[element.width, element.height],
|
||||||
|
]
|
||||||
|
: element.points;
|
||||||
|
|
||||||
|
if (points[0][0] !== 0 || points[0][1] !== 0) {
|
||||||
|
({ points, x, y } = LinearElementEditor.getNormalizedPoints(element));
|
||||||
|
}
|
||||||
|
|
||||||
return restoreElementWithProperties(element, {
|
return restoreElementWithProperties(element, {
|
||||||
type:
|
type:
|
||||||
(element.type as ExcalidrawElement["type"] | "draw") === "draw"
|
(element.type as ExcalidrawElement["type"] | "draw") === "draw"
|
||||||
@ -138,17 +157,12 @@ const restoreElement = (
|
|||||||
: element.type,
|
: element.type,
|
||||||
startBinding: element.startBinding,
|
startBinding: element.startBinding,
|
||||||
endBinding: element.endBinding,
|
endBinding: element.endBinding,
|
||||||
points:
|
|
||||||
// migrate old arrow model to new one
|
|
||||||
!Array.isArray(element.points) || element.points.length < 2
|
|
||||||
? [
|
|
||||||
[0, 0],
|
|
||||||
[element.width, element.height],
|
|
||||||
]
|
|
||||||
: element.points,
|
|
||||||
lastCommittedPoint: null,
|
lastCommittedPoint: null,
|
||||||
startArrowhead,
|
startArrowhead,
|
||||||
endArrowhead,
|
endArrowhead,
|
||||||
|
points,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// generic elements
|
// generic elements
|
||||||
|
@ -415,26 +415,31 @@ export class LinearElementEditor {
|
|||||||
return [rotatedX - element.x, rotatedY - element.y];
|
return [rotatedX - element.x, rotatedY - element.y];
|
||||||
}
|
}
|
||||||
|
|
||||||
// element-mutating methods
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalizes line points so that the start point is at [0,0]. This is
|
* Normalizes line points so that the start point is at [0,0]. This is
|
||||||
* expected in various parts of the codebase.
|
* expected in various parts of the codebase. Also returns new x/y to account
|
||||||
|
* for the potential normalization.
|
||||||
*/
|
*/
|
||||||
static normalizePoints(element: NonDeleted<ExcalidrawLinearElement>) {
|
static getNormalizedPoints(element: ExcalidrawLinearElement) {
|
||||||
const { points } = element;
|
const { points } = element;
|
||||||
|
|
||||||
const offsetX = points[0][0];
|
const offsetX = points[0][0];
|
||||||
const offsetY = points[0][1];
|
const offsetY = points[0][1];
|
||||||
|
|
||||||
mutateElement(element, {
|
return {
|
||||||
points: points.map((point, _idx) => {
|
points: points.map((point, _idx) => {
|
||||||
return [point[0] - offsetX, point[1] - offsetY] as const;
|
return [point[0] - offsetX, point[1] - offsetY] as const;
|
||||||
}),
|
}),
|
||||||
x: element.x + offsetX,
|
x: element.x + offsetX,
|
||||||
y: element.y + offsetY,
|
y: element.y + offsetY,
|
||||||
});
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// element-mutating methods
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static normalizePoints(element: NonDeleted<ExcalidrawLinearElement>) {
|
||||||
|
mutateElement(element, LinearElementEditor.getNormalizedPoints(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
static movePointByOffset(
|
static movePointByOffset(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user