mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Refactor ExcalidrawElement (#874)
* Get rid of isSelected, canvas, canvasZoom, canvasOffsetX and canvasOffsetY on ExcalidrawElement. * Fix most unit tests. Fix cmd a. Fix alt drag * Focus on paste * shift select should include previously selected items * Fix last test * Move this.shape out of ExcalidrawElement and into a WeakMap
This commit is contained in:
parent
8ecb4201db
commit
ccbbdb75a6
39 changed files with 416 additions and 306 deletions
|
@ -1,6 +1,7 @@
|
|||
import { ExcalidrawElement } from "../element/types";
|
||||
|
||||
import { getElementAbsoluteCoords, hitTest } from "../element";
|
||||
import { AppState } from "../types";
|
||||
|
||||
export const hasBackground = (type: string) =>
|
||||
type === "rectangle" || type === "ellipse" || type === "diamond";
|
||||
|
@ -16,6 +17,7 @@ export const hasText = (type: string) => type === "text";
|
|||
|
||||
export function getElementAtPosition(
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
x: number,
|
||||
y: number,
|
||||
zoom: number,
|
||||
|
@ -23,7 +25,7 @@ export function getElementAtPosition(
|
|||
let hitElement = null;
|
||||
// We need to to hit testing from front (end of the array) to back (beginning of the array)
|
||||
for (let i = elements.length - 1; i >= 0; --i) {
|
||||
if (hitTest(elements[i], x, y, zoom)) {
|
||||
if (hitTest(elements[i], appState, x, y, zoom)) {
|
||||
hitElement = elements[i];
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,11 @@ import { getCommonBounds } from "../element/bounds";
|
|||
import { renderScene, renderSceneToSvg } from "../renderer/renderScene";
|
||||
import { distance, SVG_NS } from "../utils";
|
||||
import { normalizeScroll } from "./scroll";
|
||||
import { AppState } from "../types";
|
||||
|
||||
export function exportToCanvas(
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
{
|
||||
exportBackground,
|
||||
exportPadding = 10,
|
||||
|
@ -38,6 +40,7 @@ export function exportToCanvas(
|
|||
|
||||
renderScene(
|
||||
elements,
|
||||
appState,
|
||||
null,
|
||||
rough.canvas(tempCanvas),
|
||||
tempCanvas,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
export { isOverScrollBars } from "./scrollbars";
|
||||
export {
|
||||
clearSelection,
|
||||
getSelectedIndices,
|
||||
deleteSelectedElements,
|
||||
isSomeElementSelected,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { ExcalidrawElement } from "../element/types";
|
||||
import { getElementAbsoluteCoords } from "../element";
|
||||
import { AppState } from "../types";
|
||||
|
||||
export function getElementsWithinSelection(
|
||||
elements: readonly ExcalidrawElement[],
|
||||
|
@ -29,26 +30,20 @@ export function getElementsWithinSelection(
|
|||
});
|
||||
}
|
||||
|
||||
export function clearSelection(elements: readonly ExcalidrawElement[]) {
|
||||
let someWasSelected = false;
|
||||
elements.forEach(element => {
|
||||
if (element.isSelected) {
|
||||
someWasSelected = true;
|
||||
element.isSelected = false;
|
||||
}
|
||||
});
|
||||
|
||||
return someWasSelected ? elements.slice() : elements;
|
||||
export function deleteSelectedElements(
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
) {
|
||||
return elements.filter(el => !appState.selectedElementIds[el.id]);
|
||||
}
|
||||
|
||||
export function deleteSelectedElements(elements: readonly ExcalidrawElement[]) {
|
||||
return elements.filter(el => !el.isSelected);
|
||||
}
|
||||
|
||||
export function getSelectedIndices(elements: readonly ExcalidrawElement[]) {
|
||||
export function getSelectedIndices(
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
) {
|
||||
const selectedIndices: number[] = [];
|
||||
elements.forEach((element, index) => {
|
||||
if (element.isSelected) {
|
||||
if (appState.selectedElementIds[element.id]) {
|
||||
selectedIndices.push(index);
|
||||
}
|
||||
});
|
||||
|
@ -57,8 +52,9 @@ export function getSelectedIndices(elements: readonly ExcalidrawElement[]) {
|
|||
|
||||
export function isSomeElementSelected(
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
): boolean {
|
||||
return elements.some(element => element.isSelected);
|
||||
return elements.some(element => appState.selectedElementIds[element.id]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,11 +63,14 @@ export function isSomeElementSelected(
|
|||
*/
|
||||
export function getCommonAttributeOfSelectedElements<T>(
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
getAttribute: (element: ExcalidrawElement) => T,
|
||||
): T | null {
|
||||
const attributes = Array.from(
|
||||
new Set(
|
||||
getSelectedElements(elements).map(element => getAttribute(element)),
|
||||
getSelectedElements(elements, appState).map(element =>
|
||||
getAttribute(element),
|
||||
),
|
||||
),
|
||||
);
|
||||
return attributes.length === 1 ? attributes[0] : null;
|
||||
|
@ -79,13 +78,16 @@ export function getCommonAttributeOfSelectedElements<T>(
|
|||
|
||||
export function getSelectedElements(
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
): readonly ExcalidrawElement[] {
|
||||
return elements.filter(element => element.isSelected);
|
||||
return elements.filter(element => appState.selectedElementIds[element.id]);
|
||||
}
|
||||
|
||||
export function getTargetElement(
|
||||
editingElement: ExcalidrawElement | null,
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
) {
|
||||
return editingElement ? [editingElement] : getSelectedElements(elements);
|
||||
return appState.editingElement
|
||||
? [appState.editingElement]
|
||||
: getSelectedElements(elements, appState);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue