mirror of
https://github.com/excalidraw/excalidraw.git
synced 2024-11-10 11:35:52 +01:00
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,
|
||||
} from "../constants";
|
||||
import { getDefaultAppState } from "../appState";
|
||||
import { LinearElementEditor } from "../element/linearElementEditor";
|
||||
|
||||
type RestoredAppState = Omit<
|
||||
AppState,
|
||||
@ -49,14 +50,18 @@ const getFontFamilyByName = (fontFamilyName: string): FontFamily => {
|
||||
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>,
|
||||
extra: Omit<Required<T>, keyof ExcalidrawElement> & {
|
||||
type?: ExcalidrawElement["type"];
|
||||
},
|
||||
extra: Pick<T, K>,
|
||||
): T => {
|
||||
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
|
||||
// newly added elements
|
||||
version: element.version || 1,
|
||||
@ -69,8 +74,8 @@ const restoreElementWithProperties = <T extends ExcalidrawElement>(
|
||||
roughness: element.roughness ?? 1,
|
||||
opacity: element.opacity == null ? 100 : element.opacity,
|
||||
angle: element.angle || 0,
|
||||
x: element.x || 0,
|
||||
y: element.y || 0,
|
||||
x: (extra as Partial<T>).x ?? element.x ?? 0,
|
||||
y: (extra as Partial<T>).y ?? element.y ?? 0,
|
||||
strokeColor: element.strokeColor,
|
||||
backgroundColor: element.backgroundColor,
|
||||
width: element.width || 0,
|
||||
@ -131,6 +136,20 @@ const restoreElement = (
|
||||
endArrowhead = element.type === "arrow" ? "arrow" : null,
|
||||
} = 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, {
|
||||
type:
|
||||
(element.type as ExcalidrawElement["type"] | "draw") === "draw"
|
||||
@ -138,17 +157,12 @@ const restoreElement = (
|
||||
: element.type,
|
||||
startBinding: element.startBinding,
|
||||
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,
|
||||
startArrowhead,
|
||||
endArrowhead,
|
||||
points,
|
||||
x,
|
||||
y,
|
||||
});
|
||||
}
|
||||
// generic elements
|
||||
|
@ -415,26 +415,31 @@ export class LinearElementEditor {
|
||||
return [rotatedX - element.x, rotatedY - element.y];
|
||||
}
|
||||
|
||||
// element-mutating methods
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 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 offsetX = points[0][0];
|
||||
const offsetY = points[0][1];
|
||||
|
||||
mutateElement(element, {
|
||||
return {
|
||||
points: points.map((point, _idx) => {
|
||||
return [point[0] - offsetX, point[1] - offsetY] as const;
|
||||
}),
|
||||
x: element.x + offsetX,
|
||||
y: element.y + offsetY,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// element-mutating methods
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static normalizePoints(element: NonDeleted<ExcalidrawLinearElement>) {
|
||||
mutateElement(element, LinearElementEditor.getNormalizedPoints(element));
|
||||
}
|
||||
|
||||
static movePointByOffset(
|
||||
|
Loading…
Reference in New Issue
Block a user