excalidraw/src/scene/selection.ts
Jed Fox c6a0cfc2b1
Refactor (#862)
* Initial factoring out of parts of the LayerUI component

2360 → 2224 LOC

* Create a Section component

* Break up src/index.tsx

* Refactor actions to reduce duplication, fix CSS

Also consolidate icons

* Move scene/data.ts to its own directory

* Fix accidental reverts, banish further single-character variables

* ACTIVE_ELEM_COLOR → ACTIVE_ELEMENT_COLOR

* Further refactoring the icons file

* Log all errors

* Pointer Event polyfill to make the tests work

* add test hooks & fix tests

Co-authored-by: dwelle <luzar.david@gmail.com>
2020-03-07 16:20:38 +01:00

92 lines
2.4 KiB
TypeScript

import { ExcalidrawElement } from "../element/types";
import { getElementAbsoluteCoords } from "../element";
export function getElementsWithinSelection(
elements: readonly ExcalidrawElement[],
selection: ExcalidrawElement,
) {
const [
selectionX1,
selectionY1,
selectionX2,
selectionY2,
] = getElementAbsoluteCoords(selection);
return elements.filter(element => {
const [
elementX1,
elementY1,
elementX2,
elementY2,
] = getElementAbsoluteCoords(element);
return (
element.type !== "selection" &&
selectionX1 <= elementX1 &&
selectionY1 <= elementY1 &&
selectionX2 >= elementX2 &&
selectionY2 >= elementY2
);
});
}
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[]) {
return elements.filter(el => !el.isSelected);
}
export function getSelectedIndices(elements: readonly ExcalidrawElement[]) {
const selectedIndices: number[] = [];
elements.forEach((element, index) => {
if (element.isSelected) {
selectedIndices.push(index);
}
});
return selectedIndices;
}
export function isSomeElementSelected(
elements: readonly ExcalidrawElement[],
): boolean {
return elements.some(element => element.isSelected);
}
/**
* Returns common attribute (picked by `getAttribute` callback) of selected
* elements. If elements don't share the same value, returns `null`.
*/
export function getCommonAttributeOfSelectedElements<T>(
elements: readonly ExcalidrawElement[],
getAttribute: (element: ExcalidrawElement) => T,
): T | null {
const attributes = Array.from(
new Set(
getSelectedElements(elements).map(element => getAttribute(element)),
),
);
return attributes.length === 1 ? attributes[0] : null;
}
export function getSelectedElements(
elements: readonly ExcalidrawElement[],
): readonly ExcalidrawElement[] {
return elements.filter(element => element.isSelected);
}
export function getTargetElement(
editingElement: ExcalidrawElement | null,
elements: readonly ExcalidrawElement[],
) {
return editingElement ? [editingElement] : getSelectedElements(elements);
}