comparisons.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import {
  2. ExcalidrawElement,
  3. NonDeletedExcalidrawElement,
  4. } from "../element/types";
  5. import { getElementAbsoluteCoords } from "../element";
  6. export const hasBackground = (type: string) =>
  7. type === "rectangle" ||
  8. type === "ellipse" ||
  9. type === "diamond" ||
  10. type === "draw" ||
  11. type === "line";
  12. export const hasStroke = (type: string) =>
  13. type === "rectangle" ||
  14. type === "ellipse" ||
  15. type === "diamond" ||
  16. type === "arrow" ||
  17. type === "draw" ||
  18. type === "line";
  19. export const canChangeSharpness = (type: string) =>
  20. type === "rectangle" ||
  21. type === "arrow" ||
  22. type === "draw" ||
  23. type === "line";
  24. export const hasText = (type: string) => type === "text";
  25. export const canHaveArrowheads = (type: string) => type === "arrow";
  26. export const getElementAtPosition = (
  27. elements: readonly NonDeletedExcalidrawElement[],
  28. isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,
  29. ) => {
  30. let hitElement = null;
  31. // We need to to hit testing from front (end of the array) to back (beginning of the array)
  32. // because array is ordered from lower z-index to highest and we want element z-index
  33. // with higher z-index
  34. for (let index = elements.length - 1; index >= 0; --index) {
  35. const element = elements[index];
  36. if (element.isDeleted) {
  37. continue;
  38. }
  39. if (isAtPositionFn(element)) {
  40. hitElement = element;
  41. break;
  42. }
  43. }
  44. return hitElement;
  45. };
  46. export const getElementsAtPosition = (
  47. elements: readonly NonDeletedExcalidrawElement[],
  48. isAtPositionFn: (element: NonDeletedExcalidrawElement) => boolean,
  49. ) => {
  50. // The parameter elements comes ordered from lower z-index to higher.
  51. // We want to preserve that order on the returned array.
  52. return elements.filter(
  53. (element) => !element.isDeleted && isAtPositionFn(element),
  54. );
  55. };
  56. export const getElementContainingPosition = (
  57. elements: readonly ExcalidrawElement[],
  58. x: number,
  59. y: number,
  60. ) => {
  61. let hitElement = null;
  62. // We need to to hit testing from front (end of the array) to back (beginning of the array)
  63. for (let index = elements.length - 1; index >= 0; --index) {
  64. if (elements[index].isDeleted) {
  65. continue;
  66. }
  67. const [x1, y1, x2, y2] = getElementAbsoluteCoords(elements[index]);
  68. if (x1 < x && x < x2 && y1 < y && y < y2) {
  69. hitElement = elements[index];
  70. break;
  71. }
  72. }
  73. return hitElement;
  74. };