2020-01-06 20:24:54 +04:00
|
|
|
import { ExcalidrawElement } from "../element/types";
|
2020-01-07 19:04:52 +04:00
|
|
|
import { getElementAbsoluteCoords } from "../element";
|
2020-01-06 20:24:54 +04:00
|
|
|
|
2020-01-13 04:32:25 +05:00
|
|
|
export function getElementsWithinSelection(
|
2020-01-09 19:22:04 +04:00
|
|
|
elements: readonly ExcalidrawElement[],
|
2020-01-24 12:04:54 +02:00
|
|
|
selection: ExcalidrawElement,
|
2020-01-06 20:24:54 +04:00
|
|
|
) {
|
2020-01-07 19:04:52 +04:00
|
|
|
const [
|
|
|
|
selectionX1,
|
|
|
|
selectionY1,
|
|
|
|
selectionX2,
|
2020-01-24 12:04:54 +02:00
|
|
|
selectionY2,
|
2020-01-07 19:04:52 +04:00
|
|
|
] = getElementAbsoluteCoords(selection);
|
2020-01-13 04:32:25 +05:00
|
|
|
return elements.filter(element => {
|
2020-01-07 19:04:52 +04:00
|
|
|
const [
|
|
|
|
elementX1,
|
|
|
|
elementY1,
|
|
|
|
elementX2,
|
2020-01-24 12:04:54 +02:00
|
|
|
elementY2,
|
2020-01-07 19:04:52 +04:00
|
|
|
] = getElementAbsoluteCoords(element);
|
2020-01-13 04:32:25 +05:00
|
|
|
|
|
|
|
return (
|
2020-01-06 20:24:54 +04:00
|
|
|
element.type !== "selection" &&
|
|
|
|
selectionX1 <= elementX1 &&
|
|
|
|
selectionY1 <= elementY1 &&
|
|
|
|
selectionX2 >= elementX2 &&
|
2020-01-13 04:32:25 +05:00
|
|
|
selectionY2 >= elementY2
|
|
|
|
);
|
2020-01-06 20:24:54 +04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-01-09 19:22:04 +04:00
|
|
|
export function clearSelection(elements: readonly ExcalidrawElement[]) {
|
2020-02-05 22:47:10 +04:00
|
|
|
let someWasSelected = false;
|
|
|
|
elements.forEach(element => {
|
|
|
|
if (element.isSelected) {
|
|
|
|
someWasSelected = true;
|
|
|
|
element.isSelected = false;
|
|
|
|
}
|
2020-01-06 20:24:54 +04:00
|
|
|
});
|
2020-01-09 19:22:04 +04:00
|
|
|
|
2020-02-05 22:47:10 +04:00
|
|
|
return someWasSelected ? elements.slice() : elements;
|
2020-01-06 20:24:54 +04:00
|
|
|
}
|
|
|
|
|
2020-01-09 19:22:04 +04:00
|
|
|
export function deleteSelectedElements(elements: readonly ExcalidrawElement[]) {
|
|
|
|
return elements.filter(el => !el.isSelected);
|
2020-01-06 20:24:54 +04:00
|
|
|
}
|
|
|
|
|
2020-01-09 19:22:04 +04:00
|
|
|
export function getSelectedIndices(elements: readonly ExcalidrawElement[]) {
|
2020-01-06 20:24:54 +04:00
|
|
|
const selectedIndices: number[] = [];
|
|
|
|
elements.forEach((element, index) => {
|
|
|
|
if (element.isSelected) {
|
|
|
|
selectedIndices.push(index);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return selectedIndices;
|
|
|
|
}
|
|
|
|
|
2020-02-16 22:54:50 +01:00
|
|
|
export function isSomeElementSelected(
|
|
|
|
elements: readonly ExcalidrawElement[],
|
|
|
|
): boolean {
|
|
|
|
return elements.some(element => element.isSelected);
|
|
|
|
}
|
2020-01-06 20:24:54 +04:00
|
|
|
|
2020-01-21 00:16:22 +01:00
|
|
|
/**
|
|
|
|
* Returns common attribute (picked by `getAttribute` callback) of selected
|
|
|
|
* elements. If elements don't share the same value, returns `null`.
|
|
|
|
*/
|
|
|
|
export function getCommonAttributeOfSelectedElements<T>(
|
2020-01-09 19:22:04 +04:00
|
|
|
elements: readonly ExcalidrawElement[],
|
2020-01-24 12:04:54 +02:00
|
|
|
getAttribute: (element: ExcalidrawElement) => T,
|
2020-01-06 20:24:54 +04:00
|
|
|
): T | null {
|
|
|
|
const attributes = Array.from(
|
|
|
|
new Set(
|
2020-02-16 22:54:50 +01:00
|
|
|
getSelectedElements(elements).map(element => getAttribute(element)),
|
2020-01-24 12:04:54 +02:00
|
|
|
),
|
2020-01-06 20:24:54 +04:00
|
|
|
);
|
|
|
|
return attributes.length === 1 ? attributes[0] : null;
|
|
|
|
}
|
2020-02-16 22:54:50 +01:00
|
|
|
|
|
|
|
export function getSelectedElements(
|
|
|
|
elements: readonly ExcalidrawElement[],
|
|
|
|
): readonly ExcalidrawElement[] {
|
|
|
|
return elements.filter(element => element.isSelected);
|
|
|
|
}
|
2020-03-07 10:20:38 -05:00
|
|
|
|
|
|
|
export function getTargetElement(
|
|
|
|
editingElement: ExcalidrawElement | null,
|
|
|
|
elements: readonly ExcalidrawElement[],
|
|
|
|
) {
|
|
|
|
return editingElement ? [editingElement] : getSelectedElements(elements);
|
|
|
|
}
|