index.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import {
  2. ExcalidrawElement,
  3. NonDeletedExcalidrawElement,
  4. NonDeleted,
  5. } from "./types";
  6. import { isInvisiblySmallElement } from "./sizeHelpers";
  7. import { isLinearElementType } from "./typeChecks";
  8. export {
  9. newElement,
  10. newTextElement,
  11. updateTextElement,
  12. newLinearElement,
  13. duplicateElement,
  14. } from "./newElement";
  15. export {
  16. getElementAbsoluteCoords,
  17. getElementBounds,
  18. getCommonBounds,
  19. getDiamondPoints,
  20. getArrowheadPoints,
  21. getClosestElementBounds,
  22. } from "./bounds";
  23. export {
  24. OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
  25. getTransformHandlesFromCoords,
  26. getTransformHandles,
  27. } from "./transformHandles";
  28. export {
  29. hitTest,
  30. isHittingElementBoundingBoxWithoutHittingElement,
  31. } from "./collision";
  32. export {
  33. resizeTest,
  34. getCursorForResizingElement,
  35. getElementWithTransformHandleType,
  36. getTransformHandleTypeFromCoords,
  37. } from "./resizeTest";
  38. export {
  39. transformElements,
  40. getResizeOffsetXY,
  41. getResizeArrowDirection,
  42. } from "./resizeElements";
  43. export {
  44. dragSelectedElements,
  45. getDragOffsetXY,
  46. dragNewElement,
  47. } from "./dragElements";
  48. export { isTextElement, isExcalidrawElement } from "./typeChecks";
  49. export { textWysiwyg } from "./textWysiwyg";
  50. export { redrawTextBoundingBox } from "./textElement";
  51. export {
  52. getPerfectElementSize,
  53. isInvisiblySmallElement,
  54. resizePerfectLineForNWHandler,
  55. getNormalizedDimensions,
  56. } from "./sizeHelpers";
  57. export { showSelectedShapeActions } from "./showSelectedShapeActions";
  58. export const getSyncableElements = (
  59. elements: readonly ExcalidrawElement[], // There are places in Excalidraw where synthetic invisibly small elements are added and removed.
  60. ) =>
  61. // It's probably best to keep those local otherwise there might be a race condition that
  62. // gets the app into an invalid state. I've never seen it happen but I'm worried about it :)
  63. elements.filter((el) => el.isDeleted || !isInvisiblySmallElement(el));
  64. export const getElementMap = (elements: readonly ExcalidrawElement[]) =>
  65. elements.reduce(
  66. (acc: { [key: string]: ExcalidrawElement }, element: ExcalidrawElement) => {
  67. acc[element.id] = element;
  68. return acc;
  69. },
  70. {},
  71. );
  72. export const getSceneVersion = (elements: readonly ExcalidrawElement[]) =>
  73. elements.reduce((acc, el) => acc + el.version, 0);
  74. export const getNonDeletedElements = (elements: readonly ExcalidrawElement[]) =>
  75. elements.filter(
  76. (element) => !element.isDeleted,
  77. ) as readonly NonDeletedExcalidrawElement[];
  78. export const isNonDeletedElement = <T extends ExcalidrawElement>(
  79. element: T,
  80. ): element is NonDeleted<T> => !element.isDeleted;
  81. const _clearElements = (
  82. elements: readonly ExcalidrawElement[],
  83. ): ExcalidrawElement[] =>
  84. getNonDeletedElements(elements).map((element) =>
  85. isLinearElementType(element.type)
  86. ? { ...element, lastCommittedPoint: null }
  87. : element,
  88. );
  89. export const clearElementsForExport = (
  90. elements: readonly ExcalidrawElement[],
  91. ) => _clearElements(elements);
  92. export const clearElementsForLocalStorage = (
  93. elements: readonly ExcalidrawElement[],
  94. ) => _clearElements(elements);