Add NonDeleted<ExcalidrawElement> (#1068)

* add NonDeleted

* make test:all script run tests without prompt

* rename helper

* replace with helper

* make element contructors return nonDeleted elements

* cache filtered elements where appliacable for better perf

* rename manager element getter

* remove unnecessary assertion

* fix test

* make element types in resizeElement into nonDeleted

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
Pete Hunt 2020-04-08 09:49:52 -07:00 committed by GitHub
parent c714c778ab
commit df0613d8ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 260 additions and 189 deletions

View file

@ -1,6 +1,6 @@
import { distanceBetweenPointAndSegment } from "../math";
import { ExcalidrawElement } from "./types";
import { NonDeletedExcalidrawElement } from "./types";
import { getDiamondPoints, getElementAbsoluteCoords } from "./bounds";
import { Point } from "../types";
@ -11,7 +11,7 @@ import { isLinearElement } from "./typeChecks";
import { rotate } from "../math";
function isElementDraggableFromInside(
element: ExcalidrawElement,
element: NonDeletedExcalidrawElement,
appState: AppState,
): boolean {
return (
@ -21,7 +21,7 @@ function isElementDraggableFromInside(
}
export function hitTest(
element: ExcalidrawElement,
element: NonDeletedExcalidrawElement,
appState: AppState,
x: number,
y: number,

View file

@ -1,4 +1,4 @@
import { ExcalidrawElement } from "./types";
import { ExcalidrawElement, NonDeletedExcalidrawElement } from "./types";
import { isInvisiblySmallElement } from "./sizeHelpers";
export {
@ -63,6 +63,9 @@ export function getDrawingVersion(elements: readonly ExcalidrawElement[]) {
return elements.reduce((acc, el) => acc + el.version, 0);
}
export function hasNonDeletedElements(elements: readonly ExcalidrawElement[]) {
return elements.some((element) => !element.isDeleted);
export function getNonDeletedElements(elements: readonly ExcalidrawElement[]) {
return (
elements.filter((element) => !element.isDeleted) as
readonly NonDeletedExcalidrawElement[]
);
}

View file

@ -3,6 +3,7 @@ import {
ExcalidrawTextElement,
ExcalidrawLinearElement,
ExcalidrawGenericElement,
NonDeleted,
} from "../element/types";
import { measureText } from "../utils";
import { randomInteger, randomId } from "../random";
@ -56,7 +57,7 @@ function _newElementBase<T extends ExcalidrawElement>(
seed: rest.seed ?? randomInteger(),
version: rest.version || 1,
versionNonce: rest.versionNonce ?? 0,
isDeleted: rest.isDeleted ?? false,
isDeleted: false as false,
};
}
@ -64,7 +65,7 @@ export function newElement(
opts: {
type: ExcalidrawGenericElement["type"];
} & ElementConstructorOpts,
): ExcalidrawGenericElement {
): NonDeleted<ExcalidrawGenericElement> {
return _newElementBase<ExcalidrawGenericElement>(opts.type, opts);
}
@ -73,13 +74,12 @@ export function newTextElement(
text: string;
font: string;
} & ElementConstructorOpts,
): ExcalidrawTextElement {
): NonDeleted<ExcalidrawTextElement> {
const { text, font } = opts;
const metrics = measureText(text, font);
const textElement = newElementWith(
{
..._newElementBase<ExcalidrawTextElement>("text", opts),
isDeleted: false,
text: text,
font: font,
// Center the text
@ -100,7 +100,7 @@ export function newLinearElement(
type: ExcalidrawLinearElement["type"];
lastCommittedPoint?: ExcalidrawLinearElement["lastCommittedPoint"];
} & ElementConstructorOpts,
): ExcalidrawLinearElement {
): NonDeleted<ExcalidrawLinearElement> {
return {
..._newElementBase<ExcalidrawLinearElement>(opts.type, opts),
points: [],

View file

@ -3,7 +3,11 @@ import { SHIFT_LOCKING_ANGLE } from "../constants";
import { getSelectedElements, globalSceneState } from "../scene";
import { rescalePoints } from "../points";
import { rotate, adjustXYWithRotation } from "../math";
import { ExcalidrawElement, ExcalidrawLinearElement } from "./types";
import {
ExcalidrawLinearElement,
NonDeletedExcalidrawElement,
NonDeleted,
} from "./types";
import { getElementAbsoluteCoords, getCommonBounds } from "./bounds";
import { isLinearElement } from "./typeChecks";
import { mutateElement } from "./mutateElement";
@ -17,7 +21,7 @@ import {
type ResizeTestType = ReturnType<typeof resizeTest>;
export type ResizeArrowFnType = (
element: ExcalidrawLinearElement,
element: NonDeleted<ExcalidrawLinearElement>,
pointIndex: number,
deltaX: number,
deltaY: number,
@ -27,13 +31,13 @@ export type ResizeArrowFnType = (
) => void;
const arrowResizeOrigin: ResizeArrowFnType = (
element: ExcalidrawLinearElement,
pointIndex: number,
deltaX: number,
deltaY: number,
pointerX: number,
pointerY: number,
perfect: boolean,
element,
pointIndex,
deltaX,
deltaY,
pointerX,
pointerY,
perfect,
) => {
const [px, py] = element.points[pointIndex];
let x = element.x + deltaX;
@ -63,13 +67,13 @@ const arrowResizeOrigin: ResizeArrowFnType = (
};
const arrowResizeEnd: ResizeArrowFnType = (
element: ExcalidrawLinearElement,
pointIndex: number,
deltaX: number,
deltaY: number,
pointerX: number,
pointerY: number,
perfect: boolean,
element,
pointIndex,
deltaX,
deltaY,
pointerX,
pointerY,
perfect,
) => {
const [px, py] = element.points[pointIndex];
if (perfect) {
@ -110,7 +114,7 @@ export function resizeElements(
isRotating: resizeHandle === "rotation",
});
const selectedElements = getSelectedElements(
globalSceneState.getAllElements(),
globalSceneState.getElements(),
appState,
);
if (selectedElements.length === 1) {
@ -451,7 +455,7 @@ export function resizeElements(
}
export function canResizeMutlipleElements(
elements: readonly ExcalidrawElement[],
elements: readonly NonDeletedExcalidrawElement[],
) {
return elements.every((element) =>
["rectangle", "diamond", "ellipse"].includes(element.type),

View file

@ -1,4 +1,8 @@
import { ExcalidrawElement, PointerType } from "./types";
import {
ExcalidrawElement,
PointerType,
NonDeletedExcalidrawElement,
} from "./types";
import {
OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
@ -24,7 +28,7 @@ function isInHandlerRect(
}
export function resizeTest(
element: ExcalidrawElement,
element: NonDeletedExcalidrawElement,
appState: AppState,
x: number,
y: number,
@ -66,7 +70,7 @@ export function resizeTest(
}
export function getElementWithResizeHandler(
elements: readonly ExcalidrawElement[],
elements: readonly NonDeletedExcalidrawElement[],
appState: AppState,
{ x, y }: { x: number; y: number },
zoom: number,
@ -78,7 +82,7 @@ export function getElementWithResizeHandler(
}
const resizeHandle = resizeTest(element, appState, x, y, zoom, pointerType);
return resizeHandle ? { element, resizeHandle } : null;
}, null as { element: ExcalidrawElement; resizeHandle: ReturnType<typeof resizeTest> } | null);
}, null as { element: NonDeletedExcalidrawElement; resizeHandle: ReturnType<typeof resizeTest> } | null);
}
export function getResizeHandlerFromCoords(

View file

@ -1,10 +1,10 @@
import { AppState } from "../types";
import { ExcalidrawElement } from "./types";
import { NonDeletedExcalidrawElement } from "./types";
import { getSelectedElements } from "../scene";
export const showSelectedShapeActions = (
appState: AppState,
elements: readonly ExcalidrawElement[],
elements: readonly NonDeletedExcalidrawElement[],
) =>
Boolean(
appState.editingElement ||

View file

@ -33,6 +33,12 @@ export type ExcalidrawElement =
| ExcalidrawTextElement
| ExcalidrawLinearElement;
export type NonDeleted<TElement extends ExcalidrawElement> = TElement & {
isDeleted: false;
};
export type NonDeletedExcalidrawElement = NonDeleted<ExcalidrawElement>;
export type ExcalidrawTextElement = _ExcalidrawElementBase &
Readonly<{
type: "text";