2020-04-08 09:49:52 -07:00
|
|
|
import {
|
|
|
|
ExcalidrawElement,
|
2022-03-02 17:04:09 +01:00
|
|
|
ExcalidrawTextContainer,
|
2020-04-08 09:49:52 -07:00
|
|
|
NonDeletedExcalidrawElement,
|
|
|
|
} from "../element/types";
|
2020-02-15 21:03:32 +01:00
|
|
|
|
2020-08-08 21:04:15 -07:00
|
|
|
import { getElementAbsoluteCoords } from "../element";
|
2022-03-02 17:04:09 +01:00
|
|
|
import { isTextBindableContainer } from "../element/typeChecks";
|
2020-01-06 20:24:54 +04:00
|
|
|
|
2020-01-26 06:19:43 -08:00
|
|
|
export const hasBackground = (type: string) =>
|
2020-04-09 01:46:47 -07:00
|
|
|
type === "rectangle" ||
|
|
|
|
type === "ellipse" ||
|
|
|
|
type === "diamond" ||
|
2022-02-09 22:13:21 +05:30
|
|
|
type === "line" ||
|
|
|
|
type === "freedraw";
|
2020-01-06 20:24:54 +04:00
|
|
|
|
2021-10-21 22:05:48 +02:00
|
|
|
export const hasStrokeColor = (type: string) => type !== "image";
|
|
|
|
|
2021-05-09 16:42:10 +01:00
|
|
|
export const hasStrokeWidth = (type: string) =>
|
2020-01-26 06:19:43 -08:00
|
|
|
type === "rectangle" ||
|
|
|
|
type === "ellipse" ||
|
|
|
|
type === "diamond" ||
|
2021-05-09 16:42:10 +01:00
|
|
|
type === "freedraw" ||
|
2020-01-26 06:19:43 -08:00
|
|
|
type === "arrow" ||
|
|
|
|
type === "line";
|
2020-01-06 20:24:54 +04:00
|
|
|
|
2021-05-09 16:42:10 +01:00
|
|
|
export const hasStrokeStyle = (type: string) =>
|
2020-08-15 00:59:43 +09:00
|
|
|
type === "rectangle" ||
|
2021-05-09 16:42:10 +01:00
|
|
|
type === "ellipse" ||
|
|
|
|
type === "diamond" ||
|
2020-08-15 00:59:43 +09:00
|
|
|
type === "arrow" ||
|
|
|
|
type === "line";
|
|
|
|
|
2021-05-09 16:42:10 +01:00
|
|
|
export const canChangeSharpness = (type: string) =>
|
2021-12-05 21:26:19 +05:30
|
|
|
type === "rectangle" ||
|
|
|
|
type === "arrow" ||
|
|
|
|
type === "line" ||
|
|
|
|
type === "diamond";
|
2021-05-09 16:42:10 +01:00
|
|
|
|
2020-01-26 06:19:43 -08:00
|
|
|
export const hasText = (type: string) => type === "text";
|
2020-01-09 02:29:41 +01:00
|
|
|
|
2020-12-08 15:02:55 +00:00
|
|
|
export const canHaveArrowheads = (type: string) => type === "arrow";
|
|
|
|
|
2020-05-20 16:21:37 +03:00
|
|
|
export const getElementAtPosition = (
|
2020-04-08 09:49:52 -07:00
|
|
|
elements: readonly NonDeletedExcalidrawElement[],
|
2020-08-08 21:04:15 -07:00
|
|
|
isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,
|
2020-05-20 16:21:37 +03:00
|
|
|
) => {
|
2020-01-06 20:24:54 +04:00
|
|
|
let hitElement = null;
|
|
|
|
// We need to to hit testing from front (end of the array) to back (beginning of the array)
|
2020-08-26 17:37:44 +01:00
|
|
|
// because array is ordered from lower z-index to highest and we want element z-index
|
|
|
|
// with higher z-index
|
2020-11-29 18:32:51 +02:00
|
|
|
for (let index = elements.length - 1; index >= 0; --index) {
|
|
|
|
const element = elements[index];
|
2020-08-08 21:04:15 -07:00
|
|
|
if (element.isDeleted) {
|
2020-03-14 20:46:57 -07:00
|
|
|
continue;
|
|
|
|
}
|
2020-08-08 21:04:15 -07:00
|
|
|
if (isAtPositionFn(element)) {
|
|
|
|
hitElement = element;
|
2020-01-06 20:24:54 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return hitElement;
|
2020-05-20 16:21:37 +03:00
|
|
|
};
|
2020-01-09 01:09:09 +05:00
|
|
|
|
2020-08-26 17:37:44 +01:00
|
|
|
export const getElementsAtPosition = (
|
|
|
|
elements: readonly NonDeletedExcalidrawElement[],
|
|
|
|
isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,
|
|
|
|
) => {
|
|
|
|
// The parameter elements comes ordered from lower z-index to higher.
|
|
|
|
// We want to preserve that order on the returned array.
|
|
|
|
return elements.filter(
|
|
|
|
(element) => !element.isDeleted && isAtPositionFn(element),
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2022-03-02 17:04:09 +01:00
|
|
|
export const getTextBindableContainerAtPosition = (
|
2020-01-09 19:22:04 +04:00
|
|
|
elements: readonly ExcalidrawElement[],
|
2020-01-09 01:09:09 +05:00
|
|
|
x: number,
|
2020-01-24 12:04:54 +02:00
|
|
|
y: number,
|
2022-03-02 17:04:09 +01:00
|
|
|
): ExcalidrawTextContainer | null => {
|
2020-01-09 01:09:09 +05:00
|
|
|
let hitElement = null;
|
|
|
|
// We need to to hit testing from front (end of the array) to back (beginning of the array)
|
2020-11-29 18:32:51 +02:00
|
|
|
for (let index = elements.length - 1; index >= 0; --index) {
|
|
|
|
if (elements[index].isDeleted) {
|
2020-03-14 20:46:57 -07:00
|
|
|
continue;
|
|
|
|
}
|
2020-11-29 18:32:51 +02:00
|
|
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(elements[index]);
|
2021-12-28 16:24:44 +05:30
|
|
|
if (x1 < x && x < x2 && y1 < y && y < y2) {
|
2020-11-29 18:32:51 +02:00
|
|
|
hitElement = elements[index];
|
2020-01-09 01:09:09 +05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-03-02 17:04:09 +01:00
|
|
|
return isTextBindableContainer(hitElement) ? hitElement : null;
|
2020-05-20 16:21:37 +03:00
|
|
|
};
|