Implement line editing (#1616)

* 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>
This commit is contained in:
David Luzar 2020-06-01 11:35:44 +02:00 committed by GitHub
parent db316f32e0
commit 14a66956d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 1129 additions and 76 deletions

View file

@ -1,8 +1,13 @@
import {
ExcalidrawElement,
NonDeletedExcalidrawElement,
NonDeleted,
} from "../element/types";
import { getNonDeletedElements } from "../element";
import {
getNonDeletedElements,
isNonDeletedElement,
getElementMap,
} from "../element";
export interface SceneStateCallback {
(): void;
@ -13,22 +18,40 @@ export interface SceneStateCallbackRemover {
}
class GlobalScene {
private nonDeletedElements: readonly NonDeletedExcalidrawElement[] = [];
private callbacks: Set<SceneStateCallback> = new Set();
constructor(private _elements: readonly ExcalidrawElement[] = []) {}
private nonDeletedElements: readonly NonDeletedExcalidrawElement[] = [];
private elements: readonly ExcalidrawElement[] = [];
private elementsMap: {
[id: string]: ExcalidrawElement;
} = {};
getElementsIncludingDeleted() {
return this._elements;
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.nonDeletedElements = getNonDeletedElements(this._elements);
this.elements = nextElements;
this.elementsMap = getElementMap(nextElements);
this.nonDeletedElements = getNonDeletedElements(this.elements);
this.informMutation();
}