mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-04-14 16:40:58 -04:00
* implement line editing * line editing with rotation * ensure adding new points is disabled on point dragging * fix hotkey replacement * don't paint bounding box when creating new multipoint * tweak points style, account for zoom and z-index * don't persist editingLinearElement to localStorage * don't mutate on noop points updates * account for rotation when adding new point * ensure clicking on points doesn't deselect element * tweak history handling around editingline element * update snapshots * refactor pointerMove handling * factor out point dragging * factor out pointerDown * improve positioning with rotation * revert to use roughjs for calculating points bounds * migrate from storing editingLinearElement.element to id * make GlobalScene.getElement into O(1) * use Alt for adding new points * fix adding and deleting a point with rotation * disable resize handlers & bounding box on line edit Co-authored-by: daishi <daishi@axlight.com>
80 lines
1.8 KiB
TypeScript
80 lines
1.8 KiB
TypeScript
import {
|
|
ExcalidrawElement,
|
|
NonDeletedExcalidrawElement,
|
|
NonDeleted,
|
|
} from "../element/types";
|
|
import {
|
|
getNonDeletedElements,
|
|
isNonDeletedElement,
|
|
getElementMap,
|
|
} from "../element";
|
|
|
|
export interface SceneStateCallback {
|
|
(): void;
|
|
}
|
|
|
|
export interface SceneStateCallbackRemover {
|
|
(): void;
|
|
}
|
|
|
|
class GlobalScene {
|
|
private callbacks: Set<SceneStateCallback> = new Set();
|
|
|
|
private nonDeletedElements: readonly NonDeletedExcalidrawElement[] = [];
|
|
private elements: readonly ExcalidrawElement[] = [];
|
|
private elementsMap: {
|
|
[id: string]: ExcalidrawElement;
|
|
} = {};
|
|
|
|
getElementsIncludingDeleted() {
|
|
return this.elements;
|
|
}
|
|
|
|
getElements(): readonly NonDeletedExcalidrawElement[] {
|
|
return this.nonDeletedElements;
|
|
}
|
|
|
|
getElement(id: ExcalidrawElement["id"]): ExcalidrawElement | null {
|
|
return this.elementsMap[id] || null;
|
|
}
|
|
|
|
getNonDeletedElement(
|
|
id: ExcalidrawElement["id"],
|
|
): NonDeleted<ExcalidrawElement> | null {
|
|
const element = this.getElement(id);
|
|
if (element && isNonDeletedElement(element)) {
|
|
return element;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
replaceAllElements(nextElements: readonly ExcalidrawElement[]) {
|
|
this.elements = nextElements;
|
|
this.elementsMap = getElementMap(nextElements);
|
|
this.nonDeletedElements = getNonDeletedElements(this.elements);
|
|
this.informMutation();
|
|
}
|
|
|
|
informMutation() {
|
|
for (const callback of Array.from(this.callbacks)) {
|
|
callback();
|
|
}
|
|
}
|
|
|
|
addCallback(cb: SceneStateCallback): SceneStateCallbackRemover {
|
|
if (this.callbacks.has(cb)) {
|
|
throw new Error();
|
|
}
|
|
|
|
this.callbacks.add(cb);
|
|
|
|
return () => {
|
|
if (!this.callbacks.has(cb)) {
|
|
throw new Error();
|
|
}
|
|
this.callbacks.delete(cb);
|
|
};
|
|
}
|
|
}
|
|
|
|
export const globalSceneState = new GlobalScene();
|