@excalidraw/excalidraw 0.17.1-7441-4e2c539 → 0.17.1-a38e82f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/CHANGELOG.md +52 -2
  2. package/dist/browser/dev/excalidraw-assets-dev/chunk-5VWQDKDR.js +20279 -0
  3. package/dist/browser/dev/excalidraw-assets-dev/chunk-5VWQDKDR.js.map +7 -0
  4. package/dist/browser/dev/excalidraw-assets-dev/{chunk-2W5GQUR4.js → chunk-IM4WTX2M.js} +12 -6
  5. package/dist/browser/dev/excalidraw-assets-dev/chunk-IM4WTX2M.js.map +7 -0
  6. package/dist/browser/dev/excalidraw-assets-dev/{en-OC6JWP3X.js → en-IOBA4CS2.js} +4 -2
  7. package/dist/browser/dev/excalidraw-assets-dev/image-LK4UNFRZ.css +6 -0
  8. package/dist/browser/dev/excalidraw-assets-dev/image-LK4UNFRZ.css.map +7 -0
  9. package/dist/browser/dev/excalidraw-assets-dev/{image-HYNUJ3XL.js → image-VKDAL6BQ.js} +2 -4
  10. package/dist/browser/dev/excalidraw-assets-dev/roundRect-T5BX56ZF.js +161 -0
  11. package/dist/browser/dev/excalidraw-assets-dev/roundRect-T5BX56ZF.js.map +7 -0
  12. package/dist/browser/dev/index.css +189 -129
  13. package/dist/browser/dev/index.css.map +3 -3
  14. package/dist/browser/dev/index.js +34707 -26
  15. package/dist/browser/dev/index.js.map +4 -4
  16. package/dist/browser/prod/excalidraw-assets/chunk-LIG3S5TN.js +11 -0
  17. package/dist/browser/prod/excalidraw-assets/chunk-N2C5DK3B.js +55 -0
  18. package/dist/browser/prod/excalidraw-assets/en-WFZVQ7I6.js +1 -0
  19. package/dist/browser/prod/excalidraw-assets/image-4AT7LYMR.js +1 -0
  20. package/dist/browser/prod/excalidraw-assets/image-X66R2EM5.css +1 -0
  21. package/dist/browser/prod/excalidraw-assets/roundRect-2ACQK4DA.js +1 -0
  22. package/dist/browser/prod/index.css +1 -1
  23. package/dist/browser/prod/index.js +203 -1
  24. package/dist/{prod/en-RLIAOBCI.json → dev/en-TDNWCAOT.json} +9 -5
  25. package/dist/dev/index.css +189 -129
  26. package/dist/dev/index.css.map +3 -3
  27. package/dist/dev/index.js +38445 -39402
  28. package/dist/dev/index.js.map +4 -4
  29. package/dist/excalidraw/actions/actionAddToLibrary.d.ts +12 -12
  30. package/dist/excalidraw/actions/actionAlign.d.ts +6 -6
  31. package/dist/excalidraw/actions/actionAlign.js +2 -1
  32. package/dist/excalidraw/actions/actionBoundText.d.ts +8 -8
  33. package/dist/excalidraw/actions/actionBoundText.js +8 -8
  34. package/dist/excalidraw/actions/actionCanvas.d.ts +46 -46
  35. package/dist/excalidraw/actions/actionClipboard.d.ts +27 -27
  36. package/dist/excalidraw/actions/actionClipboard.js +9 -2
  37. package/dist/excalidraw/actions/actionDeleteSelected.d.ts +12 -12
  38. package/dist/excalidraw/actions/actionDeleteSelected.js +3 -2
  39. package/dist/excalidraw/actions/actionDistribute.d.ts +2 -2
  40. package/dist/excalidraw/actions/actionDistribute.js +1 -1
  41. package/dist/excalidraw/actions/actionDuplicateSelection.d.ts +1 -1
  42. package/dist/excalidraw/actions/actionDuplicateSelection.js +4 -3
  43. package/dist/excalidraw/actions/actionElementLock.d.ts +8 -8
  44. package/dist/excalidraw/actions/actionExport.d.ts +35 -35
  45. package/dist/excalidraw/actions/actionExport.js +4 -4
  46. package/dist/excalidraw/actions/actionFinalize.d.ts +7 -7
  47. package/dist/excalidraw/actions/actionFinalize.js +7 -6
  48. package/dist/excalidraw/actions/actionFlip.d.ts +2 -2
  49. package/dist/excalidraw/actions/actionFlip.js +11 -11
  50. package/dist/excalidraw/actions/actionFrame.d.ts +13 -13
  51. package/dist/excalidraw/actions/actionFrame.js +1 -1
  52. package/dist/excalidraw/actions/actionGroup.d.ts +8 -8
  53. package/dist/excalidraw/actions/actionGroup.js +3 -2
  54. package/dist/excalidraw/actions/actionLinearEditor.d.ts +4 -4
  55. package/dist/excalidraw/actions/actionLinearEditor.js +1 -1
  56. package/dist/excalidraw/{element/Hyperlink.d.ts → actions/actionLink.d.ts} +28 -50
  57. package/dist/excalidraw/actions/actionLink.js +40 -0
  58. package/dist/excalidraw/actions/actionMenu.d.ts +11 -11
  59. package/dist/excalidraw/actions/actionNavigate.d.ts +8 -8
  60. package/dist/excalidraw/actions/actionNavigate.js +1 -1
  61. package/dist/excalidraw/actions/actionProperties.d.ts +64 -64
  62. package/dist/excalidraw/actions/actionProperties.js +32 -27
  63. package/dist/excalidraw/actions/actionSelectAll.d.ts +4 -4
  64. package/dist/excalidraw/actions/actionSelectAll.js +1 -1
  65. package/dist/excalidraw/actions/actionStyles.d.ts +6 -6
  66. package/dist/excalidraw/actions/actionStyles.js +4 -4
  67. package/dist/excalidraw/actions/actionToggleGridMode.d.ts +4 -4
  68. package/dist/excalidraw/actions/actionToggleObjectsSnapMode.d.ts +4 -4
  69. package/dist/excalidraw/actions/actionToggleStats.d.ts +4 -4
  70. package/dist/excalidraw/actions/actionToggleViewMode.d.ts +4 -4
  71. package/dist/excalidraw/actions/actionToggleZenMode.d.ts +4 -4
  72. package/dist/excalidraw/actions/index.d.ts +1 -1
  73. package/dist/excalidraw/actions/index.js +1 -1
  74. package/dist/excalidraw/actions/manager.js +2 -1
  75. package/dist/excalidraw/align.d.ts +2 -2
  76. package/dist/excalidraw/align.js +2 -2
  77. package/dist/excalidraw/animated-trail.d.ts +33 -0
  78. package/dist/excalidraw/animated-trail.js +96 -0
  79. package/dist/excalidraw/animation-frame-handler.d.ts +16 -0
  80. package/dist/excalidraw/animation-frame-handler.js +55 -0
  81. package/dist/excalidraw/appState.d.ts +1 -1
  82. package/dist/excalidraw/appState.js +1 -3
  83. package/dist/excalidraw/clipboard.js +5 -5
  84. package/dist/excalidraw/components/Actions.d.ts +3 -3
  85. package/dist/excalidraw/components/Actions.js +18 -7
  86. package/dist/excalidraw/components/App.d.ts +32 -17
  87. package/dist/excalidraw/components/App.js +474 -339
  88. package/dist/excalidraw/components/Button.d.ts +1 -1
  89. package/dist/excalidraw/components/FilledButton.d.ts +2 -2
  90. package/dist/excalidraw/components/FilledButton.js +27 -3
  91. package/dist/excalidraw/components/FollowMode/FollowMode.js +1 -1
  92. package/dist/excalidraw/components/ImageExportDialog.d.ts +2 -1
  93. package/dist/excalidraw/components/ImageExportDialog.js +16 -12
  94. package/dist/excalidraw/components/JSONExportDialog.js +1 -1
  95. package/dist/excalidraw/components/{LaserTool/LaserPointerButton.d.ts → LaserPointerButton.d.ts} +1 -1
  96. package/dist/excalidraw/components/{LaserTool/LaserPointerButton.js → LaserPointerButton.js} +2 -2
  97. package/dist/excalidraw/components/LayerUI.js +3 -3
  98. package/dist/excalidraw/components/MobileMenu.js +1 -1
  99. package/dist/excalidraw/components/ProjectName.d.ts +0 -1
  100. package/dist/excalidraw/components/ProjectName.js +1 -1
  101. package/dist/excalidraw/components/SVGLayer.d.ts +8 -0
  102. package/dist/excalidraw/components/SVGLayer.js +20 -0
  103. package/dist/excalidraw/components/ShareableLinkDialog.js +10 -10
  104. package/dist/excalidraw/components/Stack.d.ts +2 -2
  105. package/dist/excalidraw/components/TTDDialog/common.js +10 -1
  106. package/dist/excalidraw/components/TextField.d.ts +5 -2
  107. package/dist/excalidraw/components/TextField.js +6 -3
  108. package/dist/excalidraw/components/Toast.d.ts +3 -2
  109. package/dist/excalidraw/components/Toast.js +2 -2
  110. package/dist/excalidraw/components/ToolButton.js +2 -1
  111. package/dist/excalidraw/components/canvases/InteractiveCanvas.d.ts +2 -2
  112. package/dist/excalidraw/components/canvases/InteractiveCanvas.js +6 -5
  113. package/dist/excalidraw/components/canvases/StaticCanvas.d.ts +4 -3
  114. package/dist/excalidraw/components/canvases/StaticCanvas.js +7 -5
  115. package/dist/excalidraw/components/dropdownMenu/DropdownMenuContent.js +22 -2
  116. package/dist/excalidraw/components/dropdownMenu/common.d.ts +1 -1
  117. package/dist/excalidraw/components/hyperlink/Hyperlink.d.ts +19 -0
  118. package/dist/excalidraw/{element → components/hyperlink}/Hyperlink.js +40 -115
  119. package/dist/excalidraw/components/hyperlink/helpers.d.ts +7 -0
  120. package/dist/excalidraw/components/hyperlink/helpers.js +49 -0
  121. package/dist/excalidraw/components/icons.d.ts +2 -1
  122. package/dist/excalidraw/components/icons.js +2 -1
  123. package/dist/excalidraw/components/live-collaboration/LiveCollaborationTrigger.js +3 -2
  124. package/dist/excalidraw/components/main-menu/DefaultItems.js +5 -2
  125. package/dist/excalidraw/constants.d.ts +8 -0
  126. package/dist/excalidraw/constants.js +10 -0
  127. package/dist/excalidraw/data/blob.js +13 -14
  128. package/dist/excalidraw/data/filesystem.d.ts +1 -1
  129. package/dist/excalidraw/data/index.d.ts +2 -1
  130. package/dist/excalidraw/data/index.js +20 -16
  131. package/dist/excalidraw/data/json.d.ts +1 -1
  132. package/dist/excalidraw/data/json.js +5 -3
  133. package/dist/excalidraw/data/resave.d.ts +1 -1
  134. package/dist/excalidraw/data/resave.js +2 -2
  135. package/dist/excalidraw/data/restore.js +8 -13
  136. package/dist/excalidraw/data/transform.js +13 -9
  137. package/dist/excalidraw/distribute.d.ts +2 -2
  138. package/dist/excalidraw/distribute.js +2 -2
  139. package/dist/excalidraw/element/ElementCanvasButtons.d.ts +3 -2
  140. package/dist/excalidraw/element/ElementCanvasButtons.js +4 -4
  141. package/dist/excalidraw/element/binding.d.ts +9 -9
  142. package/dist/excalidraw/element/binding.js +61 -59
  143. package/dist/excalidraw/element/bounds.d.ts +5 -5
  144. package/dist/excalidraw/element/bounds.js +29 -32
  145. package/dist/excalidraw/element/collision.d.ts +11 -11
  146. package/dist/excalidraw/element/collision.js +49 -46
  147. package/dist/excalidraw/element/containerCache.d.ts +11 -0
  148. package/dist/excalidraw/element/containerCache.js +14 -0
  149. package/dist/excalidraw/element/dragElements.js +10 -19
  150. package/dist/excalidraw/element/embeddable.d.ts +11 -12
  151. package/dist/excalidraw/element/embeddable.js +17 -27
  152. package/dist/excalidraw/element/image.js +1 -2
  153. package/dist/excalidraw/element/index.d.ts +0 -1
  154. package/dist/excalidraw/element/index.js +0 -1
  155. package/dist/excalidraw/element/linearElementEditor.d.ts +35 -35
  156. package/dist/excalidraw/element/linearElementEditor.js +79 -80
  157. package/dist/excalidraw/element/newElement.d.ts +4 -6
  158. package/dist/excalidraw/element/newElement.js +11 -16
  159. package/dist/excalidraw/element/resizeElements.d.ts +6 -6
  160. package/dist/excalidraw/element/resizeElements.js +40 -46
  161. package/dist/excalidraw/element/resizeTest.d.ts +3 -3
  162. package/dist/excalidraw/element/resizeTest.js +4 -4
  163. package/dist/excalidraw/element/sizeHelpers.d.ts +2 -2
  164. package/dist/excalidraw/element/sizeHelpers.js +2 -2
  165. package/dist/excalidraw/element/textElement.d.ts +18 -20
  166. package/dist/excalidraw/element/textElement.js +80 -111
  167. package/dist/excalidraw/element/textWysiwyg.d.ts +1 -6
  168. package/dist/excalidraw/element/textWysiwyg.js +15 -37
  169. package/dist/excalidraw/element/transformHandles.d.ts +4 -4
  170. package/dist/excalidraw/element/transformHandles.js +6 -6
  171. package/dist/excalidraw/element/typeChecks.js +4 -1
  172. package/dist/excalidraw/element/types.d.ts +24 -11
  173. package/dist/excalidraw/emitter.d.ts +5 -9
  174. package/dist/excalidraw/emitter.js +12 -12
  175. package/dist/excalidraw/frame.d.ts +26 -20
  176. package/dist/excalidraw/frame.js +157 -84
  177. package/dist/excalidraw/groups.d.ts +3 -3
  178. package/dist/excalidraw/groups.js +11 -3
  179. package/dist/excalidraw/history.d.ts +1 -1
  180. package/dist/excalidraw/index.d.ts +7 -3
  181. package/dist/excalidraw/index.js +14 -5
  182. package/dist/excalidraw/laser-trails.d.ts +19 -0
  183. package/dist/excalidraw/laser-trails.js +95 -0
  184. package/dist/excalidraw/locales/en.json +9 -5
  185. package/dist/excalidraw/reactUtils.d.ts +14 -0
  186. package/dist/excalidraw/reactUtils.js +45 -0
  187. package/dist/excalidraw/renderer/helpers.d.ts +13 -0
  188. package/dist/excalidraw/renderer/helpers.js +39 -0
  189. package/dist/excalidraw/renderer/interactiveScene.d.ts +20 -0
  190. package/dist/excalidraw/renderer/{renderScene.js → interactiveScene.js} +199 -474
  191. package/dist/excalidraw/renderer/renderElement.d.ts +6 -6
  192. package/dist/excalidraw/renderer/renderElement.js +54 -366
  193. package/dist/excalidraw/renderer/staticScene.d.ts +11 -0
  194. package/dist/excalidraw/renderer/staticScene.js +205 -0
  195. package/dist/excalidraw/renderer/staticSvgScene.d.ts +5 -0
  196. package/dist/excalidraw/renderer/staticSvgScene.js +385 -0
  197. package/dist/excalidraw/scene/Fonts.js +2 -1
  198. package/dist/excalidraw/scene/Renderer.d.ts +1 -1
  199. package/dist/excalidraw/scene/Renderer.js +32 -20
  200. package/dist/excalidraw/scene/Scene.d.ts +10 -9
  201. package/dist/excalidraw/scene/Scene.js +45 -21
  202. package/dist/excalidraw/scene/Shape.d.ts +3 -1
  203. package/dist/excalidraw/scene/Shape.js +7 -5
  204. package/dist/excalidraw/scene/ShapeCache.d.ts +2 -1
  205. package/dist/excalidraw/scene/ShapeCache.js +1 -0
  206. package/dist/excalidraw/scene/comparisons.js +2 -1
  207. package/dist/excalidraw/scene/export.d.ts +3 -0
  208. package/dist/excalidraw/scene/export.js +20 -40
  209. package/dist/excalidraw/scene/index.d.ts +0 -1
  210. package/dist/excalidraw/scene/index.js +0 -1
  211. package/dist/excalidraw/scene/scrollbars.d.ts +1 -1
  212. package/dist/excalidraw/scene/scrollbars.js +1 -1
  213. package/dist/excalidraw/scene/selection.d.ts +5 -5
  214. package/dist/excalidraw/scene/selection.js +16 -14
  215. package/dist/excalidraw/scene/types.d.ts +11 -5
  216. package/dist/excalidraw/snapping.d.ts +7 -7
  217. package/dist/excalidraw/snapping.js +21 -20
  218. package/dist/excalidraw/types.d.ts +11 -12
  219. package/dist/excalidraw/utility-types.d.ts +5 -0
  220. package/dist/excalidraw/utils.d.ts +25 -16
  221. package/dist/excalidraw/utils.js +52 -45
  222. package/dist/{dev/en-RLIAOBCI.json → prod/en-TDNWCAOT.json} +9 -5
  223. package/dist/prod/index.css +1 -1
  224. package/dist/prod/index.js +45 -45
  225. package/dist/utils/export.d.ts +0 -6
  226. package/dist/utils/export.js +0 -6
  227. package/dist/utils/index.d.ts +3 -0
  228. package/dist/utils/index.js +3 -0
  229. package/dist/utils/withinBounds.js +2 -1
  230. package/package.json +4 -4
  231. package/dist/browser/dev/excalidraw-assets-dev/chunk-2W5GQUR4.js.map +0 -7
  232. package/dist/browser/dev/excalidraw-assets-dev/chunk-SUHLFFEF.js +0 -53449
  233. package/dist/browser/dev/excalidraw-assets-dev/chunk-SUHLFFEF.js.map +0 -7
  234. package/dist/browser/dev/excalidraw-assets-dev/image-NOPDRTTM.css +0 -5797
  235. package/dist/browser/dev/excalidraw-assets-dev/image-NOPDRTTM.css.map +0 -7
  236. package/dist/browser/prod/excalidraw-assets/chunk-HE2P7BQ6.js +0 -257
  237. package/dist/browser/prod/excalidraw-assets/chunk-OWLL6VOG.js +0 -11
  238. package/dist/browser/prod/excalidraw-assets/en-ERQOR3OC.js +0 -1
  239. package/dist/browser/prod/excalidraw-assets/image-DZ6B4AID.js +0 -1
  240. package/dist/browser/prod/excalidraw-assets/image-J2QCCYAR.css +0 -1
  241. package/dist/excalidraw/components/LaserTool/LaserPathManager.d.ts +0 -28
  242. package/dist/excalidraw/components/LaserTool/LaserPathManager.js +0 -225
  243. package/dist/excalidraw/components/LaserTool/LaserTool.d.ts +0 -8
  244. package/dist/excalidraw/components/LaserTool/LaserTool.js +0 -15
  245. package/dist/excalidraw/renderer/renderScene.d.ts +0 -25
  246. package/dist/excalidraw/vite.config.d.mts +0 -2
  247. package/dist/excalidraw/vite.config.mjs +0 -13
  248. /package/dist/browser/dev/excalidraw-assets-dev/{en-OC6JWP3X.js.map → en-IOBA4CS2.js.map} +0 -0
  249. /package/dist/browser/dev/excalidraw-assets-dev/{image-HYNUJ3XL.js.map → image-VKDAL6BQ.js.map} +0 -0
