2020-04-08 09:49:52 -07:00
|
|
|
import {
|
|
|
|
ExcalidrawElement,
|
|
|
|
NonDeletedExcalidrawElement,
|
|
|
|
} from "../element/types";
|
2020-04-07 23:04:20 +09:00
|
|
|
import { getElementAbsoluteCoords, getElementBounds } from "../element";
|
2020-03-08 10:20:55 -07:00
|
|
|
import { AppState } from "../types";
|
2020-01-06 20:24:54 +04:00
|
|
|
|
2020-05-20 16:21:37 +03:00
|
|
|
export const getElementsWithinSelection = (
|
2020-04-08 09:49:52 -07:00
|
|
|
elements: readonly NonDeletedExcalidrawElement[],
|
|
|
|
selection: NonDeletedExcalidrawElement,
|
2020-05-20 16:21:37 +03:00
|
|
|
) => {
|
2021-11-01 15:24:05 +02:00
|
|
|
const [selectionX1, selectionY1, selectionX2, selectionY2] =
|
|
|
|
getElementAbsoluteCoords(selection);
|
2020-03-23 13:05:07 +02:00
|
|
|
return elements.filter((element) => {
|
2021-11-01 15:24:05 +02:00
|
|
|
const [elementX1, elementY1, elementX2, elementY2] =
|
|
|
|
getElementBounds(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-05-20 16:21:37 +03:00
|
|
|
};
|
2020-01-06 20:24:54 +04:00
|
|
|
|
2020-05-20 16:21:37 +03:00
|
|
|
export const isSomeElementSelected = (
|
2020-04-08 09:49:52 -07:00
|
|
|
elements: readonly NonDeletedExcalidrawElement[],
|
2020-03-08 10:20:55 -07:00
|
|
|
appState: AppState,
|
2020-12-07 18:35:16 +02:00
|
|
|
): boolean =>
|
|
|
|
elements.some((element) => appState.selectedElementIds[element.id]);
|
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`.
|
|
|
|
*/
|
2020-05-20 16:21:37 +03:00
|
|
|
export const getCommonAttributeOfSelectedElements = <T>(
|
2020-04-08 09:49:52 -07:00
|
|
|
elements: readonly NonDeletedExcalidrawElement[],
|
2020-03-08 10:20:55 -07:00
|
|
|
appState: AppState,
|
2020-01-24 12:04:54 +02:00
|
|
|
getAttribute: (element: ExcalidrawElement) => T,
|
2020-05-20 16:21:37 +03:00
|
|
|
): T | null => {
|
2020-01-06 20:24:54 +04:00
|
|
|
const attributes = Array.from(
|
|
|
|
new Set(
|
2020-03-23 13:05:07 +02:00
|
|
|
getSelectedElements(elements, appState).map((element) =>
|
2020-03-08 10:20:55 -07:00
|
|
|
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-05-20 16:21:37 +03:00
|
|
|
};
|
2020-02-16 22:54:50 +01:00
|
|
|
|
2020-05-20 16:21:37 +03:00
|
|
|
export const getSelectedElements = (
|
2020-04-08 09:49:52 -07:00
|
|
|
elements: readonly NonDeletedExcalidrawElement[],
|
2020-03-08 10:20:55 -07:00
|
|
|
appState: AppState,
|
2020-12-07 18:35:16 +02:00
|
|
|
) => elements.filter((element) => appState.selectedElementIds[element.id]);
|
2020-03-07 10:20:38 -05:00
|
|
|
|
2020-12-07 18:35:16 +02:00
|
|
|
export const getTargetElements = (
|
2020-04-08 09:49:52 -07:00
|
|
|
elements: readonly NonDeletedExcalidrawElement[],
|
2020-03-08 10:20:55 -07:00
|
|
|
appState: AppState,
|
2020-12-07 18:35:16 +02:00
|
|
|
) =>
|
|
|
|
appState.editingElement
|
2020-03-08 10:20:55 -07:00
|
|
|
? [appState.editingElement]
|
|
|
|
: getSelectedElements(elements, appState);
|