resizeTest.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import { ExcalidrawElement } from "./types";
  2. import { handlerRectangles } from "./handlerRectangles";
  3. import { SceneScroll } from "../scene/types";
  4. type HandlerRectanglesRet = keyof ReturnType<typeof handlerRectangles>;
  5. export function resizeTest(
  6. element: ExcalidrawElement,
  7. x: number,
  8. y: number,
  9. { scrollX, scrollY }: SceneScroll,
  10. ): HandlerRectanglesRet | false {
  11. if (!element.isSelected || element.type === "text") return false;
  12. const handlers = handlerRectangles(element, { scrollX, scrollY });
  13. const filter = Object.keys(handlers).filter(key => {
  14. const handler = handlers[key as HandlerRectanglesRet]!;
  15. return (
  16. x + scrollX >= handler[0] &&
  17. x + scrollX <= handler[0] + handler[2] &&
  18. y + scrollY >= handler[1] &&
  19. y + scrollY <= handler[1] + handler[3]
  20. );
  21. });
  22. if (filter.length > 0) {
  23. return filter[0] as HandlerRectanglesRet;
  24. }
  25. return false;
  26. }
  27. export function getElementWithResizeHandler(
  28. elements: readonly ExcalidrawElement[],
  29. { x, y }: { x: number; y: number },
  30. { scrollX, scrollY }: SceneScroll,
  31. ) {
  32. return elements.reduce((result, element) => {
  33. if (result) {
  34. return result;
  35. }
  36. const resizeHandle = resizeTest(element, x, y, {
  37. scrollX,
  38. scrollY,
  39. });
  40. return resizeHandle ? { element, resizeHandle } : null;
  41. }, null as { element: ExcalidrawElement; resizeHandle: ReturnType<typeof resizeTest> } | null);
  42. }
  43. /*
  44. * Returns bi-directional cursor for the element being resized
  45. */
  46. export function getCursorForResizingElement(resizingElement: {
  47. element: ExcalidrawElement;
  48. resizeHandle: ReturnType<typeof resizeTest>;
  49. }): string {
  50. const { element, resizeHandle } = resizingElement;
  51. const shouldSwapCursors =
  52. Math.sign(element.height) * Math.sign(element.width) === -1;
  53. let cursor = null;
  54. switch (resizeHandle) {
  55. case "n":
  56. case "s":
  57. cursor = "ns";
  58. break;
  59. case "w":
  60. case "e":
  61. cursor = "ew";
  62. break;
  63. case "nw":
  64. case "se":
  65. if (shouldSwapCursors) {
  66. cursor = "nesw";
  67. } else {
  68. cursor = "nwse";
  69. }
  70. break;
  71. case "ne":
  72. case "sw":
  73. if (shouldSwapCursors) {
  74. cursor = "nwse";
  75. } else {
  76. cursor = "nesw";
  77. }
  78. break;
  79. }
  80. return cursor ? `${cursor}-resize` : "";
  81. }