@@ -2,7 +2,6 @@ import { distance2d, rotate, isPathALoop, getGridPoint, rotatePoint, centerPoint
2
2
  import { getElementAbsoluteCoords, getLockedLinearCursorAlignSize } from ".";
3
3
  import { getCurvePathOps, getElementPointsCoords, getMinMaxXYFromCurvePathOps, } from "./bounds";
4
4
  import { mutateElement } from "./mutateElement";
5
- import Scene from "../scene/Scene";
6
5
  import { bindOrUnbindLinearElement, getHoveredElementForBinding, isBindingEnabled, } from "./binding";
7
6
  import { tupleToCoors } from "../utils";
8
7
  import { isBindingElement } from "./typeChecks";
@@ -24,9 +23,8 @@ export class LinearElementEditor {
24
23
  endBindingElement;
25
24
  hoverPointIndex;
26
25
  segmentMidPointHoveredCoords;
27
- constructor(element, scene) {
26
+ constructor(element) {
28
27
  this.elementId = element.id;
29
- Scene.mapElementToScene(this.elementId, scene);
30
28
  LinearElementEditor.normalizePoints(element);
31
29
  this.selectedPointsIndices = null;
32
30
  this.lastUncommittedPoint = null;
@@ -55,26 +53,26 @@ export class LinearElementEditor {
55
53
  * @param id the `elementId` from the instance of this class (so that we can
56
54
  * statically guarantee this method returns an ExcalidrawLinearElement)
57
55
  */
58
- static getElement(id) {
59
- const element = Scene.getScene(id)?.getNonDeletedElement(id);
56
+ static getElement(id, elementsMap) {
57
+ const element = elementsMap.get(id);
60
58
  if (element) {
61
59
  return element;
62
60
  }
63
61
  return null;
64
62
  }
65
- static handleBoxSelection(event, appState, setState) {
63
+ static handleBoxSelection(event, appState, setState, elementsMap) {
66
64
  if (!appState.editingLinearElement ||
67
65
  appState.draggingElement?.type !== "selection") {
68
66
  return false;
69
67
  }
70
68
  const { editingLinearElement } = appState;
71
69
  const { selectedPointsIndices, elementId } = editingLinearElement;
72
- const element = LinearElementEditor.getElement(elementId);
70
+ const element = LinearElementEditor.getElement(elementId, elementsMap);
73
71
  if (!element) {
74
72
  return false;
75
73
  }
76
- const [selectionX1, selectionY1, selectionX2, selectionY2] = getElementAbsoluteCoords(appState.draggingElement);
77
- const pointsSceneCoords = LinearElementEditor.getPointsGlobalCoordinates(element);
74
+ const [selectionX1, selectionY1, selectionX2, selectionY2] = getElementAbsoluteCoords(appState.draggingElement, elementsMap);
75
+ const pointsSceneCoords = LinearElementEditor.getPointsGlobalCoordinates(element, elementsMap);
78
76
  const nextSelectedPoints = pointsSceneCoords.reduce((acc, point, index) => {
79
77
  if ((point[0] >= selectionX1 &&
80
78
  point[0] <= selectionX2 &&
@@ -95,12 +93,12 @@ export class LinearElementEditor {
95
93
  });
96
94
  }
97
95
  /** @returns whether point was dragged */
98
- static handlePointDragging(event, appState, scenePointerX, scenePointerY, maybeSuggestBinding, linearElementEditor) {
96
+ static handlePointDragging(event, appState, scenePointerX, scenePointerY, maybeSuggestBinding, linearElementEditor, elementsMap) {
99
97
  if (!linearElementEditor) {
100
98
  return false;
101
99
  }
102
100
  const { selectedPointsIndices, elementId } = linearElementEditor;
103
- const element = LinearElementEditor.getElement(elementId);
101
+ const element = LinearElementEditor.getElement(elementId, elementsMap);
104
102
  if (!element) {
105
103
  return false;
106
104
  }
@@ -112,7 +110,7 @@ export class LinearElementEditor {
112
110
  element.points.length > 1) {
113
111
  const selectedIndex = selectedPointsIndices[0];
114
112
  const referencePoint = element.points[selectedIndex === 0 ? 1 : selectedIndex - 1];
115
- const [width, height] = LinearElementEditor._getShiftLockedDelta(element, referencePoint, [scenePointerX, scenePointerY], event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize);
113
+ const [width, height] = LinearElementEditor._getShiftLockedDelta(element, elementsMap, referencePoint, [scenePointerX, scenePointerY], event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize);
116
114
  LinearElementEditor.movePoints(element, [
117
115
  {
118
116
  index: selectedIndex,
@@ -123,13 +121,13 @@ export class LinearElementEditor {
123
121
  ]);
124
122
  }
125
123
  else {
126
- const newDraggingPointPosition = LinearElementEditor.createPointAt(element, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize);
124
+ const newDraggingPointPosition = LinearElementEditor.createPointAt(element, elementsMap, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize);
127
125
  const deltaX = newDraggingPointPosition[0] - draggingPoint[0];
128
126
  const deltaY = newDraggingPointPosition[1] - draggingPoint[1];
129
127
  LinearElementEditor.movePoints(element, selectedPointsIndices.map((pointIndex) => {
130
128
  const newPointPosition = pointIndex ===
131
129
  linearElementEditor.pointerDownState.lastClickedPoint
132
- ? LinearElementEditor.createPointAt(element, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize)
130
+ ? LinearElementEditor.createPointAt(element, elementsMap, scenePointerX - linearElementEditor.pointerOffset.x, scenePointerY - linearElementEditor.pointerOffset.y, event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize)
133
131
  : [
134
132
  element.points[pointIndex][0] + deltaX,
135
133
  element.points[pointIndex][1] + deltaY,
@@ -142,20 +140,20 @@ export class LinearElementEditor {
142
140
  };
143
141
  }));
144
142
  }
145
- const boundTextElement = getBoundTextElement(element);
143
+ const boundTextElement = getBoundTextElement(element, elementsMap);
146
144
  if (boundTextElement) {
147
- handleBindTextResize(element, false);
145
+ handleBindTextResize(element, elementsMap, false);
148
146
  }
149
147
  // suggest bindings for first and last point if selected
150
148
  if (isBindingElement(element, false)) {
151
149
  const coords = [];
152
150
  const firstSelectedIndex = selectedPointsIndices[0];
153
151
  if (firstSelectedIndex === 0) {
154
- coords.push(tupleToCoors(LinearElementEditor.getPointGlobalCoordinates(element, element.points[0])));
152
+ coords.push(tupleToCoors(LinearElementEditor.getPointGlobalCoordinates(element, element.points[0], elementsMap)));
155
153
  }
156
154
  const lastSelectedIndex = selectedPointsIndices[selectedPointsIndices.length - 1];
157
155
  if (lastSelectedIndex === element.points.length - 1) {
158
- coords.push(tupleToCoors(LinearElementEditor.getPointGlobalCoordinates(element, element.points[lastSelectedIndex])));
156
+ coords.push(tupleToCoors(LinearElementEditor.getPointGlobalCoordinates(element, element.points[lastSelectedIndex], elementsMap)));
159
157
  }
160
158
  if (coords.length) {
161
159
  maybeSuggestBinding(element, coords);
@@ -165,9 +163,9 @@ export class LinearElementEditor {
165
163
  }
166
164
  return false;
167
165
  }
168
- static handlePointerUp(event, editingLinearElement, appState) {
166
+ static handlePointerUp(event, editingLinearElement, appState, elements, elementsMap) {
169
167
  const { elementId, selectedPointsIndices, isDragging, pointerDownState } = editingLinearElement;
170
- const element = LinearElementEditor.getElement(elementId);
168
+ const element = LinearElementEditor.getElement(elementId, elementsMap);
171
169
  if (!element) {
172
170
  return editingLinearElement;
173
171
  }
@@ -187,7 +185,7 @@ export class LinearElementEditor {
187
185
  ]);
188
186
  }
189
187
  const bindingElement = isBindingEnabled(appState)
190
- ? getHoveredElementForBinding(tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(element, selectedPoint)), Scene.getScene(element))
188
+ ? getHoveredElementForBinding(tupleToCoors(LinearElementEditor.getPointAtIndexGlobalCoordinates(element, selectedPoint, elementsMap)), elements, elementsMap)
191
189
  : null;
192
190
  bindings[selectedPoint === 0 ? "startBindingElement" : "endBindingElement"] = bindingElement;
193
191
  }
@@ -213,8 +211,8 @@ export class LinearElementEditor {
213
211
  pointerOffset: { x: 0, y: 0 },
214
212
  };
215
213
  }
216
- static getEditorMidPoints = (element, appState) => {
217
- const boundText = getBoundTextElement(element);
214
+ static getEditorMidPoints = (element, elementsMap, appState) => {
215
+ const boundText = getBoundTextElement(element, elementsMap);
218
216
  // Since its not needed outside editor unless 2 pointer lines or bound text
219
217
  if (!appState.editingLinearElement &&
220
218
  element.points.length > 2 &&
@@ -225,11 +223,11 @@ export class LinearElementEditor {
225
223
  editorMidPointsCache.zoom === appState.zoom.value) {
226
224
  return editorMidPointsCache.points;
227
225
  }
228
- LinearElementEditor.updateEditorMidPointsCache(element, appState);
226
+ LinearElementEditor.updateEditorMidPointsCache(element, elementsMap, appState);
229
227
  return editorMidPointsCache.points;
230
228
  };
231
- static updateEditorMidPointsCache = (element, appState) => {
232
- const points = LinearElementEditor.getPointsGlobalCoordinates(element);
229
+ static updateEditorMidPointsCache = (element, elementsMap, appState) => {
230
+ const points = LinearElementEditor.getPointsGlobalCoordinates(element, elementsMap);
233
231
  let index = 0;
234
232
  const midpoints = [];
235
233
  while (index < points.length - 1) {
@@ -238,7 +236,7 @@ export class LinearElementEditor {
238
236
  index++;
239
237
  continue;
240
238
  }
241
- const segmentMidPoint = LinearElementEditor.getSegmentMidPoint(element, points[index], points[index + 1], index + 1);
239
+ const segmentMidPoint = LinearElementEditor.getSegmentMidPoint(element, points[index], points[index + 1], index + 1, elementsMap);
242
240
  midpoints.push(segmentMidPoint);
243
241
  index++;
244
242
  }
@@ -246,17 +244,17 @@ export class LinearElementEditor {
246
244
  editorMidPointsCache.version = element.version;
247
245
  editorMidPointsCache.zoom = appState.zoom.value;
248
246
  };
249
- static getSegmentMidpointHitCoords = (linearElementEditor, scenePointer, appState) => {
247
+ static getSegmentMidpointHitCoords = (linearElementEditor, scenePointer, appState, elementsMap) => {
250
248
  const { elementId } = linearElementEditor;
251
- const element = LinearElementEditor.getElement(elementId);
249
+ const element = LinearElementEditor.getElement(elementId, elementsMap);
252
250
  if (!element) {
253
251
  return null;
254
252
  }
255
- const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(element, appState.zoom, scenePointer.x, scenePointer.y);
253
+ const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(element, elementsMap, appState.zoom, scenePointer.x, scenePointer.y);
256
254
  if (clickedPointIndex >= 0) {
257
255
  return null;
258
256
  }
259
- const points = LinearElementEditor.getPointsGlobalCoordinates(element);
257
+ const points = LinearElementEditor.getPointsGlobalCoordinates(element, elementsMap);
260
258
  if (points.length >= 3 && !appState.editingLinearElement) {
261
259
  return null;
262
260
  }
@@ -269,7 +267,7 @@ export class LinearElementEditor {
269
267
  }
270
268
  }
271
269
  let index = 0;
272
- const midPoints = LinearElementEditor.getEditorMidPoints(element, appState);
270
+ const midPoints = LinearElementEditor.getEditorMidPoints(element, elementsMap, appState);
273
271
  while (index < midPoints.length) {
274
272
  if (midPoints[index] !== null) {
275
273
  const distance = distance2d(midPoints[index][0], midPoints[index][1], scenePointer.x, scenePointer.y);
@@ -288,24 +286,24 @@ export class LinearElementEditor {
288
286
  }
289
287
  return distance * zoom.value < LinearElementEditor.POINT_HANDLE_SIZE * 4;
290
288
  }
291
- static getSegmentMidPoint(element, startPoint, endPoint, endPointIndex) {
289
+ static getSegmentMidPoint(element, startPoint, endPoint, endPointIndex, elementsMap) {
292
290
  let segmentMidPoint = centerPoint(startPoint, endPoint);
293
291
  if (element.points.length > 2 && element.roundness) {
294
292
  const controlPoints = getControlPointsForBezierCurve(element, element.points[endPointIndex]);
295
293
  if (controlPoints) {
296
294
  const t = mapIntervalToBezierT(element, element.points[endPointIndex], 0.5);
297
295
  const [tx, ty] = getBezierXY(controlPoints[0], controlPoints[1], controlPoints[2], controlPoints[3], t);
298
- segmentMidPoint = LinearElementEditor.getPointGlobalCoordinates(element, [tx, ty]);
296
+ segmentMidPoint = LinearElementEditor.getPointGlobalCoordinates(element, [tx, ty], elementsMap);
299
297
  }
300
298
  }
301
299
  return segmentMidPoint;
302
300
  }
303
- static getSegmentMidPointIndex(linearElementEditor, appState, midPoint) {
304
- const element = LinearElementEditor.getElement(linearElementEditor.elementId);
301
+ static getSegmentMidPointIndex(linearElementEditor, appState, midPoint, elementsMap) {
302
+ const element = LinearElementEditor.getElement(linearElementEditor.elementId, elementsMap);
305
303
  if (!element) {
306
304
  return -1;
307
305
  }
308
- const midPoints = LinearElementEditor.getEditorMidPoints(element, appState);
306
+ const midPoints = LinearElementEditor.getEditorMidPoints(element, elementsMap, appState);
309
307
  let index = 0;
310
308
  while (index < midPoints.length) {
311
309
  if (LinearElementEditor.arePointsEqual(midPoint, midPoints[index])) {
@@ -315,7 +313,7 @@ export class LinearElementEditor {
315
313
  }
316
314
  return -1;
317
315
  }
318
- static handlePointerDown(event, appState, history, scenePointer, linearElementEditor) {
316
+ static handlePointerDown(event, appState, history, scenePointer, linearElementEditor, elements, elementsMap) {
319
317
  const ret = {
320
318
  didAddPoint: false,
321
319
  hitElement: null,
@@ -325,21 +323,21 @@ export class LinearElementEditor {
325
323
  return ret;
326
324
  }
327
325
  const { elementId } = linearElementEditor;
328
- const element = LinearElementEditor.getElement(elementId);
326
+ const element = LinearElementEditor.getElement(elementId, elementsMap);
329
327
  if (!element) {
330
328
  return ret;
331
329
  }
332
- const segmentMidpoint = LinearElementEditor.getSegmentMidpointHitCoords(linearElementEditor, scenePointer, appState);
330
+ const segmentMidpoint = LinearElementEditor.getSegmentMidpointHitCoords(linearElementEditor, scenePointer, appState, elementsMap);
333
331
  let segmentMidpointIndex = null;
334
332
  if (segmentMidpoint) {
335
- segmentMidpointIndex = LinearElementEditor.getSegmentMidPointIndex(linearElementEditor, appState, segmentMidpoint);
333
+ segmentMidpointIndex = LinearElementEditor.getSegmentMidPointIndex(linearElementEditor, appState, segmentMidpoint, elementsMap);
336
334
  }
337
335
  if (event.altKey && appState.editingLinearElement) {
338
336
  if (linearElementEditor.lastUncommittedPoint == null) {
339
337
  mutateElement(element, {
340
338
  points: [
341
339
  ...element.points,
342
- LinearElementEditor.createPointAt(element, scenePointer.x, scenePointer.y, event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize),
340
+ LinearElementEditor.createPointAt(element, elementsMap, scenePointer.x, scenePointer.y, event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize),
343
341
  ],
344
342
  });
345
343
  ret.didAddPoint = true;
@@ -359,12 +357,12 @@ export class LinearElementEditor {
359
357
  },
360
358
  selectedPointsIndices: [element.points.length - 1],
361
359
  lastUncommittedPoint: null,
362
- endBindingElement: getHoveredElementForBinding(scenePointer, Scene.getScene(element)),
360
+ endBindingElement: getHoveredElementForBinding(scenePointer, elements, elementsMap),
363
361
  };
364
362
  ret.didAddPoint = true;
365
363
  return ret;
366
364
  }
367
- const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(element, appState.zoom, scenePointer.x, scenePointer.y);
365
+ const clickedPointIndex = LinearElementEditor.getPointIndexUnderCursor(element, elementsMap, appState.zoom, scenePointer.x, scenePointer.y);
368
366
  // if we clicked on a point, set the element as hitElement otherwise
369
367
  // it would get deselected if the point is outside the hitbox area
370
368
  if (clickedPointIndex >= 0 || segmentMidpoint) {
@@ -378,10 +376,10 @@ export class LinearElementEditor {
378
376
  // the point).
379
377
  const { startBindingElement, endBindingElement } = linearElementEditor;
380
378
  if (isBindingEnabled(appState) && isBindingElement(element)) {
381
- bindOrUnbindLinearElement(element, startBindingElement, endBindingElement);
379
+ bindOrUnbindLinearElement(element, startBindingElement, endBindingElement, elementsMap);
382
380
  }
383
381
  }
384
- const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
382
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
385
383
  const cx = (x1 + x2) / 2;
386
384
  const cy = (y1 + y2) / 2;
387
385
  const targetPoint = clickedPointIndex > -1 &&
@@ -426,12 +424,12 @@ export class LinearElementEditor {
426
424
  }
427
425
  return arePointsEqual(point1, point2);
428
426
  }
429
- static handlePointerMove(event, scenePointerX, scenePointerY, appState) {
427
+ static handlePointerMove(event, scenePointerX, scenePointerY, appState, elementsMap) {
430
428
  if (!appState.editingLinearElement) {
431
429
  return null;
432
430
  }
433
431
  const { elementId, lastUncommittedPoint } = appState.editingLinearElement;
434
- const element = LinearElementEditor.getElement(elementId);
432
+ const element = LinearElementEditor.getElement(elementId, elementsMap);
435
433
  if (!element) {
436
434
  return appState.editingLinearElement;
437
435
  }
@@ -449,14 +447,14 @@ export class LinearElementEditor {
449
447
  let newPoint;
450
448
  if (shouldRotateWithDiscreteAngle(event) && points.length >= 2) {
451
449
  const lastCommittedPoint = points[points.length - 2];
452
- const [width, height] = LinearElementEditor._getShiftLockedDelta(element, lastCommittedPoint, [scenePointerX, scenePointerY], event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize);
450
+ const [width, height] = LinearElementEditor._getShiftLockedDelta(element, elementsMap, lastCommittedPoint, [scenePointerX, scenePointerY], event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize);
453
451
  newPoint = [
454
452
  width + lastCommittedPoint[0],
455
453
  height + lastCommittedPoint[1],
456
454
  ];
457
455
  }
458
456
  else {
459
- newPoint = LinearElementEditor.createPointAt(element, scenePointerX - appState.editingLinearElement.pointerOffset.x, scenePointerY - appState.editingLinearElement.pointerOffset.y, event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize);
457
+ newPoint = LinearElementEditor.createPointAt(element, elementsMap, scenePointerX - appState.editingLinearElement.pointerOffset.x, scenePointerY - appState.editingLinearElement.pointerOffset.y, event[KEYS.CTRL_OR_CMD] ? null : appState.gridSize);
460
458
  }
461
459
  if (lastPoint === lastUncommittedPoint) {
462
460
  LinearElementEditor.movePoints(element, [
@@ -475,8 +473,8 @@ export class LinearElementEditor {
475
473
  };
476
474
  }
477
475
  /** scene coords */
478
- static getPointGlobalCoordinates(element, point) {
479
- const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
476
+ static getPointGlobalCoordinates(element, point, elementsMap) {
477
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
480
478
  const cx = (x1 + x2) / 2;
481
479
  const cy = (y1 + y2) / 2;
482
480
  let { x, y } = element;
@@ -484,8 +482,8 @@ export class LinearElementEditor {
484
482
  return [x, y];
485
483
  }
486
484
  /** scene coords */
487
- static getPointsGlobalCoordinates(element) {
488
- const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
485
+ static getPointsGlobalCoordinates(element, elementsMap) {
486
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
489
487
  const cx = (x1 + x2) / 2;
490
488
  const cy = (y1 + y2) / 2;
491
489
  return element.points.map((point) => {
@@ -494,11 +492,12 @@ export class LinearElementEditor {
494
492
  return [x, y];
495
493
  });
496
494
  }
497
- static getPointAtIndexGlobalCoordinates(element, indexMaybeFromEnd) {
495
+ static getPointAtIndexGlobalCoordinates(element, indexMaybeFromEnd, // -1 for last element
496
+ elementsMap) {
498
497
  const index = indexMaybeFromEnd < 0
499
498
  ? element.points.length + indexMaybeFromEnd
500
499
  : indexMaybeFromEnd;
501
- const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
500
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
502
501
  const cx = (x1 + x2) / 2;
503
502
  const cy = (y1 + y2) / 2;
504
503
  const point = element.points[index];
@@ -507,15 +506,15 @@ export class LinearElementEditor {
507
506
  ? rotate(x + point[0], y + point[1], cx, cy, element.angle)
508
507
  : rotate(x, y, cx, cy, element.angle);
509
508
  }
510
- static pointFromAbsoluteCoords(element, absoluteCoords) {
511
- const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
509
+ static pointFromAbsoluteCoords(element, absoluteCoords, elementsMap) {
510
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
512
511
  const cx = (x1 + x2) / 2;
513
512
  const cy = (y1 + y2) / 2;
514
513
  const [x, y] = rotate(absoluteCoords[0], absoluteCoords[1], cx, cy, -element.angle);
515
514
  return [x - element.x, y - element.y];
516
515
  }
517
- static getPointIndexUnderCursor(element, zoom, x, y) {
518
- const pointHandles = LinearElementEditor.getPointsGlobalCoordinates(element);
516
+ static getPointIndexUnderCursor(element, elementsMap, zoom, x, y) {
517
+ const pointHandles = LinearElementEditor.getPointsGlobalCoordinates(element, elementsMap);
519
518
  let idx = pointHandles.length;
520
519
  // loop from right to left because points on the right are rendered over
521
520
  // points on the left, thus should take precedence when clicking, if they
@@ -530,9 +529,9 @@ export class LinearElementEditor {
530
529
  }
531
530
  return -1;
532
531
  }
533
- static createPointAt(element, scenePointerX, scenePointerY, gridSize) {
532
+ static createPointAt(element, elementsMap, scenePointerX, scenePointerY, gridSize) {
534
533
  const pointerOnGrid = getGridPoint(scenePointerX, scenePointerY, gridSize);
535
- const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
534
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
536
535
  const cx = (x1 + x2) / 2;
537
536
  const cy = (y1 + y2) / 2;
538
537
  const [rotatedX, rotatedY] = rotate(pointerOnGrid[0], pointerOnGrid[1], cx, cy, -element.angle);
@@ -560,12 +559,12 @@ export class LinearElementEditor {
560
559
  static normalizePoints(element) {
561
560
  mutateElement(element, LinearElementEditor.getNormalizedPoints(element));
562
561
  }
563
- static duplicateSelectedPoints(appState) {
562
+ static duplicateSelectedPoints(appState, elementsMap) {
564
563
  if (!appState.editingLinearElement) {
565
564
  return false;
566
565
  }
567
566
  const { selectedPointsIndices, elementId } = appState.editingLinearElement;
568
- const element = LinearElementEditor.getElement(elementId);
567
+ const element = LinearElementEditor.getElement(elementId, elementsMap);
569
568
  if (!element || selectedPointsIndices === null) {
570
569
  return false;
571
570
  }
@@ -673,8 +672,8 @@ export class LinearElementEditor {
673
672
  });
674
673
  LinearElementEditor._updatePoints(element, nextPoints, offsetX, offsetY, otherUpdates);
675
674
  }
676
- static shouldAddMidpoint(linearElementEditor, pointerCoords, appState) {
677
- const element = LinearElementEditor.getElement(linearElementEditor.elementId);
675
+ static shouldAddMidpoint(linearElementEditor, pointerCoords, appState, elementsMap) {
676
+ const element = LinearElementEditor.getElement(linearElementEditor.elementId, elementsMap);
678
677
  if (!element) {
679
678
  return false;
680
679
  }
@@ -693,8 +692,8 @@ export class LinearElementEditor {
693
692
  }
694
693
  return true;
695
694
  }
696
- static addMidpoint(linearElementEditor, pointerCoords, appState, snapToGrid) {
697
- const element = LinearElementEditor.getElement(linearElementEditor.elementId);
695
+ static addMidpoint(linearElementEditor, pointerCoords, appState, snapToGrid, elementsMap) {
696
+ const element = LinearElementEditor.getElement(linearElementEditor.elementId, elementsMap);
698
697
  if (!element) {
699
698
  return;
700
699
  }
@@ -703,7 +702,7 @@ export class LinearElementEditor {
703
702
  pointerDownState: linearElementEditor.pointerDownState,
704
703
  selectedPointsIndices: linearElementEditor.selectedPointsIndices,
705
704
  };
706
- const midpoint = LinearElementEditor.createPointAt(element, pointerCoords.x, pointerCoords.y, snapToGrid ? appState.gridSize : null);
705
+ const midpoint = LinearElementEditor.createPointAt(element, elementsMap, pointerCoords.x, pointerCoords.y, snapToGrid ? appState.gridSize : null);
707
706
  const points = [
708
707
  ...element.points.slice(0, segmentMidpoint.index),
709
708
  midpoint,
@@ -740,14 +739,14 @@ export class LinearElementEditor {
740
739
  y: element.y + rotated[1],
741
740
  });
742
741
  }
743
- static _getShiftLockedDelta(element, referencePoint, scenePointer, gridSize) {
744
- const referencePointCoords = LinearElementEditor.getPointGlobalCoordinates(element, referencePoint);
742
+ static _getShiftLockedDelta(element, elementsMap, referencePoint, scenePointer, gridSize) {
743
+ const referencePointCoords = LinearElementEditor.getPointGlobalCoordinates(element, referencePoint, elementsMap);
745
744
  const [gridX, gridY] = getGridPoint(scenePointer[0], scenePointer[1], gridSize);
746
745
  const { width, height } = getLockedLinearCursorAlignSize(referencePointCoords[0], referencePointCoords[1], gridX, gridY);
747
746
  return rotatePoint([width, height], [0, 0], -element.angle);
748
747
  }
749
- static getBoundTextElementPosition = (element, boundTextElement) => {
750
- const points = LinearElementEditor.getPointsGlobalCoordinates(element);
748
+ static getBoundTextElementPosition = (element, boundTextElement, elementsMap) => {
749
+ const points = LinearElementEditor.getPointsGlobalCoordinates(element, elementsMap);
751
750
  if (points.length < 2) {
752
751
  mutateElement(boundTextElement, { isDeleted: true });
753
752
  }
@@ -755,7 +754,7 @@ export class LinearElementEditor {
755
754
  let y = 0;
756
755
  if (element.points.length % 2 === 1) {
757
756
  const index = Math.floor(element.points.length / 2);
758
- const midPoint = LinearElementEditor.getPointGlobalCoordinates(element, element.points[index]);
757
+ const midPoint = LinearElementEditor.getPointGlobalCoordinates(element, element.points[index], elementsMap);
759
758
  x = midPoint[0] - boundTextElement.width / 2;
760
759
  y = midPoint[1] - boundTextElement.height / 2;
761
760
  }
@@ -767,18 +766,18 @@ export class LinearElementEditor {
767
766
  }
768
767
  if (!midSegmentMidpoint ||
769
768
  editorMidPointsCache.version !== element.version) {
770
- midSegmentMidpoint = LinearElementEditor.getSegmentMidPoint(element, points[index], points[index + 1], index + 1);
769
+ midSegmentMidpoint = LinearElementEditor.getSegmentMidPoint(element, points[index], points[index + 1], index + 1, elementsMap);
771
770
  }
772
771
  x = midSegmentMidpoint[0] - boundTextElement.width / 2;
773
772
  y = midSegmentMidpoint[1] - boundTextElement.height / 2;
774
773
  }
775
774
  return { x, y };
776
775
  };
777
- static getMinMaxXYWithBoundText = (element, elementBounds, boundTextElement) => {
776
+ static getMinMaxXYWithBoundText = (element, elementsMap, elementBounds, boundTextElement) => {
778
777
  let [x1, y1, x2, y2] = elementBounds;
779
778
  const cx = (x1 + x2) / 2;
780
779
  const cy = (y1 + y2) / 2;
781
- const { x: boundTextX1, y: boundTextY1 } = LinearElementEditor.getBoundTextElementPosition(element, boundTextElement);
780
+ const { x: boundTextX1, y: boundTextY1 } = LinearElementEditor.getBoundTextElementPosition(element, boundTextElement, elementsMap);
782
781
  const boundTextX2 = boundTextX1 + boundTextElement.width;
783
782
  const boundTextY2 = boundTextY1 + boundTextElement.height;
784
783
  const topLeftRotatedPoint = rotatePoint([x1, y1], [cx, cy], element.angle);
@@ -815,7 +814,7 @@ export class LinearElementEditor {
815
814
  }
816
815
  return [x1, y1, x2, y2, cx, cy];
817
816
  };
818
- static getElementAbsoluteCoords = (element, includeBoundText = false) => {
817
+ static getElementAbsoluteCoords = (element, elementsMap, includeBoundText = false) => {
819
818
  let coords;
820
819
  let x1;
821
820
  let y1;
@@ -851,9 +850,9 @@ export class LinearElementEditor {
851
850
  if (!includeBoundText) {
852
851
  return coords;
853
852
  }
854
- const boundTextElement = getBoundTextElement(element);
853
+ const boundTextElement = getBoundTextElement(element, elementsMap);
855
854
  if (boundTextElement) {
856
- coords = LinearElementEditor.getMinMaxXYWithBoundText(element, [x1, y1, x2, y2], boundTextElement);
855
+ coords = LinearElementEditor.getMinMaxXYWithBoundText(element, elementsMap, [x1, y1, x2, y2], boundTextElement);
857
856
  }
858
857
  return coords;
859
858
  };
@@ -1,13 +1,12 @@
1
- import { ExcalidrawElement, ExcalidrawImageElement, ExcalidrawTextElement, ExcalidrawLinearElement, ExcalidrawGenericElement, NonDeleted, TextAlign, GroupId, VerticalAlign, Arrowhead, ExcalidrawFreeDrawElement, FontFamilyValues, ExcalidrawTextContainer, ExcalidrawFrameElement, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawIframeElement } from "./types";
1
+ import { ExcalidrawElement, ExcalidrawImageElement, ExcalidrawTextElement, ExcalidrawLinearElement, ExcalidrawGenericElement, NonDeleted, TextAlign, GroupId, VerticalAlign, Arrowhead, ExcalidrawFreeDrawElement, FontFamilyValues, ExcalidrawTextContainer, ExcalidrawFrameElement, ExcalidrawEmbeddableElement, ExcalidrawMagicFrameElement, ExcalidrawIframeElement, ElementsMap } from "./types";
2
2
  import { AppState } from "../types";
3
3
  import { MarkOptional, Mutable } from "../utility-types";
4
- export type ElementConstructorOpts = MarkOptional<Omit<ExcalidrawGenericElement, "id" | "type" | "isDeleted" | "updated">, "width" | "height" | "angle" | "groupIds" | "frameId" | "boundElements" | "seed" | "version" | "versionNonce" | "link" | "strokeStyle" | "fillStyle" | "strokeColor" | "backgroundColor" | "roughness" | "strokeWidth" | "roundness" | "locked" | "opacity">;
4
+ export type ElementConstructorOpts = MarkOptional<Omit<ExcalidrawGenericElement, "id" | "type" | "isDeleted" | "updated">, "width" | "height" | "angle" | "groupIds" | "frameId" | "boundElements" | "seed" | "version" | "versionNonce" | "link" | "strokeStyle" | "fillStyle" | "strokeColor" | "backgroundColor" | "roughness" | "strokeWidth" | "roundness" | "locked" | "opacity" | "customData">;
5
5
  export declare const newElement: (opts: {
6
6
  type: ExcalidrawGenericElement["type"];
7
7
  } & ElementConstructorOpts) => NonDeleted<ExcalidrawGenericElement>;
8
8
  export declare const newEmbeddableElement: (opts: {
9
9
  type: "embeddable";
10
- validated: ExcalidrawEmbeddableElement["validated"];
11
10
  } & ElementConstructorOpts) => NonDeleted<ExcalidrawEmbeddableElement>;
12
11
  export declare const newIframeElement: (opts: {
13
12
  type: "iframe";
@@ -28,15 +27,14 @@ export declare const newTextElement: (opts: {
28
27
  lineHeight?: ExcalidrawTextElement["lineHeight"];
29
28
  strokeWidth?: ExcalidrawTextElement["strokeWidth"];
30
29
  } & ElementConstructorOpts) => NonDeleted<ExcalidrawTextElement>;
31
- export declare const refreshTextDimensions: (textElement: ExcalidrawTextElement, text?: string) => {
30
+ export declare const refreshTextDimensions: (textElement: ExcalidrawTextElement, container: ExcalidrawTextContainer | null, elementsMap: ElementsMap, text?: string) => {
32
31
  x: number;
33
32
  y: number;
34
33
  width: number;
35
34
  height: number;
36
- baseline: number;
37
35
  text: string;
38
36
  } | undefined;
39
- export declare const updateTextElement: (textElement: ExcalidrawTextElement, { text, isDeleted, originalText, }: {
37
+ export declare const updateTextElement: (textElement: ExcalidrawTextElement, container: ExcalidrawTextContainer | null, elementsMap: ElementsMap, { text, isDeleted, originalText, }: {
40
38
  text: string;
41
39
  isDeleted?: boolean | undefined;
42
40
  originalText: string;
@@ -5,7 +5,7 @@ import { getNewGroupIdsForDuplication } from "../groups";
5
5
  import { getElementAbsoluteCoords } from ".";
6
6
  import { adjustXYWithRotation } from "../math";
7
7
  import { getResizedElementAbsoluteCoords } from "./bounds";
8
- import { getContainerElement, measureText, normalizeText, wrapText, getBoundTextMaxWidth, getDefaultLineHeight, } from "./textElement";
8
+ import { measureText, normalizeText, wrapText, getBoundTextMaxWidth, getDefaultLineHeight, } from "./textElement";
9
9
  import { DEFAULT_ELEMENT_PROPS, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_TEXT_ALIGN, DEFAULT_VERTICAL_ALIGN, VERTICAL_ALIGN, } from "../constants";
10
10
  const _newElementBase = (type, { x, y, strokeColor = DEFAULT_ELEMENT_PROPS.strokeColor, backgroundColor = DEFAULT_ELEMENT_PROPS.backgroundColor, fillStyle = DEFAULT_ELEMENT_PROPS.fillStyle, strokeWidth = DEFAULT_ELEMENT_PROPS.strokeWidth, strokeStyle = DEFAULT_ELEMENT_PROPS.strokeStyle, roughness = DEFAULT_ELEMENT_PROPS.roughness, opacity = DEFAULT_ELEMENT_PROPS.opacity, width = 0, height = 0, angle = 0, groupIds = [], frameId = null, roundness = null, boundElements = null, link = null, locked = DEFAULT_ELEMENT_PROPS.locked, ...rest }) => {
11
11
  // assign type to guard against excess properties
@@ -35,15 +35,13 @@ const _newElementBase = (type, { x, y, strokeColor = DEFAULT_ELEMENT_PROPS.strok
35
35
  updated: getUpdatedTimestamp(),
36
36
  link,
37
37
  locked,
38
+ customData: rest.customData,
38
39
  };
39
40
  return element;
40
41
  };
41
42
  export const newElement = (opts) => _newElementBase(opts.type, opts);
42
43
  export const newEmbeddableElement = (opts) => {
43
- return {
44
- ..._newElementBase("embeddable", opts),
45
- validated: opts.validated,
46
- };
44
+ return _newElementBase("embeddable", opts);
47
45
  };
48
46
  export const newIframeElement = (opts) => {
49
47
  return {
@@ -97,15 +95,14 @@ export const newTextElement = (opts) => {
97
95
  y: opts.y - offsets.y,
98
96
  width: metrics.width,
99
97
  height: metrics.height,
100
- baseline: metrics.baseline,
101
98
  containerId: opts.containerId || null,
102
99
  originalText: text,
103
100
  lineHeight,
104
101
  }, {});
105
102
  return textElement;
106
103
  };
107
- const getAdjustedDimensions = (element, nextText) => {
108
- const { width: nextWidth, height: nextHeight, baseline: nextBaseline, } = measureText(nextText, getFontString(element), element.lineHeight);
104
+ const getAdjustedDimensions = (element, elementsMap, nextText) => {
105
+ const { width: nextWidth, height: nextHeight } = measureText(nextText, getFontString(element), element.lineHeight);
109
106
  const { textAlign, verticalAlign } = element;
110
107
  let x;
111
108
  let y;
@@ -121,7 +118,7 @@ const getAdjustedDimensions = (element, nextText) => {
121
118
  y = element.y - offsets.y;
122
119
  }
123
120
  else {
124
- const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
121
+ const [x1, y1, x2, y2] = getElementAbsoluteCoords(element, elementsMap);
125
122
  const [nextX1, nextY1, nextX2, nextY2] = getResizedElementAbsoluteCoords(element, nextWidth, nextHeight, false);
126
123
  const deltaX1 = (x1 - nextX1) / 2;
127
124
  const deltaY1 = (y1 - nextY1) / 2;
@@ -136,27 +133,25 @@ const getAdjustedDimensions = (element, nextText) => {
136
133
  return {
137
134
  width: nextWidth,
138
135
  height: nextHeight,
139
- baseline: nextBaseline,
140
136
  x: Number.isFinite(x) ? x : element.x,
141
137
  y: Number.isFinite(y) ? y : element.y,
142
138
  };
143
139
  };
144
- export const refreshTextDimensions = (textElement, text = textElement.text) => {
140
+ export const refreshTextDimensions = (textElement, container, elementsMap, text = textElement.text) => {
145
141
  if (textElement.isDeleted) {
146
142
  return;
147
143
  }
148
- const container = getContainerElement(textElement);
149
144
  if (container) {
150
- text = wrapText(text, getFontString(textElement), getBoundTextMaxWidth(container));
145
+ text = wrapText(text, getFontString(textElement), getBoundTextMaxWidth(container, textElement));
151
146
  }
152
- const dimensions = getAdjustedDimensions(textElement, text);
147
+ const dimensions = getAdjustedDimensions(textElement, elementsMap, text);
153
148
  return { text, ...dimensions };
154
149
  };
155
- export const updateTextElement = (textElement, { text, isDeleted, originalText, }) => {
150
+ export const updateTextElement = (textElement, container, elementsMap, { text, isDeleted, originalText, }) => {
156
151
  return newElementWith(textElement, {
157
152
  originalText,
158
153
  isDeleted: isDeleted ?? textElement.isDeleted,
159
- ...refreshTextDimensions(textElement, originalText),
154
+ ...refreshTextDimensions(textElement, container, elementsMap, originalText),
160
155
  });
161
156
  };
162
157
  export const newFreeDrawElement = (opts) => {
@@ -1,9 +1,9 @@
1
- import { ExcalidrawLinearElement, NonDeletedExcalidrawElement, NonDeleted } from "./types";
1
+ import { ExcalidrawLinearElement, NonDeletedExcalidrawElement, NonDeleted, ElementsMap } from "./types";
2
2
  import { MaybeTransformHandleType, TransformHandleDirection } from "./transformHandles";
3
- import { AppState, PointerDownState } from "../types";
3
+ import { PointerDownState } from "../types";
4
4
  export declare const normalizeAngle: (angle: number) => number;
5
- export declare const transformElements: (pointerDownState: PointerDownState, transformHandleType: MaybeTransformHandleType, selectedElements: readonly NonDeletedExcalidrawElement[], resizeArrowDirection: "origin" | "end", shouldRotateWithDiscreteAngle: boolean, shouldResizeFromCenter: boolean, shouldMaintainAspectRatio: boolean, pointerX: number, pointerY: number, centerX: number, centerY: number, appState: AppState) => boolean;
6
- export declare const resizeSingleElement: (originalElements: PointerDownState["originalElements"], shouldMaintainAspectRatio: boolean, element: NonDeletedExcalidrawElement, transformHandleDirection: TransformHandleDirection, shouldResizeFromCenter: boolean, pointerX: number, pointerY: number) => void;
7
- export declare const resizeMultipleElements: (pointerDownState: PointerDownState, selectedElements: readonly NonDeletedExcalidrawElement[], transformHandleType: "nw" | "ne" | "sw" | "se", shouldResizeFromCenter: boolean, pointerX: number, pointerY: number) => void;
8
- export declare const getResizeOffsetXY: (transformHandleType: MaybeTransformHandleType, selectedElements: NonDeletedExcalidrawElement[], x: number, y: number) => [number, number];
5
+ export declare const transformElements: (originalElements: PointerDownState["originalElements"], transformHandleType: MaybeTransformHandleType, selectedElements: readonly NonDeletedExcalidrawElement[], elementsMap: ElementsMap, shouldRotateWithDiscreteAngle: boolean, shouldResizeFromCenter: boolean, shouldMaintainAspectRatio: boolean, pointerX: number, pointerY: number, centerX: number, centerY: number) => boolean;
6
+ export declare const resizeSingleElement: (originalElements: PointerDownState["originalElements"], shouldMaintainAspectRatio: boolean, element: NonDeletedExcalidrawElement, elementsMap: ElementsMap, transformHandleDirection: TransformHandleDirection, shouldResizeFromCenter: boolean, pointerX: number, pointerY: number) => void;
7
+ export declare const resizeMultipleElements: (originalElements: PointerDownState["originalElements"], selectedElements: readonly NonDeletedExcalidrawElement[], elementsMap: ElementsMap, transformHandleType: "nw" | "ne" | "sw" | "se", shouldResizeFromCenter: boolean, pointerX: number, pointerY: number) => void;
8
+ export declare const getResizeOffsetXY: (transformHandleType: MaybeTransformHandleType, selectedElements: NonDeletedExcalidrawElement[], elementsMap: ElementsMap, x: number, y: number) => [number, number];
9
9
  export declare const getResizeArrowDirection: (transformHandleType: MaybeTransformHandleType, element: NonDeleted<ExcalidrawLinearElement>) => "origin" | "end";