2020-02-21 14:34:18 -05:00
|
|
|
import { ExcalidrawElement, PointerType } from "./types";
|
2020-01-06 19:34:22 +04:00
|
|
|
|
|
|
|
import { handlerRectangles } from "./handlerRectangles";
|
|
|
|
|
2020-01-08 16:55:13 +01:00
|
|
|
type HandlerRectanglesRet = keyof ReturnType<typeof handlerRectangles>;
|
|
|
|
|
2020-01-06 19:34:22 +04:00
|
|
|
export function resizeTest(
|
|
|
|
element: ExcalidrawElement,
|
|
|
|
x: number,
|
|
|
|
y: number,
|
2020-02-15 21:03:32 +01:00
|
|
|
zoom: number,
|
2020-02-21 14:34:18 -05:00
|
|
|
pointerType: PointerType,
|
2020-01-08 16:55:13 +01:00
|
|
|
): HandlerRectanglesRet | false {
|
2020-02-02 20:04:35 +02:00
|
|
|
if (!element.isSelected || element.type === "text") {
|
|
|
|
return false;
|
|
|
|
}
|
2020-01-06 19:34:22 +04:00
|
|
|
|
2020-02-21 14:34:18 -05:00
|
|
|
const handlers = handlerRectangles(element, zoom, pointerType);
|
2020-01-06 19:34:22 +04:00
|
|
|
|
|
|
|
const filter = Object.keys(handlers).filter(key => {
|
2020-01-08 16:55:13 +01:00
|
|
|
const handler = handlers[key as HandlerRectanglesRet]!;
|
2020-02-02 20:04:35 +02:00
|
|
|
if (!handler) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-01-06 19:34:22 +04:00
|
|
|
|
|
|
|
return (
|
2020-02-15 21:03:32 +01:00
|
|
|
x >= handler[0] &&
|
|
|
|
x <= handler[0] + handler[2] &&
|
|
|
|
y >= handler[1] &&
|
|
|
|
y <= handler[1] + handler[3]
|
2020-01-06 19:34:22 +04:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (filter.length > 0) {
|
2020-01-08 16:55:13 +01:00
|
|
|
return filter[0] as HandlerRectanglesRet;
|
2020-01-06 19:34:22 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2020-01-08 23:56:35 -03:00
|
|
|
|
|
|
|
export function getElementWithResizeHandler(
|
2020-01-09 19:22:04 +04:00
|
|
|
elements: readonly ExcalidrawElement[],
|
2020-01-08 23:56:35 -03:00
|
|
|
{ x, y }: { x: number; y: number },
|
2020-02-15 21:03:32 +01:00
|
|
|
zoom: number,
|
2020-02-21 14:34:18 -05:00
|
|
|
pointerType: PointerType,
|
2020-01-08 23:56:35 -03:00
|
|
|
) {
|
|
|
|
return elements.reduce((result, element) => {
|
|
|
|
if (result) {
|
|
|
|
return result;
|
|
|
|
}
|
2020-02-21 14:34:18 -05:00
|
|
|
const resizeHandle = resizeTest(element, x, y, zoom, pointerType);
|
2020-01-08 23:56:35 -03:00
|
|
|
return resizeHandle ? { element, resizeHandle } : null;
|
|
|
|
}, null as { element: ExcalidrawElement; resizeHandle: ReturnType<typeof resizeTest> } | null);
|
|
|
|
}
|
2020-01-19 21:11:46 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Returns bi-directional cursor for the element being resized
|
|
|
|
*/
|
|
|
|
export function getCursorForResizingElement(resizingElement: {
|
|
|
|
element: ExcalidrawElement;
|
|
|
|
resizeHandle: ReturnType<typeof resizeTest>;
|
|
|
|
}): string {
|
|
|
|
const { element, resizeHandle } = resizingElement;
|
|
|
|
const shouldSwapCursors =
|
|
|
|
Math.sign(element.height) * Math.sign(element.width) === -1;
|
|
|
|
let cursor = null;
|
|
|
|
|
|
|
|
switch (resizeHandle) {
|
|
|
|
case "n":
|
|
|
|
case "s":
|
|
|
|
cursor = "ns";
|
|
|
|
break;
|
|
|
|
case "w":
|
|
|
|
case "e":
|
|
|
|
cursor = "ew";
|
|
|
|
break;
|
|
|
|
case "nw":
|
|
|
|
case "se":
|
|
|
|
if (shouldSwapCursors) {
|
|
|
|
cursor = "nesw";
|
|
|
|
} else {
|
|
|
|
cursor = "nwse";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "ne":
|
|
|
|
case "sw":
|
|
|
|
if (shouldSwapCursors) {
|
|
|
|
cursor = "nwse";
|
|
|
|
} else {
|
|
|
|
cursor = "nesw";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cursor ? `${cursor}-resize` : "";
|
|
|
|
}
|
2020-01-24 20:45:52 +01:00
|
|
|
|
|
|
|
export function normalizeResizeHandle(
|
|
|
|
element: ExcalidrawElement,
|
|
|
|
resizeHandle: HandlerRectanglesRet,
|
|
|
|
): HandlerRectanglesRet {
|
|
|
|
if (
|
|
|
|
(element.width >= 0 && element.height >= 0) ||
|
|
|
|
element.type === "line" ||
|
|
|
|
element.type === "arrow"
|
|
|
|
) {
|
|
|
|
return resizeHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (element.width < 0 && element.height < 0) {
|
|
|
|
switch (resizeHandle) {
|
|
|
|
case "nw":
|
|
|
|
return "se";
|
|
|
|
case "ne":
|
|
|
|
return "sw";
|
|
|
|
case "se":
|
|
|
|
return "nw";
|
|
|
|
case "sw":
|
|
|
|
return "ne";
|
|
|
|
}
|
|
|
|
} else if (element.width < 0) {
|
|
|
|
switch (resizeHandle) {
|
|
|
|
case "nw":
|
|
|
|
return "ne";
|
|
|
|
case "ne":
|
|
|
|
return "nw";
|
|
|
|
case "se":
|
|
|
|
return "sw";
|
|
|
|
case "sw":
|
|
|
|
return "se";
|
|
|
|
case "e":
|
|
|
|
return "w";
|
|
|
|
case "w":
|
|
|
|
return "e";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (resizeHandle) {
|
|
|
|
case "nw":
|
|
|
|
return "sw";
|
|
|
|
case "ne":
|
|
|
|
return "se";
|
|
|
|
case "se":
|
|
|
|
return "ne";
|
|
|
|
case "sw":
|
|
|
|
return "nw";
|
|
|
|
case "n":
|
|
|
|
return "s";
|
|
|
|
case "s":
|
|
|
|
return "n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return resizeHandle;
|
|
|
|
}
|