@yuzhouu/canvas-kit 0.1.2 → 0.1.3

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 (492) hide show
  1. package/_vendor/canvas-core/bindings/BindingUtil.d.ts +45 -0
  2. package/_vendor/canvas-core/bindings/BindingUtilRegistry.d.ts +8 -0
  3. package/_vendor/canvas-core/bindings/arrow/arrowBindingHelpers.d.ts +28 -0
  4. package/_vendor/canvas-core/contextMenu.d.ts +62 -0
  5. package/_vendor/canvas-core/editor/Editor.d.ts +564 -0
  6. package/_vendor/canvas-core/editor/HistoryManager.d.ts +18 -0
  7. package/_vendor/canvas-core/editor/StateNode.d.ts +31 -0
  8. package/_vendor/canvas-core/editor/camera.d.ts +3 -0
  9. package/_vendor/canvas-core/editor/clipboard.d.ts +43 -0
  10. package/_vendor/canvas-core/editor/commands.d.ts +126 -0
  11. package/_vendor/canvas-core/editor/edgeScroll.d.ts +5 -0
  12. package/_vendor/canvas-core/editor/editorComputedHelpers.d.ts +21 -0
  13. package/_vendor/canvas-core/editor/editorSelectionTransforms.d.ts +6 -0
  14. package/_vendor/canvas-core/editor/events.d.ts +71 -0
  15. package/_vendor/canvas-core/editor/{index.ts → index.d.ts} +1 -5
  16. package/_vendor/canvas-core/editor/interactions.d.ts +51 -0
  17. package/_vendor/canvas-core/editor/internal.d.ts +7 -0
  18. package/_vendor/canvas-core/editor/managers/BindingManager.d.ts +27 -0
  19. package/_vendor/canvas-core/editor/managers/CameraManager.d.ts +39 -0
  20. package/_vendor/canvas-core/editor/managers/ClipboardManager.d.ts +14 -0
  21. package/_vendor/canvas-core/editor/managers/DocumentSnapshotManager.d.ts +28 -0
  22. package/_vendor/canvas-core/editor/managers/InputsManager.d.ts +44 -0
  23. package/_vendor/canvas-core/editor/managers/InteractionTransientManager.d.ts +52 -0
  24. package/_vendor/canvas-core/editor/managers/QueryManager.d.ts +76 -0
  25. package/_vendor/canvas-core/editor/managers/RenderWindowManager.d.ts +25 -0
  26. package/_vendor/canvas-core/editor/managers/SelectionLayoutManager.d.ts +29 -0
  27. package/_vendor/canvas-core/editor/managers/SelectionManager.d.ts +21 -0
  28. package/_vendor/canvas-core/editor/managers/SelectionOverlayManager.d.ts +23 -0
  29. package/_vendor/canvas-core/editor/managers/ShapeEditingManager.d.ts +29 -0
  30. package/_vendor/canvas-core/editor/managers/ShapeGeometryManager.d.ts +42 -0
  31. package/_vendor/canvas-core/editor/managers/ShapeHierarchyManager.d.ts +58 -0
  32. package/_vendor/canvas-core/editor/managers/SideEffectManager.d.ts +23 -0
  33. package/_vendor/canvas-core/editor/managers/SnapManager.d.ts +29 -0
  34. package/_vendor/canvas-core/editor/managers/SnapSnapshotBuilder.d.ts +22 -0
  35. package/_vendor/canvas-core/editor/managers/SpatialIndexManager.d.ts +30 -0
  36. package/_vendor/canvas-core/editor/managers/ToolManager.d.ts +25 -0
  37. package/_vendor/canvas-core/editor/managers/queryState.d.ts +18 -0
  38. package/_vendor/canvas-core/editor/managers/selectionGeometry.d.ts +28 -0
  39. package/_vendor/canvas-core/editor/managers/shapeOrder.d.ts +14 -0
  40. package/_vendor/canvas-core/editor/managers/shapeReparenting.d.ts +6 -0
  41. package/_vendor/canvas-core/editor/managers/snapCalculations.d.ts +40 -0
  42. package/_vendor/canvas-core/editor/managers/snapGeometry.d.ts +26 -0
  43. package/_vendor/canvas-core/editor/managers/snapIndicators.d.ts +22 -0
  44. package/_vendor/canvas-core/editor/managers/snapTypes.d.ts +98 -0
  45. package/_vendor/canvas-core/editor/queries/shapeTransforms.d.ts +27 -0
  46. package/_vendor/canvas-core/editor/renderWindow.d.ts +30 -0
  47. package/_vendor/canvas-core/editor/resizeGeometry.d.ts +97 -0
  48. package/_vendor/canvas-core/editor/selection.d.ts +224 -0
  49. package/_vendor/canvas-core/editor/selectionHandleInteractions.d.ts +11 -0
  50. package/_vendor/canvas-core/editor/selectionOverlay.d.ts +31 -0
  51. package/_vendor/canvas-core/exports/integrity.d.ts +32 -0
  52. package/_vendor/canvas-core/exports/svg.d.ts +48 -0
  53. package/_vendor/canvas-core/geometry/Box.d.ts +19 -0
  54. package/_vendor/canvas-core/geometry/Ellipse2d.d.ts +16 -0
  55. package/_vendor/canvas-core/geometry/Geometry2d.d.ts +15 -0
  56. package/_vendor/canvas-core/geometry/Mat.d.ts +28 -0
  57. package/_vendor/canvas-core/geometry/Polyline2d.d.ts +14 -0
  58. package/_vendor/canvas-core/geometry/Rectangle2d.d.ts +16 -0
  59. package/_vendor/canvas-core/geometry/Vec.d.ts +37 -0
  60. package/_vendor/canvas-core/geometry/{index.ts → index.d.ts} +1 -6
  61. package/_vendor/canvas-core/geometry/segments.d.ts +5 -0
  62. package/_vendor/canvas-core/index.d.ts +57 -0
  63. package/_vendor/canvas-core/plugins/index.d.ts +1 -0
  64. package/_vendor/canvas-core/plugins/types.d.ts +27 -0
  65. package/_vendor/canvas-core/reactivity.d.ts +4 -0
  66. package/_vendor/canvas-core/schema/records.d.ts +112 -0
  67. package/_vendor/canvas-core/schema/snapshots.d.ts +27 -0
  68. package/_vendor/canvas-core/shapes/ShapeUtil.d.ts +133 -0
  69. package/_vendor/canvas-core/shapes/ShapeUtilRegistry.d.ts +9 -0
  70. package/_vendor/canvas-core/shapes/capabilities.d.ts +25 -0
  71. package/_vendor/canvas-core/shapes/types.d.ts +2 -0
  72. package/_vendor/canvas-core/toolbar.d.ts +117 -0
  73. package/_vendor/canvas-core/tools/hand/HandTool.d.ts +5 -0
  74. package/_vendor/canvas-core/tools/select/SelectTool.d.ts +5 -0
  75. package/_vendor/canvas-core/tools/select/selectContainment.d.ts +11 -0
  76. package/_vendor/canvas-core/tools/select/selectToolHelpers.d.ts +161 -0
  77. package/_vendor/canvas-core/tools/select/states/BrushingState.d.ts +19 -0
  78. package/_vendor/canvas-core/tools/select/states/DraggingSelectionHandleInteractionState.d.ts +15 -0
  79. package/_vendor/canvas-core/tools/select/states/IdleState.d.ts +8 -0
  80. package/_vendor/canvas-core/tools/select/states/PointingCanvasState.d.ts +11 -0
  81. package/_vendor/canvas-core/tools/select/states/PointingResizeHandleState.d.ts +10 -0
  82. package/_vendor/canvas-core/tools/select/states/PointingRotateHandleState.d.ts +10 -0
  83. package/_vendor/canvas-core/tools/select/states/PointingSelectionHandleInteractionState.d.ts +10 -0
  84. package/_vendor/canvas-core/tools/select/states/PointingShapeState.d.ts +12 -0
  85. package/_vendor/canvas-core/tools/select/states/ResizingState.d.ts +16 -0
  86. package/_vendor/canvas-core/tools/select/states/RotatingState.d.ts +14 -0
  87. package/_vendor/canvas-core/tools/select/states/SelectStateNode.d.ts +60 -0
  88. package/_vendor/canvas-core/tools/select/states/TranslatingState.d.ts +16 -0
  89. package/_vendor/canvas-plugin-api/feature.d.ts +37 -0
  90. package/_vendor/canvas-plugin-api/index.d.ts +57 -0
  91. package/_vendor/canvas-product-react/api/apiRegistry.d.ts +12 -0
  92. package/_vendor/canvas-product-react/api/canvasProductApi.d.ts +124 -0
  93. package/_vendor/canvas-product-react/api/index.d.ts +4 -0
  94. package/_vendor/canvas-product-react/capabilities/clipboard/clipboardService.d.ts +9 -0
  95. package/_vendor/canvas-product-react/capabilities/clipboard/systemClipboard.d.ts +16 -0
  96. package/_vendor/canvas-product-react/capabilities/context-menu/systemContextMenu.d.ts +17 -0
  97. package/_vendor/canvas-product-react/capabilities/context-menu/useContextMenuSurface.d.ts +12 -0
  98. package/_vendor/canvas-product-react/capabilities/export/useSvgExport.d.ts +29 -0
  99. package/_vendor/canvas-product-react/capabilities/history/useHistoryControls.d.ts +8 -0
  100. package/_vendor/canvas-product-react/capabilities/pages/usePageControls.d.ts +12 -0
  101. package/_vendor/canvas-product-react/capabilities/toolbar/systemToolbar.d.ts +32 -0
  102. package/_vendor/canvas-product-react/capabilities/toolbar/useToolbarSurfaces.d.ts +19 -0
  103. package/_vendor/canvas-product-react/capabilities/zoom/useZoomControls.d.ts +9 -0
  104. package/_vendor/canvas-product-react/index.d.ts +24 -0
  105. package/_vendor/canvas-product-react/persistence/index.d.ts +2 -0
  106. package/_vendor/canvas-product-react/persistence/localSnapshotPersistence.d.ts +40 -0
  107. package/_vendor/canvas-product-react/runtime/CanvasProductRoot.d.ts +4 -0
  108. package/_vendor/canvas-product-react/runtime/productDefinition.d.ts +45 -0
  109. package/_vendor/canvas-product-react/runtime/productServices.d.ts +31 -0
  110. package/_vendor/canvas-react/components/CanvasView.d.ts +11 -0
  111. package/_vendor/canvas-react/components/OverlayLayer.d.ts +1 -0
  112. package/_vendor/canvas-react/components/PageSpace.d.ts +6 -0
  113. package/_vendor/canvas-react/components/ShapeLayer.d.ts +1 -0
  114. package/_vendor/canvas-react/hooks/useEditor.d.ts +3 -0
  115. package/_vendor/canvas-react/hooks/useValue.d.ts +2 -0
  116. package/_vendor/canvas-react/host/CanvasRendererRegistryContext.d.ts +3 -0
  117. package/_vendor/canvas-react/host/contextMenuRegistry.d.ts +12 -0
  118. package/_vendor/canvas-react/host/domEventGuards.d.ts +11 -0
  119. package/_vendor/canvas-react/host/index.d.ts +8 -0
  120. package/_vendor/canvas-react/host/pluginHost.d.ts +93 -0
  121. package/_vendor/canvas-react/host/rendererRegistry.d.ts +12 -0
  122. package/_vendor/canvas-react/host/toolbarRegistry.d.ts +24 -0
  123. package/_vendor/plugin-arrow/ArrowBindingUtil.d.ts +27 -0
  124. package/_vendor/plugin-arrow/ArrowShapeUtil.d.ts +20 -0
  125. package/_vendor/plugin-arrow/ArrowTool.d.ts +4 -0
  126. package/_vendor/plugin-arrow/arrowGeometry.d.ts +50 -0
  127. package/_vendor/plugin-arrow/arrowTerminalBindingResolver.d.ts +21 -0
  128. package/_vendor/plugin-arrow/arrowTerminalCommands.d.ts +12 -0
  129. package/_vendor/plugin-arrow/canvas.d.ts +2 -0
  130. package/_vendor/plugin-arrow/core.d.ts +7 -0
  131. package/_vendor/plugin-arrow/feature.d.ts +3 -0
  132. package/_vendor/plugin-arrow/index.d.ts +11 -0
  133. package/_vendor/plugin-arrow/selectionHandleInteractions.d.ts +3 -0
  134. package/_vendor/plugin-arrow/types.d.ts +31 -0
  135. package/_vendor/plugin-draw/DrawShapeRenderer.d.ts +8 -0
  136. package/_vendor/plugin-draw/DrawShapeUtil.d.ts +21 -0
  137. package/_vendor/plugin-draw/DrawTool.d.ts +6 -0
  138. package/_vendor/plugin-draw/canvas.d.ts +2 -0
  139. package/_vendor/plugin-draw/core.d.ts +7 -0
  140. package/_vendor/plugin-draw/drawGeometry.d.ts +45 -0
  141. package/_vendor/plugin-draw/drawHitTest.d.ts +11 -0
  142. package/_vendor/plugin-draw/drawInterpolation.d.ts +5 -0
  143. package/_vendor/plugin-draw/drawPath.d.ts +37 -0
  144. package/_vendor/plugin-draw/drawSegments.d.ts +11 -0
  145. package/_vendor/plugin-draw/drawSelectionTransform.d.ts +18 -0
  146. package/_vendor/plugin-draw/drawShapeGeometry.d.ts +33 -0
  147. package/_vendor/plugin-draw/drawStrokeGeometry.d.ts +17 -0
  148. package/_vendor/plugin-draw/feature.d.ts +3 -0
  149. package/_vendor/plugin-draw/index.d.ts +13 -0
  150. package/_vendor/plugin-draw/types.d.ts +23 -0
  151. package/_vendor/plugin-eraser/EraserTool.d.ts +5 -0
  152. package/_vendor/plugin-eraser/canvas.d.ts +2 -0
  153. package/_vendor/plugin-eraser/core.d.ts +2 -0
  154. package/_vendor/plugin-eraser/feature.d.ts +3 -0
  155. package/_vendor/plugin-frame/FrameShapeUtil.d.ts +22 -0
  156. package/_vendor/plugin-frame/FrameTool.d.ts +6 -0
  157. package/_vendor/plugin-frame/canvas.d.ts +8 -0
  158. package/_vendor/plugin-frame/core.d.ts +7 -0
  159. package/_vendor/plugin-frame/feature.d.ts +3 -0
  160. package/_vendor/plugin-geo/GeoShapeUtil.d.ts +13 -0
  161. package/_vendor/plugin-geo/GeoTools.d.ts +17 -0
  162. package/_vendor/plugin-geo/canvas.d.ts +11 -0
  163. package/_vendor/plugin-geo/core.d.ts +7 -0
  164. package/_vendor/plugin-geo/feature.d.ts +3 -0
  165. package/_vendor/plugin-geo/types.d.ts +15 -0
  166. package/_vendor/plugin-group/GroupShapeUtil.d.ts +15 -0
  167. package/_vendor/plugin-group/canvas.d.ts +10 -0
  168. package/_vendor/plugin-group/core.d.ts +7 -0
  169. package/_vendor/plugin-group/feature.d.ts +3 -0
  170. package/_vendor/plugin-image/ImageShapeUtil.d.ts +10 -0
  171. package/_vendor/plugin-image/canvas.d.ts +2 -0
  172. package/_vendor/plugin-image/core.d.ts +16 -0
  173. package/_vendor/plugin-image/crop.d.ts +112 -0
  174. package/_vendor/plugin-image/cropInteractions.d.ts +3 -0
  175. package/_vendor/plugin-image/cropSession.d.ts +4 -0
  176. package/_vendor/plugin-image/feature.d.ts +3 -0
  177. package/_vendor/plugin-image/index.d.ts +8 -0
  178. package/_vendor/plugin-image/types.d.ts +37 -0
  179. package/_vendor/plugin-image-product-react/ImageImportController.d.ts +9 -0
  180. package/_vendor/plugin-image-product-react/imageAssetService.d.ts +7 -0
  181. package/_vendor/plugin-image-product-react/imageBlobStore.d.ts +25 -0
  182. package/_vendor/plugin-image-product-react/imageHostActions.d.ts +35 -0
  183. package/_vendor/plugin-image-product-react/imageProductApi.d.ts +21 -0
  184. package/_vendor/plugin-image-product-react/imageToolbarHostBridge.d.ts +14 -0
  185. package/_vendor/plugin-image-product-react/imageToolbarRuntime.d.ts +2 -0
  186. package/_vendor/plugin-image-product-react/index.d.ts +16 -0
  187. package/_vendor/plugin-image-product-react/snapshotGuards.d.ts +1 -0
  188. package/_vendor/plugin-image-product-react/svgImageAssetInliner.d.ts +3 -0
  189. package/_vendor/plugin-image-product-react/useImageImport.d.ts +16 -0
  190. package/_vendor/plugin-laser/LaserTool.d.ts +4 -0
  191. package/_vendor/plugin-laser/canvas.d.ts +2 -0
  192. package/_vendor/plugin-laser/core.d.ts +2 -0
  193. package/_vendor/plugin-laser/feature.d.ts +3 -0
  194. package/_vendor/plugin-text/ArrowLabelBindingUtil.d.ts +42 -0
  195. package/_vendor/plugin-text/GeoLabelBindingUtil.d.ts +45 -0
  196. package/_vendor/plugin-text/TextShapeSvgExporter.d.ts +6 -0
  197. package/_vendor/plugin-text/TextShapeUtil.d.ts +19 -0
  198. package/_vendor/plugin-text/TextTool.d.ts +4 -0
  199. package/_vendor/plugin-text/canvas.d.ts +2 -0
  200. package/_vendor/plugin-text/core.d.ts +2 -0
  201. package/_vendor/plugin-text/feature.d.ts +3 -0
  202. package/_vendor/plugin-text/host/RichTextEditingBox.d.ts +5 -0
  203. package/_vendor/plugin-text/host/RichTextToolbar.d.ts +6 -0
  204. package/_vendor/plugin-text/host/TiptapTextEditor.d.ts +24 -0
  205. package/_vendor/plugin-text/host/richTextRendering.d.ts +3 -0
  206. package/_vendor/plugin-text/host/textDomSelection.d.ts +7 -0
  207. package/_vendor/plugin-text/host/textEditingBoxStyle.d.ts +3 -0
  208. package/_vendor/plugin-text/host/textEntryFocus.d.ts +22 -0
  209. package/_vendor/plugin-text/host/textFontLoader.d.ts +2 -0
  210. package/_vendor/plugin-text/host/textMeasurement.d.ts +12 -0
  211. package/_vendor/plugin-text/host/textMeasurementSync.d.ts +10 -0
  212. package/_vendor/plugin-text/host/textRangeSelection.d.ts +14 -0
  213. package/_vendor/plugin-text/host/textShapeRendererRuntime.d.ts +8 -0
  214. package/_vendor/plugin-text/host/textShapeSync.d.ts +17 -0
  215. package/_vendor/plugin-text/host/tiptapTextEditorController.d.ts +33 -0
  216. package/_vendor/plugin-text/index.d.ts +4 -0
  217. package/_vendor/plugin-text/richTextUtils.d.ts +18 -0
  218. package/_vendor/plugin-text/textInteractions.d.ts +2 -0
  219. package/_vendor/plugin-text/textLabelHelpers.d.ts +44 -0
  220. package/_vendor/plugin-text/textShapeHelpers.d.ts +21 -0
  221. package/_vendor/plugin-text/textStyle.d.ts +9 -0
  222. package/_vendor/plugin-text/textTypes.d.ts +28 -0
  223. package/_vendor/signals/atom.d.ts +9 -0
  224. package/_vendor/signals/computed.d.ts +11 -0
  225. package/_vendor/signals/core.d.ts +17 -0
  226. package/_vendor/signals/effect.d.ts +29 -0
  227. package/_vendor/signals/types.d.ts +15 -0
  228. package/_vendor/store/Store.d.ts +26 -0
  229. package/_vendor/store/diff.d.ts +9 -0
  230. package/_vendor/store/history.d.ts +37 -0
  231. package/_vendor/store/index.d.ts +5 -0
  232. package/_vendor/store/types.d.ts +27 -0
  233. package/api/canvasKitApi.d.ts +2 -2
  234. package/index.css +1 -1
  235. package/index.d.ts +0 -1
  236. package/index.mjs +1 -1
  237. package/package.json +1 -1
  238. package/product/Shell.d.ts +2 -2
  239. package/product/chromeContext.d.ts +8 -8
  240. package/product/createCanvasKitEditor.d.ts +1 -1
  241. package/product/persistence.d.ts +1 -1
  242. package/product/product.d.ts +1 -1
  243. package/product/useCanvasClipboardShortcuts.d.ts +2 -2
  244. package/product-CxN5NN6u.mjs +4 -0
  245. package/product.mjs +1 -1
  246. package/standard/extensions.d.ts +1 -1
  247. package/standard/standardApi.d.ts +5 -5
  248. package/standard-R17_x8HU.mjs +44 -0
  249. package/standard.mjs +1 -1
  250. package/_vendor/canvas-core/bindings/BindingUtil.ts +0 -92
  251. package/_vendor/canvas-core/bindings/BindingUtilRegistry.ts +0 -22
  252. package/_vendor/canvas-core/bindings/arrow/arrowBindingHelpers.ts +0 -52
  253. package/_vendor/canvas-core/contextMenu.ts +0 -85
  254. package/_vendor/canvas-core/editor/Editor.ts +0 -2614
  255. package/_vendor/canvas-core/editor/HistoryManager.ts +0 -83
  256. package/_vendor/canvas-core/editor/StateNode.ts +0 -162
  257. package/_vendor/canvas-core/editor/camera.ts +0 -6
  258. package/_vendor/canvas-core/editor/clipboard.ts +0 -478
  259. package/_vendor/canvas-core/editor/commands.ts +0 -833
  260. package/_vendor/canvas-core/editor/edgeScroll.ts +0 -37
  261. package/_vendor/canvas-core/editor/editorComputedHelpers.ts +0 -257
  262. package/_vendor/canvas-core/editor/editorSelectionTransforms.ts +0 -116
  263. package/_vendor/canvas-core/editor/events.ts +0 -93
  264. package/_vendor/canvas-core/editor/interactions.ts +0 -101
  265. package/_vendor/canvas-core/editor/internal.ts +0 -22
  266. package/_vendor/canvas-core/editor/managers/BindingManager.ts +0 -262
  267. package/_vendor/canvas-core/editor/managers/CameraManager.ts +0 -147
  268. package/_vendor/canvas-core/editor/managers/ClipboardManager.ts +0 -32
  269. package/_vendor/canvas-core/editor/managers/DocumentSnapshotManager.ts +0 -256
  270. package/_vendor/canvas-core/editor/managers/InputsManager.ts +0 -319
  271. package/_vendor/canvas-core/editor/managers/InteractionTransientManager.ts +0 -218
  272. package/_vendor/canvas-core/editor/managers/QueryManager.ts +0 -837
  273. package/_vendor/canvas-core/editor/managers/RenderWindowManager.ts +0 -347
  274. package/_vendor/canvas-core/editor/managers/SelectionLayoutManager.ts +0 -196
  275. package/_vendor/canvas-core/editor/managers/SelectionManager.ts +0 -98
  276. package/_vendor/canvas-core/editor/managers/SelectionOverlayManager.ts +0 -308
  277. package/_vendor/canvas-core/editor/managers/ShapeEditingManager.ts +0 -226
  278. package/_vendor/canvas-core/editor/managers/ShapeGeometryManager.ts +0 -162
  279. package/_vendor/canvas-core/editor/managers/ShapeHierarchyManager.ts +0 -797
  280. package/_vendor/canvas-core/editor/managers/SideEffectManager.ts +0 -83
  281. package/_vendor/canvas-core/editor/managers/SnapManager.ts +0 -433
  282. package/_vendor/canvas-core/editor/managers/SnapSnapshotBuilder.ts +0 -430
  283. package/_vendor/canvas-core/editor/managers/SpatialIndexManager.ts +0 -354
  284. package/_vendor/canvas-core/editor/managers/ToolManager.ts +0 -81
  285. package/_vendor/canvas-core/editor/managers/queryState.ts +0 -583
  286. package/_vendor/canvas-core/editor/managers/selectionGeometry.ts +0 -287
  287. package/_vendor/canvas-core/editor/managers/shapeOrder.ts +0 -350
  288. package/_vendor/canvas-core/editor/managers/shapeReparenting.ts +0 -160
  289. package/_vendor/canvas-core/editor/managers/snapCalculations.ts +0 -412
  290. package/_vendor/canvas-core/editor/managers/snapGeometry.ts +0 -202
  291. package/_vendor/canvas-core/editor/managers/snapIndicators.ts +0 -403
  292. package/_vendor/canvas-core/editor/managers/snapTypes.ts +0 -122
  293. package/_vendor/canvas-core/editor/queries/shapeTransforms.ts +0 -171
  294. package/_vendor/canvas-core/editor/renderWindow.ts +0 -439
  295. package/_vendor/canvas-core/editor/resizeGeometry.ts +0 -654
  296. package/_vendor/canvas-core/editor/selection.ts +0 -489
  297. package/_vendor/canvas-core/editor/selectionHandleInteractions.ts +0 -43
  298. package/_vendor/canvas-core/editor/selectionOverlay.ts +0 -567
  299. package/_vendor/canvas-core/exports/integrity.ts +0 -174
  300. package/_vendor/canvas-core/exports/svg.ts +0 -494
  301. package/_vendor/canvas-core/geometry/Box.ts +0 -80
  302. package/_vendor/canvas-core/geometry/Ellipse2d.ts +0 -67
  303. package/_vendor/canvas-core/geometry/Geometry2d.ts +0 -52
  304. package/_vendor/canvas-core/geometry/Mat.ts +0 -92
  305. package/_vendor/canvas-core/geometry/Polyline2d.ts +0 -63
  306. package/_vendor/canvas-core/geometry/Rectangle2d.ts +0 -64
  307. package/_vendor/canvas-core/geometry/Vec.ts +0 -123
  308. package/_vendor/canvas-core/geometry/segments.ts +0 -65
  309. package/_vendor/canvas-core/index.ts +0 -391
  310. package/_vendor/canvas-core/plugins/index.ts +0 -5
  311. package/_vendor/canvas-core/plugins/types.ts +0 -53
  312. package/_vendor/canvas-core/reactivity.ts +0 -16
  313. package/_vendor/canvas-core/schema/records.ts +0 -221
  314. package/_vendor/canvas-core/schema/snapshots.ts +0 -527
  315. package/_vendor/canvas-core/shapes/ShapeUtil.ts +0 -516
  316. package/_vendor/canvas-core/shapes/ShapeUtilRegistry.ts +0 -26
  317. package/_vendor/canvas-core/shapes/capabilities.ts +0 -67
  318. package/_vendor/canvas-core/shapes/types.ts +0 -20
  319. package/_vendor/canvas-core/toolbar.ts +0 -148
  320. package/_vendor/canvas-core/tools/hand/HandTool.ts +0 -75
  321. package/_vendor/canvas-core/tools/select/SelectTool.ts +0 -33
  322. package/_vendor/canvas-core/tools/select/selectContainment.ts +0 -104
  323. package/_vendor/canvas-core/tools/select/selectToolHelpers.ts +0 -801
  324. package/_vendor/canvas-core/tools/select/states/BrushingState.ts +0 -145
  325. package/_vendor/canvas-core/tools/select/states/DraggingSelectionHandleInteractionState.ts +0 -116
  326. package/_vendor/canvas-core/tools/select/states/IdleState.ts +0 -159
  327. package/_vendor/canvas-core/tools/select/states/PointingCanvasState.ts +0 -41
  328. package/_vendor/canvas-core/tools/select/states/PointingResizeHandleState.ts +0 -78
  329. package/_vendor/canvas-core/tools/select/states/PointingRotateHandleState.ts +0 -64
  330. package/_vendor/canvas-core/tools/select/states/PointingSelectionHandleInteractionState.ts +0 -34
  331. package/_vendor/canvas-core/tools/select/states/PointingShapeState.ts +0 -140
  332. package/_vendor/canvas-core/tools/select/states/ResizingState.ts +0 -171
  333. package/_vendor/canvas-core/tools/select/states/RotatingState.ts +0 -124
  334. package/_vendor/canvas-core/tools/select/states/SelectStateNode.ts +0 -128
  335. package/_vendor/canvas-core/tools/select/states/TranslatingState.ts +0 -139
  336. package/_vendor/canvas-plugin-api/feature.ts +0 -204
  337. package/_vendor/canvas-plugin-api/index.ts +0 -142
  338. package/_vendor/canvas-product-react/api/apiRegistry.ts +0 -35
  339. package/_vendor/canvas-product-react/api/canvasProductApi.ts +0 -422
  340. package/_vendor/canvas-product-react/api/index.ts +0 -31
  341. package/_vendor/canvas-product-react/capabilities/clipboard/clipboardService.ts +0 -36
  342. package/_vendor/canvas-product-react/capabilities/clipboard/systemClipboard.ts +0 -245
  343. package/_vendor/canvas-product-react/capabilities/context-menu/systemContextMenu.ts +0 -396
  344. package/_vendor/canvas-product-react/capabilities/context-menu/useContextMenuSurface.ts +0 -59
  345. package/_vendor/canvas-product-react/capabilities/export/useSvgExport.ts +0 -156
  346. package/_vendor/canvas-product-react/capabilities/history/useHistoryControls.ts +0 -23
  347. package/_vendor/canvas-product-react/capabilities/pages/usePageControls.ts +0 -41
  348. package/_vendor/canvas-product-react/capabilities/toolbar/systemToolbar.ts +0 -490
  349. package/_vendor/canvas-product-react/capabilities/toolbar/useToolbarSurfaces.ts +0 -92
  350. package/_vendor/canvas-product-react/capabilities/zoom/useZoomControls.ts +0 -27
  351. package/_vendor/canvas-product-react/index.ts +0 -84
  352. package/_vendor/canvas-product-react/persistence/index.ts +0 -18
  353. package/_vendor/canvas-product-react/persistence/localSnapshotPersistence.ts +0 -294
  354. package/_vendor/canvas-product-react/runtime/CanvasProductRoot.tsx +0 -250
  355. package/_vendor/canvas-product-react/runtime/productDefinition.ts +0 -72
  356. package/_vendor/canvas-product-react/runtime/productServices.ts +0 -96
  357. package/_vendor/canvas-react/components/CanvasView.tsx +0 -796
  358. package/_vendor/canvas-react/components/OverlayLayer.tsx +0 -879
  359. package/_vendor/canvas-react/components/PageSpace.tsx +0 -34
  360. package/_vendor/canvas-react/components/ShapeLayer.tsx +0 -428
  361. package/_vendor/canvas-react/hooks/useEditor.ts +0 -11
  362. package/_vendor/canvas-react/hooks/useValue.ts +0 -14
  363. package/_vendor/canvas-react/host/CanvasRendererRegistryContext.tsx +0 -14
  364. package/_vendor/canvas-react/host/contextMenuRegistry.ts +0 -61
  365. package/_vendor/canvas-react/host/domEventGuards.ts +0 -61
  366. package/_vendor/canvas-react/host/index.ts +0 -38
  367. package/_vendor/canvas-react/host/pluginHost.ts +0 -635
  368. package/_vendor/canvas-react/host/rendererRegistry.tsx +0 -58
  369. package/_vendor/canvas-react/host/toolbarRegistry.ts +0 -100
  370. package/_vendor/plugin-arrow/ArrowBindingUtil.ts +0 -239
  371. package/_vendor/plugin-arrow/ArrowShapeUtil.ts +0 -311
  372. package/_vendor/plugin-arrow/ArrowTool.ts +0 -208
  373. package/_vendor/plugin-arrow/arrowGeometry.ts +0 -441
  374. package/_vendor/plugin-arrow/arrowTerminalBindingResolver.ts +0 -253
  375. package/_vendor/plugin-arrow/arrowTerminalCommands.ts +0 -230
  376. package/_vendor/plugin-arrow/canvas.tsx +0 -92
  377. package/_vendor/plugin-arrow/core.ts +0 -409
  378. package/_vendor/plugin-arrow/feature.ts +0 -20
  379. package/_vendor/plugin-arrow/index.ts +0 -28
  380. package/_vendor/plugin-arrow/selectionHandleInteractions.ts +0 -154
  381. package/_vendor/plugin-arrow/types.ts +0 -63
  382. package/_vendor/plugin-draw/DrawShapeRenderer.tsx +0 -60
  383. package/_vendor/plugin-draw/DrawShapeUtil.ts +0 -372
  384. package/_vendor/plugin-draw/DrawTool.ts +0 -444
  385. package/_vendor/plugin-draw/canvas.tsx +0 -24
  386. package/_vendor/plugin-draw/core.ts +0 -515
  387. package/_vendor/plugin-draw/drawGeometry.ts +0 -491
  388. package/_vendor/plugin-draw/drawHitTest.ts +0 -271
  389. package/_vendor/plugin-draw/drawInterpolation.ts +0 -250
  390. package/_vendor/plugin-draw/drawPath.ts +0 -550
  391. package/_vendor/plugin-draw/drawSegments.ts +0 -106
  392. package/_vendor/plugin-draw/drawSelectionTransform.ts +0 -67
  393. package/_vendor/plugin-draw/drawShapeGeometry.ts +0 -307
  394. package/_vendor/plugin-draw/drawStrokeGeometry.ts +0 -454
  395. package/_vendor/plugin-draw/feature.ts +0 -20
  396. package/_vendor/plugin-draw/index.ts +0 -31
  397. package/_vendor/plugin-draw/types.ts +0 -36
  398. package/_vendor/plugin-eraser/EraserTool.ts +0 -297
  399. package/_vendor/plugin-eraser/canvas.tsx +0 -616
  400. package/_vendor/plugin-eraser/core.ts +0 -49
  401. package/_vendor/plugin-eraser/feature.ts +0 -20
  402. package/_vendor/plugin-frame/FrameShapeUtil.ts +0 -173
  403. package/_vendor/plugin-frame/FrameTool.ts +0 -225
  404. package/_vendor/plugin-frame/canvas.tsx +0 -75
  405. package/_vendor/plugin-frame/core.ts +0 -534
  406. package/_vendor/plugin-frame/feature.ts +0 -20
  407. package/_vendor/plugin-geo/GeoShapeUtil.ts +0 -463
  408. package/_vendor/plugin-geo/GeoTools.ts +0 -247
  409. package/_vendor/plugin-geo/canvas.tsx +0 -90
  410. package/_vendor/plugin-geo/core.ts +0 -495
  411. package/_vendor/plugin-geo/feature.ts +0 -20
  412. package/_vendor/plugin-geo/types.ts +0 -27
  413. package/_vendor/plugin-group/GroupShapeUtil.ts +0 -59
  414. package/_vendor/plugin-group/canvas.tsx +0 -59
  415. package/_vendor/plugin-group/core.ts +0 -40
  416. package/_vendor/plugin-group/feature.ts +0 -20
  417. package/_vendor/plugin-image/ImageShapeUtil.ts +0 -95
  418. package/_vendor/plugin-image/canvas.tsx +0 -212
  419. package/_vendor/plugin-image/core.ts +0 -542
  420. package/_vendor/plugin-image/crop.ts +0 -770
  421. package/_vendor/plugin-image/cropInteractions.ts +0 -350
  422. package/_vendor/plugin-image/cropSession.ts +0 -38
  423. package/_vendor/plugin-image/feature.ts +0 -20
  424. package/_vendor/plugin-image/index.ts +0 -29
  425. package/_vendor/plugin-image/types.ts +0 -55
  426. package/_vendor/plugin-image-product-react/ImageImportController.tsx +0 -143
  427. package/_vendor/plugin-image-product-react/imageAssetService.ts +0 -52
  428. package/_vendor/plugin-image-product-react/imageBlobStore.ts +0 -315
  429. package/_vendor/plugin-image-product-react/imageHostActions.ts +0 -438
  430. package/_vendor/plugin-image-product-react/imageProductApi.ts +0 -88
  431. package/_vendor/plugin-image-product-react/imageToolbarHostBridge.ts +0 -48
  432. package/_vendor/plugin-image-product-react/imageToolbarRuntime.ts +0 -21
  433. package/_vendor/plugin-image-product-react/index.ts +0 -60
  434. package/_vendor/plugin-image-product-react/snapshotGuards.ts +0 -33
  435. package/_vendor/plugin-image-product-react/svgImageAssetInliner.ts +0 -54
  436. package/_vendor/plugin-image-product-react/useImageImport.ts +0 -64
  437. package/_vendor/plugin-laser/LaserTool.ts +0 -154
  438. package/_vendor/plugin-laser/canvas.tsx +0 -645
  439. package/_vendor/plugin-laser/core.ts +0 -49
  440. package/_vendor/plugin-laser/feature.ts +0 -20
  441. package/_vendor/plugin-text/ArrowLabelBindingUtil.ts +0 -336
  442. package/_vendor/plugin-text/GeoLabelBindingUtil.ts +0 -391
  443. package/_vendor/plugin-text/TextShapeSvgExporter.ts +0 -101
  444. package/_vendor/plugin-text/TextShapeUtil.ts +0 -284
  445. package/_vendor/plugin-text/TextTool.ts +0 -228
  446. package/_vendor/plugin-text/canvas.tsx +0 -115
  447. package/_vendor/plugin-text/core.ts +0 -422
  448. package/_vendor/plugin-text/feature.ts +0 -20
  449. package/_vendor/plugin-text/host/RichTextEditingBox.tsx +0 -144
  450. package/_vendor/plugin-text/host/RichTextToolbar.tsx +0 -266
  451. package/_vendor/plugin-text/host/TiptapTextEditor.tsx +0 -191
  452. package/_vendor/plugin-text/host/richTextRendering.tsx +0 -49
  453. package/_vendor/plugin-text/host/textDomSelection.ts +0 -93
  454. package/_vendor/plugin-text/host/textEditingBoxStyle.ts +0 -36
  455. package/_vendor/plugin-text/host/textEntryFocus.ts +0 -307
  456. package/_vendor/plugin-text/host/textFontLoader.ts +0 -149
  457. package/_vendor/plugin-text/host/textMeasurement.ts +0 -258
  458. package/_vendor/plugin-text/host/textMeasurementSync.ts +0 -77
  459. package/_vendor/plugin-text/host/textRangeSelection.ts +0 -134
  460. package/_vendor/plugin-text/host/textShapeRendererRuntime.tsx +0 -89
  461. package/_vendor/plugin-text/host/textShapeSync.ts +0 -173
  462. package/_vendor/plugin-text/host/tiptapTextEditorController.ts +0 -148
  463. package/_vendor/plugin-text/index.ts +0 -18
  464. package/_vendor/plugin-text/richTextUtils.ts +0 -259
  465. package/_vendor/plugin-text/textInteractions.ts +0 -366
  466. package/_vendor/plugin-text/textLabelHelpers.ts +0 -235
  467. package/_vendor/plugin-text/textShapeHelpers.ts +0 -123
  468. package/_vendor/plugin-text/textStyle.ts +0 -96
  469. package/_vendor/plugin-text/textTypes.ts +0 -48
  470. package/_vendor/signals/atom.ts +0 -74
  471. package/_vendor/signals/computed.ts +0 -132
  472. package/_vendor/signals/core.ts +0 -130
  473. package/_vendor/signals/effect.ts +0 -117
  474. package/_vendor/signals/types.ts +0 -17
  475. package/_vendor/store/Store.ts +0 -171
  476. package/_vendor/store/diff.ts +0 -229
  477. package/_vendor/store/history.ts +0 -177
  478. package/_vendor/store/index.ts +0 -32
  479. package/_vendor/store/types.ts +0 -37
  480. package/internal-modules.d.ts +0 -187
  481. package/product-iyBbEPIs.mjs +0 -4
  482. package/standard-BmrxwqpJ.mjs +0 -44
  483. /package/_vendor/canvas-core/tools/{index.ts → index.d.ts} +0 -0
  484. /package/_vendor/canvas-core/tools/select/states/{index.ts → index.d.ts} +0 -0
  485. /package/_vendor/canvas-react/components/{index.ts → index.d.ts} +0 -0
  486. /package/_vendor/canvas-react/{index.ts → index.d.ts} +0 -0
  487. /package/_vendor/plugin-eraser/{index.ts → index.d.ts} +0 -0
  488. /package/_vendor/plugin-frame/{index.ts → index.d.ts} +0 -0
  489. /package/_vendor/plugin-geo/{index.ts → index.d.ts} +0 -0
  490. /package/_vendor/plugin-group/{index.ts → index.d.ts} +0 -0
  491. /package/_vendor/plugin-laser/{index.ts → index.d.ts} +0 -0
  492. /package/_vendor/signals/{index.ts → index.d.ts} +0 -0
@@ -1,2614 +0,0 @@
1
- import {
2
- UNINITIALIZED,
3
- atom,
4
- computed,
5
- type Atom,
6
- type Signal,
7
- } from "@land/signals";
8
- import type {
9
- ArrowTerminalBindingResolver,
10
- ArrowTerminalBindingResolverInput,
11
- ResolvedArrowTerminalBinding,
12
- } from "../bindings/arrow/arrowBindingHelpers";
13
- import type { BindingUtil } from "../bindings/BindingUtil";
14
- import { BindingUtilRegistry } from "../bindings/BindingUtilRegistry";
15
- import { Box } from "../geometry/Box";
16
- import { Mat } from "../geometry/Mat";
17
- import { Vec } from "../geometry/Vec";
18
- import {
19
- type BindingId,
20
- type BindingRecord,
21
- DEFAULT_CAMERA,
22
- DEFAULT_SESSION_ID,
23
- type AssetId,
24
- type AssetRecord,
25
- type Camera,
26
- isAssetRecord,
27
- isBindingRecord,
28
- isPageRecord,
29
- isSessionRecord,
30
- isShapeRecord,
31
- type PageId,
32
- type PageRecord,
33
- type EditorRecord,
34
- type RecordScope,
35
- type SessionRecord,
36
- type ShapeId,
37
- type ShapeParentId,
38
- type ShapeRecord,
39
- type ShapeEditingEntryRequest,
40
- type ShapeEditingSession,
41
- } from "../schema/records";
42
- import {
43
- type DocumentSnapshot,
44
- type SessionSnapshot,
45
- } from "../schema/snapshots";
46
- import type {
47
- ShapeSelectionFlipAxis,
48
- ShapeUtil,
49
- } from "../shapes/ShapeUtil";
50
- import { ShapeUtilRegistry } from "../shapes/ShapeUtilRegistry";
51
- import {
52
- exportShapesToSvgString,
53
- ShapeSvgExporterRegistry,
54
- type ShapeSvgExporter,
55
- type SvgExportOptions,
56
- type SvgExportResult,
57
- } from "../exports/svg";
58
- import {
59
- getExportIntegrityReport,
60
- repairExportIntegrity,
61
- type ExportIntegrityRepairResult,
62
- type ExportIntegrityReport,
63
- } from "../exports/integrity";
64
- import {
65
- getShapeCapabilityManifest,
66
- type ShapeCapabilityDefinition,
67
- type ShapeCapabilityManifest,
68
- } from "../shapes/capabilities";
69
- import { Store, type ChangeSource, type StoreChange } from "@land/store";
70
- import {
71
- createEditorCommands,
72
- type CreateAssetInput,
73
- type CreateBindingInput,
74
- type CreatePageInput,
75
- type CreateShapeInput,
76
- type StartEditingShapeInput,
77
- type EditorCommands,
78
- } from "./commands";
79
- import type {
80
- CancelEditorEvent,
81
- ClickEditorEvent,
82
- EditorEvent,
83
- PointerEditorEvent,
84
- } from "./events";
85
- import { HistoryManager, type HistoryState } from "./HistoryManager";
86
- import { BindingManager } from "./managers/BindingManager";
87
- import { CameraManager } from "./managers/CameraManager";
88
- import { ClipboardManager } from "./managers/ClipboardManager";
89
- import { DocumentSnapshotManager } from "./managers/DocumentSnapshotManager";
90
- import { InputsManager } from "./managers/InputsManager";
91
- import {
92
- InteractionTransientManager,
93
- type LaserTrailState,
94
- } from "./managers/InteractionTransientManager";
95
- import {
96
- QueryManager,
97
- type ShapeContainment,
98
- } from "./managers/QueryManager";
99
- import {
100
- SpatialIndexManager,
101
- type ShapeAtPointOptions,
102
- type ShapeLineSegmentHitTestOptions,
103
- type SpatialQueryOptions,
104
- } from "./managers/SpatialIndexManager";
105
- import { SnapManager } from "./managers/SnapManager";
106
- import { SideEffectManager } from "./managers/SideEffectManager";
107
- import { SelectionLayoutManager } from "./managers/SelectionLayoutManager";
108
- import { SelectionManager } from "./managers/SelectionManager";
109
- import { SelectionOverlayManager } from "./managers/SelectionOverlayManager";
110
- import { ShapeEditingManager } from "./managers/ShapeEditingManager";
111
- import { ShapeGeometryManager } from "./managers/ShapeGeometryManager";
112
- import { ShapeHierarchyManager } from "./managers/ShapeHierarchyManager";
113
- import { RenderWindowManager } from "./managers/RenderWindowManager";
114
- import { ToolManager } from "./managers/ToolManager";
115
- import type { ShapeGeometry } from "./queries/shapeTransforms";
116
- import { editorStoreSymbol, getEditorStore, setEditorStore } from "./internal";
117
- import {
118
- getEditorSelectionFlipUpdates,
119
- resetEditorSelectionRotation,
120
- } from "./editorSelectionTransforms";
121
- import type {
122
- DuplicateSelectionInput,
123
- EditorClipboardPayload,
124
- PasteClipboardPayloadInput,
125
- } from "./clipboard";
126
- import { InteractionHandlerRegistry } from "./interactions";
127
- import { SelectionHandleInteractionRegistry } from "./selectionHandleInteractions";
128
- import {
129
- RENDER_CULLING_OVERSCAN_SCREEN,
130
- doesBoxContainBox,
131
- } from "./renderWindow";
132
- import {
133
- areSelectedShapeOverlayItemsEqual,
134
- getSelectionHandleState,
135
- isSingleSelectionPathOverlay,
136
- type SelectedShapeOverlayItem,
137
- } from "./selectionOverlay";
138
- import type {
139
- ArrowBindingPreviewState,
140
- SnapIndicatorState,
141
- SelectionHandle,
142
- SelectionFrame,
143
- SelectionOverlayFrameState,
144
- SelectionOverlayFrameGeometryState,
145
- SelectionOverlayFrameStyleState,
146
- SelectionOverlayHandleAnchorsState,
147
- SelectionOverlayHandleCountsState,
148
- SelectionOverlayHandlesState,
149
- SelectionOverlayState,
150
- } from "./selection";
151
-
152
- const SELECTION_HANDLE_HIT_PADDING_SCREEN = 6;
153
- const DOUBLE_CLICK_DURATION_MS = 250;
154
- const DOUBLE_CLICK_DISTANCE = 40;
155
- const DOUBLE_CLICK_DISTANCE_SQUARED =
156
- DOUBLE_CLICK_DISTANCE * DOUBLE_CLICK_DISTANCE;
157
- const CAMERA_WHEEL_MAX_ZOOM_STEP = 10;
158
- const CAMERA_WHEEL_ZOOM_SPEED = 1;
159
-
160
- export interface EditorOptions {
161
- shapeUtils?: ShapeUtil[];
162
- shapeSvgExporters?: ShapeSvgExporter[];
163
- bindingUtils?: BindingUtil[];
164
- shapeCapabilities?: readonly ShapeCapabilityDefinition[];
165
- resolveAssetUrl?: (assetId: AssetId) => string | null;
166
- documentSnapshot?: unknown;
167
- sessionSnapshot?: unknown;
168
- }
169
-
170
- export interface ContainerBoundsQueryOptions {
171
- includeIntersecting?: boolean;
172
- }
173
-
174
- export interface RenderItem {
175
- id: ShapeId;
176
- shape: ShapeRecord;
177
- bounds: Box;
178
- isSelected: boolean;
179
- }
180
-
181
- export interface EditorPageState {
182
- pages: PageRecord[];
183
- currentPageId: PageId;
184
- currentPage: PageRecord | null;
185
- canDeleteCurrentPage: boolean;
186
- }
187
-
188
- export interface EditorToolState {
189
- activeToolId: string;
190
- isToolLocked: boolean;
191
- }
192
-
193
- export type ShapeSiblingOrderDirection = "backward" | "forward";
194
- export type ShapeSiblingOrderEdge = "back" | "front";
195
-
196
- export interface ShapeSiblingOrderState {
197
- parentId: ShapeParentId;
198
- index: number;
199
- count: number;
200
- canMoveBackward: boolean;
201
- canMoveForward: boolean;
202
- }
203
-
204
- export interface ShapeSelectionSiblingOrderState {
205
- parentId: ShapeParentId;
206
- selectedCount: number;
207
- count: number;
208
- canMoveBackward: boolean;
209
- canMoveForward: boolean;
210
- }
211
-
212
- export type ReparentShapePlacementFailureReason =
213
- | "notFound"
214
- | "locked"
215
- | "hidden"
216
- | "invalidParent"
217
- | "cycle"
218
- | "invalidBeforeId";
219
-
220
- export type ReparentShapePlacementResult =
221
- | { ok: true; movedIds: ShapeId[] }
222
- | { ok: false; reason: ReparentShapePlacementFailureReason };
223
-
224
- export interface ReparentShapePlacementInput {
225
- ids: readonly ShapeId[];
226
- parentId: ShapeParentId;
227
- beforeId?: ShapeId;
228
- }
229
-
230
- export interface ShapeGroupState {
231
- parentId: ShapeParentId;
232
- shapeIds: ShapeId[];
233
- bounds: Box;
234
- }
235
-
236
- export interface LayerTreeNode {
237
- id: ShapeId;
238
- parentId: ShapeParentId;
239
- pageId: PageId;
240
- type: ShapeRecord["type"];
241
- childIds: ShapeId[];
242
- index: number;
243
- depth: number;
244
- isHidden: boolean;
245
- isLocked: boolean;
246
- isEffectivelyHidden: boolean;
247
- isEffectivelyLocked: boolean;
248
- }
249
-
250
- export type LayerOrderDirection = "backward" | "forward";
251
- export type LayerOrderEdge = "back" | "front";
252
-
253
- export type ShapePropsPatch = Record<string, unknown>;
254
-
255
- export interface EditorShapeEditingState {
256
- editingShapeId: ShapeId | null;
257
- session: ShapeEditingSession | null;
258
- }
259
-
260
- export interface EditorShapeEditingEntryRequestState {
261
- request: ShapeEditingEntryRequest | null;
262
- }
263
-
264
- export interface EditorSelectionState {
265
- count: number;
266
- singleShapeType: ShapeRecord["type"] | null;
267
- commonShapeType: ShapeRecord["type"] | null;
268
- hasPointHandleSelection: boolean;
269
- hasFrameSelection: boolean;
270
- isMixedFrameAndPointHandleSelection: boolean;
271
- canDragPointHandles: boolean;
272
- hasSelectionRotation: boolean;
273
- hasMixedSelectionRotation: boolean;
274
- canResetSelectionRotation: boolean;
275
- frameBounds: Box | null;
276
- frameRotation: number;
277
- frameRotationCenter: Vec | null;
278
- toolbarAnchorPagePoint: Vec | null;
279
- }
280
-
281
- export interface EditorRenderHostDebugState {
282
- culledCount: number;
283
- visibleCount: number;
284
- retainedCount: number;
285
- retainedBaseCount: number;
286
- culledRangeCount: number;
287
- culledRangeSpan: number;
288
- culledRangesSummary: string;
289
- retainedBaseRangeCount: number;
290
- retainedBaseRangeSpan: number;
291
- retainedBaseRangesSummary: string;
292
- retainedRangeCount: number;
293
- retainedRangeSpan: number;
294
- retainedRangesSummary: string;
295
- retainedChangeCount: number;
296
- retainedAddedCount: number;
297
- retainedRemovedCount: number;
298
- selectedOutsideCulledCount: number;
299
- }
300
-
301
- export interface EditorOverlayDebugState {
302
- selectionFrameActive: boolean;
303
- selectionHandlesActive: boolean;
304
- bindingPreviewActive: boolean;
305
- brushBoxActive: boolean;
306
- selectionFrameChangeCount: number;
307
- selectionHandlesChangeCount: number;
308
- resizeHandleCount: number;
309
- rotateHandleCount: number;
310
- terminalHandleCount: number;
311
- middleHandleCount: number;
312
- customHandleCount: number;
313
- boundsSummary: string;
314
- rotation: number | null;
315
- strokeWidth: number | null;
316
- }
317
-
318
- interface ReadonlyStore {
319
- readonly recordsSignal: Signal<Map<string, EditorRecord>>;
320
- get(id: string): EditorRecord | undefined;
321
- getAll(): EditorRecord[];
322
- getByScope(scope: RecordScope): EditorRecord[];
323
- listen(listener: (change: StoreChange<EditorRecord>) => void): () => void;
324
- }
325
-
326
- import {
327
- areBoxesEqual,
328
- areShapeIdArraysEqual,
329
- areShapeIdSetsEqual,
330
- areShapePropsPatchesEqual,
331
- areVecsEqual,
332
- getCommonShapeType,
333
- getShapeAssetId,
334
- } from "./editorComputedHelpers";
335
-
336
- export class Editor {
337
- readonly store: ReadonlyStore;
338
- readonly [editorStoreSymbol]!: Store<EditorRecord>;
339
- readonly inputs = new InputsManager();
340
- readonly snapshots = new DocumentSnapshotManager(this);
341
- readonly clipboard = new ClipboardManager(this);
342
- readonly tools = new ToolManager(this);
343
- readonly camera = new CameraManager(this);
344
- readonly selection = new SelectionManager(this);
345
- readonly selectionLayout = new SelectionLayoutManager(this);
346
- readonly editing = new ShapeEditingManager(this);
347
- readonly geometry = new ShapeGeometryManager(this);
348
- readonly hierarchy = new ShapeHierarchyManager(this);
349
- readonly shapeUtils = new ShapeUtilRegistry();
350
- readonly shapeSvgExporters = new ShapeSvgExporterRegistry();
351
- readonly bindingUtils = new BindingUtilRegistry();
352
- readonly interactions = new InteractionHandlerRegistry();
353
- readonly selectionHandleInteractions = new SelectionHandleInteractionRegistry(
354
- this.interactions,
355
- );
356
- readonly queries: QueryManager;
357
- readonly bindings: BindingManager;
358
- readonly spatialIndex: SpatialIndexManager;
359
- readonly snaps: SnapManager;
360
- readonly renderWindow: RenderWindowManager;
361
- readonly selectionOverlay: SelectionOverlayManager;
362
- readonly transients = new InteractionTransientManager(this);
363
- readonly history: HistoryManager;
364
- readonly sideEffects = new SideEffectManager();
365
- readonly commands: EditorCommands;
366
- private readonly shapeCapabilityDefinitions: readonly ShapeCapabilityDefinition[];
367
- readonly brushBoxSignal: Signal<Box | null> = this.transients.brushBoxSignal;
368
- readonly brushBoxActiveSignal: Signal<boolean> =
369
- this.transients.brushBoxActiveSignal;
370
- readonly erasingShapeIdsSignal: Signal<ShapeId[]> =
371
- this.transients.erasingShapeIdsSignal;
372
- readonly erasingShapeIdsActiveSignal: Signal<boolean> =
373
- this.transients.erasingShapeIdsActiveSignal;
374
- readonly eraserTrailSignal: Signal<Vec[]> =
375
- this.transients.eraserTrailSignal;
376
- readonly eraserTrailActiveSignal: Signal<boolean> =
377
- this.transients.eraserTrailActiveSignal;
378
- readonly laserTrailSignal: Signal<LaserTrailState | null> =
379
- this.transients.laserTrailSignal;
380
- readonly laserTrailActiveSignal: Signal<boolean> =
381
- this.transients.laserTrailActiveSignal;
382
- readonly bindingPreviewSignal: Signal<ArrowBindingPreviewState | null> =
383
- this.transients.bindingPreviewSignal;
384
- readonly bindingPreviewActiveSignal: Signal<boolean> =
385
- this.transients.bindingPreviewActiveSignal;
386
- readonly dropTargetShapeIdSignal: Signal<ShapeId | null> =
387
- this.transients.dropTargetShapeIdSignal;
388
- readonly snapIndicatorsSignal: Signal<SnapIndicatorState[]>;
389
- readonly snapIndicatorsActiveSignal: Signal<boolean>;
390
- get viewportScreenSizeSignal(): Signal<{ w: number; h: number }> {
391
- return this.camera.viewportScreenSizeSignal;
392
- }
393
- readonly shapeEditingEntryRequestSignal: Signal<ShapeEditingEntryRequest | null> =
394
- this.editing.entryRequestSignal;
395
- private readonly _shapeDefaultPropsByTypeSignal: Atom<
396
- ReadonlyMap<ShapeRecord["type"], ShapePropsPatch>
397
- > = atom<ReadonlyMap<ShapeRecord["type"], ShapePropsPatch>>(
398
- "editor.shapeDefaultPropsByType",
399
- new Map(),
400
- );
401
- readonly shapeDefaultPropsByTypeSignal: Signal<
402
- ReadonlyMap<ShapeRecord["type"], ShapePropsPatch>
403
- > = this._shapeDefaultPropsByTypeSignal;
404
- private nextShapeNumber = 1;
405
- private nextPageNumber = 1;
406
- private nextBindingNumber = 1;
407
- private nextAssetNumber = 1;
408
- private assetUrlResolver: (assetId: AssetId) => string | null = () => null;
409
-
410
- private get _internalStore(): Store<EditorRecord> {
411
- return getEditorStore(this);
412
- }
413
-
414
- readonly sessionSignal = computed<SessionRecord>("editor.session", () => {
415
- const session = this._internalStore.recordsSignal
416
- .get()
417
- .get(DEFAULT_SESSION_ID);
418
- if (!isSessionRecord(session)) {
419
- throw new Error("Missing session record");
420
- }
421
- return session;
422
- });
423
-
424
- readonly currentPageIdSignal = computed<PageId>(
425
- "editor.currentPageId",
426
- () => {
427
- return this.sessionSignal.get().currentPageId;
428
- },
429
- );
430
-
431
- readonly currentPageShapeIdsSignal: Signal<ShapeId[]>;
432
-
433
- readonly currentPageShapesSignal: Signal<ShapeRecord[]>;
434
-
435
- readonly culledShapeIdsSignal: Signal<ShapeId[]>;
436
- readonly renderVisibleShapeIdsSignal: Signal<ShapeId[]>;
437
- readonly retainedShapeIdsSignal: Signal<ShapeId[]>;
438
- readonly selectionPageBoundsSignal: Signal<Box | null>;
439
- readonly selectionFrameBoundsSignal: Signal<Box | null>;
440
- readonly selectionToolbarAnchorPagePointSignal: Signal<Vec | null>;
441
-
442
- readonly pagesSignal = computed<PageRecord[]>("editor.pages", () => {
443
- return Array.from(this._internalStore.recordsSignal.get().values())
444
- .filter(isPageRecord)
445
- .sort((left, right) => left.index.localeCompare(right.index));
446
- });
447
-
448
- readonly currentPageSignal = computed<PageRecord | null>(
449
- "editor.currentPage",
450
- () => {
451
- const currentPageId = this.currentPageIdSignal.get();
452
- return (
453
- this.pagesSignal.get().find((page) => page.id === currentPageId) ?? null
454
- );
455
- },
456
- );
457
-
458
- readonly pageStateSignal = computed<EditorPageState>(
459
- "editor.pageState",
460
- () => {
461
- const pages = this.pagesSignal.get();
462
- const currentPageId = this.currentPageIdSignal.get();
463
- const currentPage =
464
- pages.find((page) => page.id === currentPageId) ?? null;
465
- return {
466
- pages,
467
- currentPageId,
468
- currentPage,
469
- canDeleteCurrentPage: pages.length > 1 && currentPage !== null,
470
- };
471
- },
472
- );
473
-
474
- readonly toolStateSignal = computed<EditorToolState>(
475
- "editor.toolState",
476
- () => {
477
- const session = this.sessionSignal.get();
478
- return {
479
- activeToolId: session.activeToolId,
480
- isToolLocked: session.isToolLocked,
481
- };
482
- },
483
- );
484
-
485
- readonly editingShapeIdSignal = computed<ShapeId | null>(
486
- "editor.editingShapeId",
487
- () => this.sessionSignal.get().editingShapeId,
488
- );
489
-
490
- readonly shapeEditingSessionSignal = computed<ShapeEditingSession | null>(
491
- "editor.shapeEditingSession",
492
- () => this.sessionSignal.get().shapeEditingSession,
493
- );
494
-
495
- readonly shapeEditingStateSignal = computed<EditorShapeEditingState>(
496
- "editor.shapeEditingState",
497
- () => ({
498
- editingShapeId: this.editingShapeIdSignal.get(),
499
- session: this.shapeEditingSessionSignal.get(),
500
- }),
501
- );
502
-
503
- readonly currentCameraSignal = computed<Camera>(
504
- "editor.currentCamera",
505
- () => {
506
- const session = this.sessionSignal.get();
507
- return (
508
- session.pageCameraById[this.currentPageIdSignal.get()] ?? DEFAULT_CAMERA
509
- );
510
- },
511
- );
512
-
513
- readonly selectedShapeIdsSignal = computed<ShapeId[]>(
514
- "editor.selectedShapeIds",
515
- () => {
516
- const session = this.sessionSignal.get();
517
- return session.pageSelectedShapeIdsById[session.currentPageId] ?? [];
518
- },
519
- { isEqual: areShapeIdArraysEqual },
520
- );
521
-
522
- readonly selectedShapeIdSetSignal = computed<Set<ShapeId>>(
523
- "editor.selectedShapeIdSet",
524
- () => new Set(this.selectedShapeIdsSignal.get()),
525
- { isEqual: areShapeIdSetsEqual },
526
- );
527
-
528
- readonly selectedShapesSignal = computed<ShapeRecord[]>(
529
- "editor.selectedShapes",
530
- () =>
531
- this.selectedShapeIdsSignal
532
- .get()
533
- .map((id) => this.getShapeSignal(id).get())
534
- .filter((shape): shape is ShapeRecord => !!shape),
535
- );
536
-
537
- readonly selectedShapeOverlayItemsSignal = computed<
538
- SelectedShapeOverlayItem[]
539
- >(
540
- "editor.selectedShapeOverlayItems",
541
- () => {
542
- if (this.toolStateSignal.get().activeToolId !== "select") {
543
- return [];
544
- }
545
- return this.selectedShapeIdsSignal
546
- .get()
547
- .map((id) => this.getShapeSignal(id).get())
548
- .filter((shape): shape is ShapeRecord => !!shape)
549
- .map((shape) => {
550
- const overlayInfo =
551
- this.getShapeUtil(shape).getSelectionOverlayInfo(shape);
552
- return {
553
- id: shape.id,
554
- usesSelectionPathOverlay: overlayInfo.usesSelectionPathOverlay,
555
- startPagePoint: overlayInfo.startPagePoint,
556
- endPagePoint: overlayInfo.endPagePoint,
557
- middlePagePoint: overlayInfo.middlePagePoint,
558
- path: overlayInfo.path,
559
- };
560
- });
561
- },
562
- { isEqual: areSelectedShapeOverlayItemsEqual },
563
- );
564
-
565
- readonly selectionStateSignal = computed<EditorSelectionState>(
566
- "editor.selectionState",
567
- () => {
568
- const selectedShapeIds = this.selectedShapeIdsSignal.get();
569
- const singleShape =
570
- selectedShapeIds.length === 1
571
- ? (this.getShapeSignal(selectedShapeIds[0]!).get() ?? null)
572
- : null;
573
- const selectedShapes = this.selectedShapesSignal.get();
574
- const commonShapeType = getCommonShapeType(selectedShapes);
575
- const isOnlySelected = selectedShapes.length === 1;
576
- const selectedShapeHandleAnchors = selectedShapes.map((shape) =>
577
- this.getShapeUtil(shape).getSelectionHandleAnchors(shape, {
578
- isOnlySelected,
579
- editor: this,
580
- }),
581
- );
582
- const hasPointHandleSelection = selectedShapeHandleAnchors.some(
583
- (anchors) =>
584
- anchors.terminalHandleAnchors.length > 0 ||
585
- anchors.middleHandleAnchors.length > 0 ||
586
- (anchors.customHandleAnchors?.length ?? 0) > 0,
587
- );
588
- const hasFrameSelection = selectedShapes.some((shape) =>
589
- this.getShapeUtil(shape).contributesToSelectionFrame(shape, {
590
- editor: this,
591
- }),
592
- );
593
- const isMixedFrameAndPointHandleSelection =
594
- hasPointHandleSelection && hasFrameSelection;
595
- const singleShapeHandleAnchors =
596
- singleShape ?
597
- this.getShapeUtil(singleShape).getSelectionHandleAnchors(
598
- singleShape,
599
- { isOnlySelected, editor: this },
600
- )
601
- : null;
602
- const canDragPointHandles =
603
- selectedShapeIds.length === 1 &&
604
- !!singleShapeHandleAnchors &&
605
- (singleShapeHandleAnchors.terminalHandleAnchors.length > 0 ||
606
- (singleShapeHandleAnchors.customHandleAnchors?.length ?? 0) > 0);
607
- const hasSelectionRotation = this.queries.selectionHasRotationSignal.get();
608
- return {
609
- count: selectedShapeIds.length,
610
- singleShapeType: singleShape?.type ?? null,
611
- commonShapeType,
612
- hasPointHandleSelection,
613
- hasFrameSelection,
614
- isMixedFrameAndPointHandleSelection,
615
- canDragPointHandles,
616
- hasSelectionRotation,
617
- hasMixedSelectionRotation:
618
- !this.queries.selectionHasCompatibleRotationSignal.get(),
619
- canResetSelectionRotation:
620
- hasSelectionRotation && hasFrameSelection,
621
- frameBounds: this.selectionFrameBoundsSignal.get(),
622
- frameRotation: this.queries.selectionRotationSignal.get(),
623
- frameRotationCenter: this.queries.selectionRotationCenterSignal.get(),
624
- toolbarAnchorPagePoint:
625
- this.selectionToolbarAnchorPagePointSignal.get(),
626
- };
627
- },
628
- );
629
-
630
- readonly pageTransformSignal = computed<Mat>("editor.pageTransform", () => {
631
- const camera = this.currentCameraSignal.get();
632
- return Mat.Scale(camera.z, camera.z).compose(
633
- Mat.Translate(-camera.x, -camera.y),
634
- );
635
- });
636
-
637
- readonly cameraZoomSignal = computed<number>("editor.cameraZoom", () => {
638
- return this.currentCameraSignal.get().z;
639
- });
640
-
641
- readonly viewportPageBoundsSignal = computed<Box | null>(
642
- "editor.viewportPageBounds",
643
- () => {
644
- const { w, h } = this.viewportScreenSizeSignal.get();
645
- if (w <= 0 || h <= 0) {
646
- return null;
647
- }
648
-
649
- const camera = this.currentCameraSignal.get();
650
- return new Box(camera.x, camera.y, w / camera.z, h / camera.z);
651
- },
652
- );
653
-
654
- readonly renderViewportPageBoundsSignal = computed<Box | null>(
655
- "editor.renderViewportPageBounds",
656
- (previous) => {
657
- const viewportBounds = this.viewportPageBoundsSignal.get();
658
- if (!viewportBounds) {
659
- return null;
660
- }
661
-
662
- if (
663
- previous !== UNINITIALIZED &&
664
- previous &&
665
- doesBoxContainBox(previous, viewportBounds)
666
- ) {
667
- return previous;
668
- }
669
-
670
- return viewportBounds.expand(
671
- RENDER_CULLING_OVERSCAN_SCREEN / this.cameraZoomSignal.get(),
672
- );
673
- },
674
- { isEqual: areBoxesEqual },
675
- );
676
-
677
- readonly renderItemsSignal: Signal<RenderItem[]>;
678
- readonly renderHostDebugStateSignal: Signal<EditorRenderHostDebugState>;
679
- readonly historyStateSignal: Signal<HistoryState>;
680
- readonly shapeRenderOrderByIdSignal: Signal<Map<ShapeId, number>>;
681
- readonly culledShapeIdSetSignal: Signal<Set<ShapeId>>;
682
- readonly selectedShapeIdsOutsideCulledSignal: Signal<ShapeId[]>;
683
- readonly selectedShapeIdsOutsideCulledSetSignal: Signal<Set<ShapeId>>;
684
- readonly renderVisibleShapeIdSetSignal: Signal<Set<ShapeId>>;
685
-
686
- private readonly shapeSignals = new Map<
687
- ShapeId,
688
- Signal<ShapeRecord | undefined>
689
- >();
690
- private readonly shapeSelectedSignals = new Map<ShapeId, Signal<boolean>>();
691
- private readonly shapeRenderOrderSignals = new Map<ShapeId, Signal<number>>();
692
- private readonly shapeRenderVisibleSignals = new Map<
693
- ShapeId,
694
- Signal<boolean>
695
- >();
696
- private readonly shapeDocumentVisibleSignals = new Map<
697
- ShapeId,
698
- Signal<boolean>
699
- >();
700
- private readonly shapeEditingSessionSignals = new Map<
701
- ShapeId,
702
- Signal<ShapeEditingSession | null>
703
- >();
704
- private readonly shapeDropTargetSignals = new Map<ShapeId, Signal<boolean>>();
705
- private readonly shapeErasingSignals = new Map<ShapeId, Signal<boolean>>();
706
- private readonly shapeSelectedDescendantTransformAncestorSignals = new Map<
707
- ShapeId,
708
- Signal<boolean>
709
- >();
710
- private lastPointerDownForClickCount:
711
- | { timestamp: number; screenPoint: Vec }
712
- | null = null;
713
- private lastPointerUpForClickCount:
714
- | { timestamp: number; screenPoint: Vec }
715
- | null = null;
716
- private currentPointerClickCount = 1;
717
-
718
- readonly selectionOverlayFrameGeometrySignal: Signal<SelectionOverlayFrameGeometryState | null>;
719
- readonly selectionOverlayCompanionFrameGeometriesSignal: Signal<
720
- SelectionOverlayFrameGeometryState[]
721
- >;
722
- readonly selectionOverlayArrowPathSignal: Signal<string | null>;
723
- readonly selectionOverlayFrameStyleSignal: Signal<SelectionOverlayFrameStyleState>;
724
- readonly selectionOverlayFrameSignal: Signal<SelectionOverlayFrameState | null>;
725
- readonly selectionOverlayHandleAnchorsSignal: Signal<SelectionOverlayHandleAnchorsState | null>;
726
- readonly selectionOverlayHandlesSignal: Signal<SelectionOverlayHandlesState | null>;
727
- readonly selectionOverlayHandleCountsSignal: Signal<SelectionOverlayHandleCountsState | null>;
728
- readonly selectionOverlaySignal: Signal<SelectionOverlayState | null>;
729
- readonly overlayDebugStateSignal: Signal<EditorOverlayDebugState>;
730
-
731
- constructor(options: EditorOptions = {}) {
732
- this.shapeCapabilityDefinitions = options.shapeCapabilities ?? [];
733
- if (options.resolveAssetUrl) {
734
- this.assetUrlResolver = options.resolveAssetUrl;
735
- }
736
-
737
- for (const util of options.shapeUtils ?? []) {
738
- this.shapeUtils.register(util);
739
- }
740
- for (const exporter of options.shapeSvgExporters ?? []) {
741
- this.shapeSvgExporters.register(exporter);
742
- }
743
- for (const util of options.bindingUtils ?? []) {
744
- this.bindingUtils.register(util);
745
- }
746
-
747
- const store = new Store<EditorRecord>(
748
- this.snapshots.buildInitialRecords(
749
- options.documentSnapshot ?? null,
750
- options.sessionSnapshot ?? null,
751
- ),
752
- );
753
- setEditorStore(this, store);
754
- this.store = store;
755
- this.snapshots.ensureSessionIntegrity();
756
- this.queries = new QueryManager(this);
757
- this.bindings = new BindingManager(this);
758
- this.spatialIndex = new SpatialIndexManager(this, this.queries);
759
- this.snaps = new SnapManager(this);
760
- this.snapIndicatorsSignal = this.snaps.indicatorsSignal;
761
- this.snapIndicatorsActiveSignal = this.snaps.activeSignal;
762
- this.currentPageShapeIdsSignal = this.queries.currentPageShapeIdsSignal;
763
- this.currentPageShapesSignal = this.queries.currentPageShapesSignal;
764
- this.selectionPageBoundsSignal = this.queries.selectionPageBoundsSignal;
765
- this.selectionFrameBoundsSignal = this.queries.selectionFrameBoundsSignal;
766
- this.selectionToolbarAnchorPagePointSignal =
767
- this.queries.selectionToolbarAnchorPagePointSignal;
768
- this.selectionOverlay = new SelectionOverlayManager(this);
769
- this.selectionOverlayFrameGeometrySignal =
770
- this.selectionOverlay.frameGeometrySignal;
771
- this.selectionOverlayCompanionFrameGeometriesSignal =
772
- this.selectionOverlay.companionFrameGeometriesSignal;
773
- this.selectionOverlayArrowPathSignal =
774
- this.selectionOverlay.arrowPathSignal;
775
- this.selectionOverlayFrameStyleSignal =
776
- this.selectionOverlay.frameStyleSignal;
777
- this.selectionOverlayFrameSignal = this.selectionOverlay.frameSignal;
778
- this.selectionOverlayHandleAnchorsSignal =
779
- this.selectionOverlay.handleAnchorsSignal;
780
- this.selectionOverlayHandlesSignal = this.selectionOverlay.handlesSignal;
781
- this.selectionOverlayHandleCountsSignal =
782
- this.selectionOverlay.handleCountsSignal;
783
- this.selectionOverlaySignal = this.selectionOverlay.overlaySignal;
784
- this.overlayDebugStateSignal = this.selectionOverlay.debugStateSignal;
785
- this.renderWindow = new RenderWindowManager(this);
786
- this.shapeRenderOrderByIdSignal =
787
- this.renderWindow.shapeRenderOrderByIdSignal;
788
- this.culledShapeIdsSignal = this.renderWindow.culledShapeIdsSignal;
789
- this.culledShapeIdSetSignal = this.renderWindow.culledShapeIdSetSignal;
790
- this.selectedShapeIdsOutsideCulledSignal =
791
- this.renderWindow.selectedShapeIdsOutsideCulledSignal;
792
- this.selectedShapeIdsOutsideCulledSetSignal =
793
- this.renderWindow.selectedShapeIdsOutsideCulledSetSignal;
794
- this.renderVisibleShapeIdsSignal =
795
- this.renderWindow.renderVisibleShapeIdsSignal;
796
- this.retainedShapeIdsSignal = this.renderWindow.retainedShapeIdsSignal;
797
- this.renderVisibleShapeIdSetSignal =
798
- this.renderWindow.renderVisibleShapeIdSetSignal;
799
- this.renderItemsSignal = this.renderWindow.renderItemsSignal;
800
- this.renderHostDebugStateSignal =
801
- this.renderWindow.renderHostDebugStateSignal;
802
- this.syncShapeCounter();
803
- this.syncPageCounter();
804
- this.syncBindingCounter();
805
- this.syncAssetCounter();
806
- this.bindings.repairLoadedBindings("system");
807
- this.history = new HistoryManager(this);
808
- this.historyStateSignal = this.history.state;
809
- this.commands = createEditorCommands(this);
810
- this.registerBuiltInSideEffects();
811
- }
812
-
813
- private registerBuiltInSideEffects(): void {
814
- // Binding cleanup must run before the shapes are removed so the bindings
815
- // can still read the doomed shapes. Selection/editing-session repair runs
816
- // after the records are gone.
817
- this.sideEffects.registerBeforeDeleteHandler("shape", (ids, source) => {
818
- this.bindings.cleanupBindingsForDeletedShapes(ids as ShapeId[], source);
819
- });
820
- this.sideEffects.registerAfterDeleteHandler("shape", (ids, source) => {
821
- this.removeShapeIdsFromSelection(ids as ShapeId[], source);
822
- this.removeShapeIdsFromEditingSession(ids as ShapeId[], source);
823
- });
824
- }
825
-
826
- dispatch(event: EditorEvent): void {
827
- const normalizedEvent = this.normalizeEvent(event);
828
- this.inputs.handleEvent(normalizedEvent);
829
-
830
- if (normalizedEvent.type === "keyboard" && normalizedEvent.name === "key_down") {
831
- if (
832
- normalizedEvent.altKey &&
833
- !normalizedEvent.accelKey &&
834
- !normalizedEvent.shiftKey &&
835
- (normalizedEvent.key === "ArrowDown" ||
836
- normalizedEvent.key === "ArrowUp")
837
- ) {
838
- const direction =
839
- normalizedEvent.key === "ArrowDown" ? "backward" : "forward";
840
- if (this.moveSelectionWithinParent(direction, "user")) {
841
- return;
842
- }
843
- }
844
-
845
- if (normalizedEvent.accelKey && normalizedEvent.key.toLowerCase() === "z") {
846
- if (normalizedEvent.shiftKey) {
847
- this.redo();
848
- } else {
849
- this.undo();
850
- }
851
- return;
852
- }
853
-
854
- if (!normalizedEvent.accelKey && !normalizedEvent.altKey) {
855
- const shortcutToolId = this.tools.getToolIdForShortcut(
856
- normalizedEvent.key,
857
- );
858
- if (shortcutToolId) {
859
- this.commands.setActiveTool(shortcutToolId, { source: "system" });
860
- return;
861
- }
862
-
863
- if (normalizedEvent.key === "Backspace" || normalizedEvent.key === "Delete") {
864
- this.deleteSelection("user");
865
- return;
866
- }
867
-
868
- }
869
- }
870
-
871
- if (
872
- normalizedEvent.type === "keyboard" &&
873
- normalizedEvent.name === "key_down" &&
874
- normalizedEvent.key === "Escape"
875
- ) {
876
- const wasInteracting = !this.tools.isActiveToolInInitialState();
877
- if (!wasInteracting && this.getActiveToolId() !== "select") {
878
- this.commands.setActiveTool("select", { source: "system" });
879
- } else {
880
- this.cancelInteractionAndClearTransients("escape");
881
- }
882
- return;
883
- }
884
-
885
- if (normalizedEvent.type === "wheel") {
886
- this.handleWheelEvent(normalizedEvent);
887
- return;
888
- }
889
-
890
- if (normalizedEvent.type === "cancel") {
891
- this.cancelInteractionAndClearTransients(normalizedEvent.reason);
892
- return;
893
- }
894
-
895
- if (normalizedEvent.type === "pointer" && normalizedEvent.name === "pointer_cancel") {
896
- this.cancelInteractionAndClearTransients("pointer_cancel");
897
- return;
898
- }
899
-
900
- if (this.interactions.handleEvent(this, normalizedEvent) === "handled") {
901
- return;
902
- }
903
-
904
- this.tools.dispatch(normalizedEvent);
905
-
906
- if (
907
- normalizedEvent.type === "pointer" &&
908
- normalizedEvent.name === "pointer_up"
909
- ) {
910
- const doubleClickEvent = this.getDoubleClickEvent(normalizedEvent);
911
- if (doubleClickEvent) {
912
- if (this.interactions.handleEvent(this, doubleClickEvent) !== "handled") {
913
- this.tools.dispatch(doubleClickEvent);
914
- }
915
- }
916
- }
917
- }
918
-
919
- handleInteractionEvent(event: EditorEvent): boolean {
920
- const normalizedEvent = this.normalizeEvent(event);
921
- this.inputs.handleEvent(normalizedEvent);
922
- return this.interactions.handleEvent(this, normalizedEvent) === "handled";
923
- }
924
-
925
- private normalizeEvent(event: EditorEvent): EditorEvent {
926
- if (event.type !== "pointer") {
927
- return event;
928
- }
929
-
930
- if (event.name === "pointer_up") {
931
- // Pointer up inherits the click count computed from the preceding down/up
932
- // sequence so tools can distinguish single-click caret placement from
933
- // double-click select-all without relying on host DOM timing quirks.
934
- const nextEvent =
935
- event.clickCount === this.currentPointerClickCount
936
- ? event
937
- : ({
938
- ...event,
939
- clickCount: this.currentPointerClickCount,
940
- } satisfies PointerEditorEvent);
941
- this.lastPointerUpForClickCount = {
942
- timestamp: nextEvent.timestamp,
943
- screenPoint: nextEvent.screenPoint.clone(),
944
- };
945
- return nextEvent;
946
- }
947
-
948
- if (event.name !== "pointer_down") {
949
- return event;
950
- }
951
-
952
- // Keep double-click detection in core so host layers only forward pointer
953
- // events; select/text tools can then share one consistent click contract.
954
- const previousDown = this.lastPointerDownForClickCount;
955
- const previousUp = this.lastPointerUpForClickCount;
956
- const nextClickCount =
957
- previousDown &&
958
- previousUp &&
959
- previousUp.timestamp >= previousDown.timestamp &&
960
- event.timestamp - previousUp.timestamp <= DOUBLE_CLICK_DURATION_MS &&
961
- previousUp.screenPoint.dist2(event.screenPoint) <=
962
- DOUBLE_CLICK_DISTANCE_SQUARED
963
- ? 2
964
- : 1;
965
-
966
- this.lastPointerDownForClickCount = {
967
- timestamp: event.timestamp,
968
- screenPoint: event.screenPoint.clone(),
969
- };
970
- this.currentPointerClickCount = nextClickCount;
971
-
972
- if (event.clickCount === nextClickCount) {
973
- return event;
974
- }
975
-
976
- return {
977
- ...event,
978
- clickCount: nextClickCount,
979
- } satisfies PointerEditorEvent;
980
- }
981
-
982
- private getDoubleClickEvent(
983
- event: PointerEditorEvent,
984
- ): ClickEditorEvent | null {
985
- if ((event.clickCount ?? 1) < 2 || this.currentPointerClickCount < 2) {
986
- return null;
987
- }
988
-
989
- return {
990
- type: "click",
991
- name: "double_click",
992
- phase: "up",
993
- timestamp: event.timestamp,
994
- pointerId: event.pointerId,
995
- button: event.button,
996
- buttons: event.buttons,
997
- pointerType: event.pointerType,
998
- screenPoint: event.screenPoint.clone(),
999
- pagePoint: event.pagePoint.clone(),
1000
- pressure: event.pressure,
1001
- shiftKey: event.shiftKey,
1002
- altKey: event.altKey,
1003
- ctrlKey: event.ctrlKey,
1004
- metaKey: event.metaKey,
1005
- accelKey: event.accelKey,
1006
- };
1007
- }
1008
-
1009
- listen(listener: (change: StoreChange<EditorRecord>) => void): () => void {
1010
- return this.store.listen((change) => listener(change));
1011
- }
1012
-
1013
- getRenderItems(): RenderItem[] {
1014
- return this.renderItemsSignal.get();
1015
- }
1016
-
1017
- getPages(): PageRecord[] {
1018
- return this.pagesSignal.get();
1019
- }
1020
-
1021
- getCurrentPageId(): PageId {
1022
- return this.currentPageIdSignal.get();
1023
- }
1024
-
1025
- getActiveToolId(): string {
1026
- return this.sessionSignal.get().activeToolId;
1027
- }
1028
-
1029
- isToolLocked(): boolean {
1030
- return this.sessionSignal.get().isToolLocked;
1031
- }
1032
-
1033
- isActiveToolInInitialState(): boolean {
1034
- return this.tools.isActiveToolInInitialState();
1035
- }
1036
-
1037
- getEditingShapeId(): ShapeId | null {
1038
- return this.editingShapeIdSignal.get();
1039
- }
1040
-
1041
- getShapeEditingSession(): ShapeEditingSession | null {
1042
- return this.shapeEditingSessionSignal.get();
1043
- }
1044
-
1045
- getShapeEditingEntryRequest(): ShapeEditingEntryRequest | null {
1046
- return this.shapeEditingEntryRequestSignal.get();
1047
- }
1048
-
1049
- resetPointerClickTracking(): void {
1050
- this.lastPointerDownForClickCount = null;
1051
- this.lastPointerUpForClickCount = null;
1052
- this.currentPointerClickCount = 1;
1053
- }
1054
-
1055
- getCurrentPageShapeIds(): ShapeId[] {
1056
- return this.currentPageShapeIdsSignal.get();
1057
- }
1058
-
1059
- getPage(id: PageId): PageRecord | undefined {
1060
- const record = this._internalStore.get(id);
1061
- return isPageRecord(record) ? record : undefined;
1062
- }
1063
-
1064
- getCurrentCamera(): Camera {
1065
- return this.camera.getCurrentCamera();
1066
- }
1067
-
1068
- undo(): boolean {
1069
- this.cancelInteractionForCommand();
1070
- return this.history.undo();
1071
- }
1072
-
1073
- redo(): boolean {
1074
- this.cancelInteractionForCommand();
1075
- return this.history.redo();
1076
- }
1077
-
1078
- createPageAndSelect(
1079
- input?: CreatePageInput,
1080
- source: ChangeSource = "user",
1081
- ): PageRecord {
1082
- const page = this.commands.createPage(input, { source });
1083
- this.commands.setCurrentPageId(page.id, { source });
1084
- return page;
1085
- }
1086
-
1087
- selectPage(pageId: PageId, source: ChangeSource = "user"): void {
1088
- this.commands.setCurrentPageId(pageId, { source });
1089
- }
1090
-
1091
- renamePage(
1092
- pageId: PageId,
1093
- name: string,
1094
- source: ChangeSource = "user",
1095
- ): void {
1096
- this.commands.renamePage({ id: pageId, name }, { source });
1097
- }
1098
-
1099
- deletePage(pageId: PageId, source: ChangeSource = "user"): boolean {
1100
- this.cancelInteractionForCommand();
1101
- return this.commands.deletePage(pageId, { source });
1102
- }
1103
-
1104
- setActiveTool(toolId: string, source: ChangeSource = "system"): void {
1105
- this.commands.setActiveTool(toolId, { source });
1106
- }
1107
-
1108
- setToolLocked(locked: boolean, source: ChangeSource = "system"): void {
1109
- this.commands.setToolLocked(locked, { source });
1110
- }
1111
-
1112
- toggleToolLocked(source: ChangeSource = "system"): void {
1113
- this.setToolLocked(!this.isToolLocked(), source);
1114
- }
1115
-
1116
- getCamera(pageId: PageId = this.getCurrentPageId()): Camera {
1117
- return this.camera.getCamera(pageId);
1118
- }
1119
-
1120
- pageToScreen(point: Vec, pageId: PageId = this.getCurrentPageId()): Vec {
1121
- return this.camera.pageToScreen(point, pageId);
1122
- }
1123
-
1124
- screenToPage(point: Vec, pageId: PageId = this.getCurrentPageId()): Vec {
1125
- return this.camera.screenToPage(point, pageId);
1126
- }
1127
-
1128
- getSelectedShapeIds(pageId: PageId = this.getCurrentPageId()): ShapeId[] {
1129
- if (pageId === this.getCurrentPageId()) {
1130
- return this.selectedShapeIdsSignal.get();
1131
- }
1132
- return this.sessionSignal.get().pageSelectedShapeIdsById[pageId] ?? [];
1133
- }
1134
-
1135
- isShapeHidden(shapeId: ShapeId): boolean {
1136
- const seen = new Set<ShapeId>();
1137
- let shape = this.getShape(shapeId);
1138
- while (shape) {
1139
- if (shape.isHidden) {
1140
- return true;
1141
- }
1142
- if (!shape.parentId.startsWith("shape:")) {
1143
- return false;
1144
- }
1145
-
1146
- const parentId = shape.parentId as ShapeId;
1147
- if (seen.has(parentId)) {
1148
- return false;
1149
- }
1150
- seen.add(parentId);
1151
- shape = this.getShape(parentId);
1152
- }
1153
-
1154
- return false;
1155
- }
1156
-
1157
- getSelectedShapes(): ShapeRecord[] {
1158
- return this.selectedShapesSignal.get();
1159
- }
1160
-
1161
- getDefaultShapeProps<TProps extends object = object>(
1162
- type: ShapeRecord["type"],
1163
- ): TProps {
1164
- const util = this.shapeUtils.get(type);
1165
- const override = this._shapeDefaultPropsByTypeSignal.get().get(type) ?? {};
1166
- return util.validateProps({
1167
- ...util.getDefaultProps(),
1168
- ...override,
1169
- }) as TProps;
1170
- }
1171
-
1172
- updateDefaultShapeProps(
1173
- type: ShapeRecord["type"],
1174
- props: ShapePropsPatch,
1175
- ): void {
1176
- const util = this.shapeUtils.get(type);
1177
- const current = this._shapeDefaultPropsByTypeSignal.get().get(type) ?? {};
1178
- const nextProps = util.validateProps({
1179
- ...util.getDefaultProps(),
1180
- ...current,
1181
- ...props,
1182
- });
1183
- const fallback = util.validateProps(util.getDefaultProps());
1184
- const nextOverride: ShapePropsPatch = {};
1185
-
1186
- for (const [key, value] of Object.entries(nextProps)) {
1187
- if ((fallback as Record<string, unknown>)[key] !== value) {
1188
- nextOverride[key] = value;
1189
- }
1190
- }
1191
-
1192
- if (areShapePropsPatchesEqual(current, nextOverride)) {
1193
- return;
1194
- }
1195
-
1196
- const nextDefaults = new Map(this._shapeDefaultPropsByTypeSignal.get());
1197
- if (Object.keys(nextOverride).length === 0) {
1198
- nextDefaults.delete(type);
1199
- } else {
1200
- nextDefaults.set(type, nextOverride);
1201
- }
1202
- this._shapeDefaultPropsByTypeSignal.set(nextDefaults);
1203
- }
1204
-
1205
- getSelectionParentOrderState(): ShapeSelectionSiblingOrderState | null {
1206
- return this.hierarchy.getSelectionParentOrderState();
1207
- }
1208
-
1209
- getSelectionGroupState(): ShapeGroupState | null {
1210
- return this.hierarchy.getSelectionGroupState();
1211
- }
1212
-
1213
- canGroupSelection(): boolean {
1214
- return this.hierarchy.canGroupSelection();
1215
- }
1216
-
1217
- getLayerTree(pageId: PageId = this.getCurrentPageId()): LayerTreeNode[] {
1218
- return this.hierarchy.getLayerTree(pageId);
1219
- }
1220
-
1221
- getLayerNode(id: ShapeId): LayerTreeNode | null {
1222
- return this.hierarchy.getLayerNode(id);
1223
- }
1224
-
1225
- canGroupShapes(ids: readonly ShapeId[]): boolean {
1226
- return this.hierarchy.canGroupShapes(ids);
1227
- }
1228
-
1229
- groupShapes(
1230
- ids: readonly ShapeId[],
1231
- source: ChangeSource = "user",
1232
- ): ShapeRecord | null {
1233
- return this.hierarchy.groupShapes(ids, source);
1234
- }
1235
-
1236
- groupSelection(source: ChangeSource = "user"): ShapeRecord | null {
1237
- return this.hierarchy.groupSelection(source);
1238
- }
1239
-
1240
- getUngroupableSelectedShapeIds(): ShapeId[] {
1241
- return this.hierarchy.getUngroupableSelectedShapeIds();
1242
- }
1243
-
1244
- getUngroupableShapeIds(ids: readonly ShapeId[]): ShapeId[] {
1245
- return this.hierarchy.getUngroupableShapeIds(ids);
1246
- }
1247
-
1248
- canUngroupSelection(): boolean {
1249
- return this.hierarchy.canUngroupSelection();
1250
- }
1251
-
1252
- canUngroupShapes(ids: readonly ShapeId[]): boolean {
1253
- return this.hierarchy.canUngroupShapes(ids);
1254
- }
1255
-
1256
- ungroupShapes(
1257
- ids: readonly ShapeId[],
1258
- source: ChangeSource = "user",
1259
- ): ShapeId[] {
1260
- return this.hierarchy.ungroupShapes(ids, source);
1261
- }
1262
-
1263
- ungroupSelection(source: ChangeSource = "user"): ShapeId[] {
1264
- return this.hierarchy.ungroupSelection(source);
1265
- }
1266
-
1267
- getSelectionSiblingOrderState(): ShapeSiblingOrderState | null {
1268
- return this.hierarchy.getSelectionSiblingOrderState();
1269
- }
1270
-
1271
- canMoveSelectionWithinParent(
1272
- direction: ShapeSiblingOrderDirection,
1273
- ): boolean {
1274
- return this.hierarchy.canMoveSelectionWithinParent(direction);
1275
- }
1276
-
1277
- canMoveSelectionInParentOrder(
1278
- direction: ShapeSiblingOrderDirection,
1279
- ): boolean {
1280
- return this.hierarchy.canMoveSelectionInParentOrder(direction);
1281
- }
1282
-
1283
- canMoveShapesInParentOrder(
1284
- ids: readonly ShapeId[],
1285
- direction: LayerOrderDirection,
1286
- ): boolean {
1287
- return this.hierarchy.canMoveShapesInParentOrder(ids, direction);
1288
- }
1289
-
1290
- moveShapesInParentOrder(
1291
- ids: readonly ShapeId[],
1292
- direction: LayerOrderDirection,
1293
- source: ChangeSource = "user",
1294
- ): boolean {
1295
- return this.hierarchy.moveShapesInParentOrder(ids, direction, source);
1296
- }
1297
-
1298
- moveShapesToParentOrderEdge(
1299
- ids: readonly ShapeId[],
1300
- edge: LayerOrderEdge,
1301
- source: ChangeSource = "user",
1302
- ): boolean {
1303
- return this.hierarchy.moveShapesToParentOrderEdge(ids, edge, source);
1304
- }
1305
-
1306
- moveSelectionWithinParent(
1307
- direction: ShapeSiblingOrderDirection,
1308
- source: ChangeSource = "user",
1309
- ): boolean {
1310
- return this.hierarchy.moveSelectionWithinParent(direction, source);
1311
- }
1312
-
1313
- /**
1314
- * Align selected top-level shapes along an edge or center of their combined
1315
- * page bounds. Only shapes parented directly to the current page are moved so
1316
- * the page-space delta maps directly onto `x`/`y`. Needs at least two shapes.
1317
- */
1318
- alignSelection(
1319
- mode:
1320
- | "left"
1321
- | "horizontal-center"
1322
- | "right"
1323
- | "top"
1324
- | "vertical-center"
1325
- | "bottom",
1326
- source: ChangeSource = "user",
1327
- ): boolean {
1328
- this.cancelInteractionForCommand();
1329
- return this.selectionLayout.align(mode, source);
1330
- }
1331
-
1332
- /**
1333
- * Distribute selected top-level shapes so the gaps between them are equal
1334
- * along the given axis. Needs at least three shapes.
1335
- */
1336
- distributeSelection(
1337
- axis: "horizontal" | "vertical",
1338
- source: ChangeSource = "user",
1339
- ): boolean {
1340
- this.cancelInteractionForCommand();
1341
- return this.selectionLayout.distribute(axis, source);
1342
- }
1343
-
1344
- moveShapesToParentPlacement(
1345
- input: ReparentShapePlacementInput,
1346
- source: ChangeSource = "user",
1347
- ): boolean {
1348
- return this.hierarchy.moveShapesToParentPlacement(input, source);
1349
- }
1350
-
1351
- moveShapesToParentPlacementResult(
1352
- input: ReparentShapePlacementInput,
1353
- source: ChangeSource = "user",
1354
- ): ReparentShapePlacementResult {
1355
- return this.hierarchy.moveShapesToParentPlacementResult(input, source);
1356
- }
1357
-
1358
- moveSelectionInParentOrder(
1359
- direction: ShapeSiblingOrderDirection,
1360
- source: ChangeSource = "user",
1361
- ): boolean {
1362
- return this.hierarchy.moveSelectionInParentOrder(direction, source);
1363
- }
1364
-
1365
- moveSelectionToParentOrderEdge(
1366
- edge: ShapeSiblingOrderEdge,
1367
- source: ChangeSource = "user",
1368
- ): boolean {
1369
- return this.hierarchy.moveSelectionToParentOrderEdge(edge, source);
1370
- }
1371
-
1372
- canEditShape(shapeOrId: ShapeRecord | ShapeId | null | undefined): boolean {
1373
- return this.editing.canEditShape(shapeOrId);
1374
- }
1375
-
1376
- startEditingShape(
1377
- input: StartEditingShapeInput,
1378
- source: ChangeSource = "user",
1379
- ): ShapeEditingSession | null {
1380
- return this.editing.start(input, source);
1381
- }
1382
-
1383
- completeEditing(source: ChangeSource = "user"): boolean {
1384
- return this.editing.complete(source);
1385
- }
1386
-
1387
- cancelEditing(source: ChangeSource = "user"): boolean {
1388
- return this.editing.cancel(source);
1389
- }
1390
-
1391
- setShapeEditingComposition(
1392
- isComposing: boolean,
1393
- source: ChangeSource = "system",
1394
- ): void {
1395
- this.editing.setComposition(isComposing, source);
1396
- }
1397
-
1398
- consumeShapeEditingEntryRequest(requestId: number): void {
1399
- this.editing.consumeEntryRequest(requestId);
1400
- }
1401
-
1402
- deleteSelection(source: ChangeSource = "user"): void {
1403
- this.deleteShapesById(this.getSelectedShapeIds(), source);
1404
- }
1405
-
1406
- deleteShapesById(
1407
- ids: readonly ShapeId[],
1408
- source: ChangeSource = "user",
1409
- ): void {
1410
- const uniqueIds = Array.from(new Set(ids));
1411
- if (uniqueIds.length === 0) {
1412
- return;
1413
- }
1414
- this.cancelInteractionForCommand();
1415
- this.commands.deleteShapes(uniqueIds, { source });
1416
- }
1417
-
1418
- setShapesHidden(
1419
- ids: readonly ShapeId[],
1420
- isHidden: boolean,
1421
- source: ChangeSource = "user",
1422
- ): ShapeId[] {
1423
- const nextIds = Array.from(
1424
- new Set(
1425
- ids.filter((id) => {
1426
- const shape = this.getShape(id);
1427
- return !!shape && shape.isHidden !== isHidden;
1428
- }),
1429
- ),
1430
- );
1431
- if (nextIds.length === 0) {
1432
- return [];
1433
- }
1434
-
1435
- this.cancelInteractionForCommand();
1436
- this.commands.updateShapes(
1437
- nextIds.map((id) => ({
1438
- id,
1439
- isHidden,
1440
- })),
1441
- { source },
1442
- );
1443
-
1444
- if (isHidden) {
1445
- this.removeShapeIdsFromSelection(
1446
- this.getShapeIdsIncludingDescendants(nextIds),
1447
- source,
1448
- );
1449
- this.removeShapeIdsFromEditingSession(
1450
- this.getShapeIdsIncludingDescendants(nextIds),
1451
- source,
1452
- );
1453
- }
1454
-
1455
- return nextIds;
1456
- }
1457
-
1458
- setShapesLocked(
1459
- ids: readonly ShapeId[],
1460
- isLocked: boolean,
1461
- source: ChangeSource = "user",
1462
- ): ShapeId[] {
1463
- const nextIds = Array.from(
1464
- new Set(
1465
- ids.filter((id) => {
1466
- const shape = this.getShape(id);
1467
- return !!shape && shape.isLocked !== isLocked;
1468
- }),
1469
- ),
1470
- );
1471
- if (nextIds.length === 0) {
1472
- return [];
1473
- }
1474
-
1475
- this.cancelInteractionForCommand();
1476
- this.commands.updateShapes(
1477
- nextIds.map((id) => ({
1478
- id,
1479
- isLocked,
1480
- })),
1481
- { source },
1482
- );
1483
-
1484
- if (isLocked) {
1485
- this.removeShapeIdsFromSelection(
1486
- this.getShapeIdsIncludingDescendants(nextIds),
1487
- source,
1488
- );
1489
- this.removeShapeIdsFromEditingSession(
1490
- this.getShapeIdsIncludingDescendants(nextIds),
1491
- source,
1492
- );
1493
- }
1494
-
1495
- return nextIds;
1496
- }
1497
-
1498
- createClipboardPayloadFromSelection(): EditorClipboardPayload | null {
1499
- return this.clipboard.createPayloadFromSelection();
1500
- }
1501
-
1502
- pasteClipboardPayload(input: PasteClipboardPayloadInput): ShapeId[] {
1503
- return this.clipboard.pastePayload(input);
1504
- }
1505
-
1506
- duplicateSelection(input: DuplicateSelectionInput = {}): ShapeId[] {
1507
- return this.clipboard.duplicateSelection(input);
1508
- }
1509
-
1510
- selectAllCurrentPage(source: ChangeSource = "user"): void {
1511
- this.cancelInteractionForCommand();
1512
- this.selection.selectAllCurrentPage(source);
1513
- }
1514
-
1515
- resetSelectionRotation(source: ChangeSource = "user"): void {
1516
- resetEditorSelectionRotation(this, source);
1517
- }
1518
-
1519
- flipSelection(
1520
- axis: ShapeSelectionFlipAxis,
1521
- source: ChangeSource = "user",
1522
- ): void {
1523
- const updates = getEditorSelectionFlipUpdates(this, axis);
1524
- if (updates.length === 0) {
1525
- return;
1526
- }
1527
-
1528
- this.cancelInteractionForCommand();
1529
- this.commands.updateShapes(updates, { source });
1530
- }
1531
-
1532
- getShape(id: ShapeId): ShapeRecord | undefined {
1533
- const record = this._internalStore.get(id);
1534
- return isShapeRecord(record) ? record : undefined;
1535
- }
1536
-
1537
- getAsset(id: AssetId): AssetRecord | undefined {
1538
- const record = this._internalStore.get(id);
1539
- return isAssetRecord(record) ? record : undefined;
1540
- }
1541
-
1542
- getAssets(): AssetRecord[] {
1543
- return this._internalStore
1544
- .getAll()
1545
- .filter(isAssetRecord)
1546
- .sort((left, right) => left.id.localeCompare(right.id));
1547
- }
1548
-
1549
- resolveAssetUrl(assetId: AssetId): string | null {
1550
- return this.assetUrlResolver(assetId);
1551
- }
1552
-
1553
- getUnreferencedAssetIdsAfterShapeDelete(
1554
- shapeIds: readonly ShapeId[],
1555
- ): AssetId[] {
1556
- if (shapeIds.length === 0) {
1557
- return [];
1558
- }
1559
-
1560
- const deletedShapeIds = new Set(shapeIds);
1561
- const deletedAssetIds = new Set<AssetId>();
1562
- const retainedAssetIds = new Set<AssetId>();
1563
-
1564
- for (const shape of this._internalStore.getAll().filter(isShapeRecord)) {
1565
- const assetId = getShapeAssetId(shape);
1566
- if (!assetId) {
1567
- continue;
1568
- }
1569
- if (deletedShapeIds.has(shape.id)) {
1570
- deletedAssetIds.add(assetId);
1571
- } else {
1572
- retainedAssetIds.add(assetId);
1573
- }
1574
- }
1575
-
1576
- return this.getAssets()
1577
- .map((asset) => asset.id)
1578
- .filter(
1579
- (assetId) =>
1580
- deletedAssetIds.has(assetId) && !retainedAssetIds.has(assetId),
1581
- );
1582
- }
1583
-
1584
- getShapeSignal(id: ShapeId): Signal<ShapeRecord | undefined> {
1585
- let signal = this.shapeSignals.get(id);
1586
- if (!signal) {
1587
- signal = computed<ShapeRecord | undefined>(`editor.shape.${id}`, () =>
1588
- this.getShape(id),
1589
- );
1590
- this.shapeSignals.set(id, signal);
1591
- }
1592
- return signal;
1593
- }
1594
-
1595
- getShapeSelectedSignal(id: ShapeId): Signal<boolean> {
1596
- let signal = this.shapeSelectedSignals.get(id);
1597
- if (!signal) {
1598
- signal = computed<boolean>(`editor.shapeSelected.${id}`, () =>
1599
- this.selectedShapeIdSetSignal.get().has(id),
1600
- );
1601
- this.shapeSelectedSignals.set(id, signal);
1602
- }
1603
- return signal;
1604
- }
1605
-
1606
- getShapeRenderOrderSignal(id: ShapeId): Signal<number> {
1607
- let signal = this.shapeRenderOrderSignals.get(id);
1608
- if (!signal) {
1609
- signal = computed<number>(`editor.shapeRenderOrder.${id}`, () => {
1610
- return this.shapeRenderOrderByIdSignal.get().get(id) ?? -1;
1611
- });
1612
- this.shapeRenderOrderSignals.set(id, signal);
1613
- }
1614
- return signal;
1615
- }
1616
-
1617
- getShapeRenderVisibleSignal(id: ShapeId): Signal<boolean> {
1618
- let signal = this.shapeRenderVisibleSignals.get(id);
1619
- if (!signal) {
1620
- signal = computed<boolean>(`editor.shapeRenderVisible.${id}`, () => {
1621
- return (
1622
- this.renderVisibleShapeIdSetSignal.get().has(id) &&
1623
- !this.isShapeHidden(id)
1624
- );
1625
- });
1626
- this.shapeRenderVisibleSignals.set(id, signal);
1627
- }
1628
- return signal;
1629
- }
1630
-
1631
- getShapeDocumentVisibleSignal(id: ShapeId): Signal<boolean> {
1632
- let signal = this.shapeDocumentVisibleSignals.get(id);
1633
- if (!signal) {
1634
- signal = computed<boolean>(`editor.shapeDocumentVisible.${id}`, () => {
1635
- const shape = this.getShapeSignal(id).get();
1636
- return !!shape && !this.isShapeHidden(shape.id);
1637
- });
1638
- this.shapeDocumentVisibleSignals.set(id, signal);
1639
- }
1640
- return signal;
1641
- }
1642
-
1643
- getShapeEditingSessionForShapeSignal(
1644
- id: ShapeId,
1645
- ): Signal<ShapeEditingSession | null> {
1646
- let signal = this.shapeEditingSessionSignals.get(id);
1647
- if (!signal) {
1648
- signal = computed<ShapeEditingSession | null>(
1649
- `editor.shapeEditingSessionForShape.${id}`,
1650
- () => {
1651
- const session = this.shapeEditingSessionSignal.get();
1652
- return session?.shapeId === id ? session : null;
1653
- },
1654
- );
1655
- this.shapeEditingSessionSignals.set(id, signal);
1656
- }
1657
- return signal;
1658
- }
1659
-
1660
- getShapeDropTargetSignal(id: ShapeId): Signal<boolean> {
1661
- let signal = this.shapeDropTargetSignals.get(id);
1662
- if (!signal) {
1663
- signal = computed<boolean>(`editor.shapeDropTarget.${id}`, () => {
1664
- return this.dropTargetShapeIdSignal.get() === id;
1665
- });
1666
- this.shapeDropTargetSignals.set(id, signal);
1667
- }
1668
- return signal;
1669
- }
1670
-
1671
- getShapeErasingSignal(id: ShapeId): Signal<boolean> {
1672
- let signal = this.shapeErasingSignals.get(id);
1673
- if (!signal) {
1674
- signal = computed<boolean>(`editor.shapeErasing.${id}`, () => {
1675
- const erasingShapeIds = new Set(this.erasingShapeIdsSignal.get());
1676
- return this.hierarchy.isShapeOrAncestorInSet(id, erasingShapeIds);
1677
- });
1678
- this.shapeErasingSignals.set(id, signal);
1679
- }
1680
- return signal;
1681
- }
1682
-
1683
- getShapeSelectedDescendantTransformAncestorSignal(
1684
- id: ShapeId,
1685
- ): Signal<boolean> {
1686
- let signal = this.shapeSelectedDescendantTransformAncestorSignals.get(id);
1687
- if (!signal) {
1688
- signal = computed<boolean>(
1689
- `editor.shapeSelectedDescendantTransformAncestor.${id}`,
1690
- () => {
1691
- if (this.getShapeSelectedSignal(id).get()) {
1692
- return false;
1693
- }
1694
- const shape = this.getShapeSignal(id).get();
1695
- if (
1696
- !shape ||
1697
- !this.getShapeUtil(shape).shouldTransformDescendants(shape)
1698
- ) {
1699
- return false;
1700
- }
1701
- return this.selectedShapeIdsSignal
1702
- .get()
1703
- .some((selectedShapeId) =>
1704
- this.hierarchy.isShapeDescendantOf(selectedShapeId, id),
1705
- );
1706
- },
1707
- );
1708
- this.shapeSelectedDescendantTransformAncestorSignals.set(id, signal);
1709
- }
1710
- return signal;
1711
- }
1712
-
1713
- getBinding(id: BindingId): BindingRecord | undefined {
1714
- const record = this._internalStore.get(id);
1715
- return isBindingRecord(record) ? record : undefined;
1716
- }
1717
-
1718
- getShapesForPage(pageId: PageId): ShapeRecord[] {
1719
- return this.queries.getShapesForPage(pageId);
1720
- }
1721
-
1722
- getBindingsFromShape(shapeId: ShapeId): BindingRecord[] {
1723
- return this.queries.getBindingsFromShape(shapeId);
1724
- }
1725
-
1726
- getBindingsToShape(shapeId: ShapeId): BindingRecord[] {
1727
- return this.queries.getBindingsToShape(shapeId);
1728
- }
1729
-
1730
- getBindingsForShape(shapeId: ShapeId): BindingRecord[] {
1731
- return this.queries.getBindingsForShape(shapeId);
1732
- }
1733
-
1734
- getChildShapeIds(parentId: ShapeParentId): ShapeId[] {
1735
- return this.queries.getChildShapeIds(parentId);
1736
- }
1737
-
1738
- getChildShapes(parentId: ShapeParentId): ShapeRecord[] {
1739
- return this.queries.getChildShapes(parentId);
1740
- }
1741
-
1742
- getDescendantShapeIds(parentId: ShapeParentId): ShapeId[] {
1743
- return this.queries.getDescendantShapeIds(parentId);
1744
- }
1745
-
1746
- getDescendantPageBounds(parentId: ShapeParentId): Box | null {
1747
- return this.queries.getDescendantPageBounds(parentId);
1748
- }
1749
-
1750
- getShapeSubtreePageBounds(shapeId: ShapeId): Box | null {
1751
- return this.queries.getShapeSubtreePageBounds(shapeId);
1752
- }
1753
-
1754
- getShapePageId(shapeId: ShapeId): PageId | null {
1755
- return this.queries.getPageIdForShape(shapeId);
1756
- }
1757
-
1758
- isShapeOrAncestorLocked(shapeId: ShapeId): boolean {
1759
- return this.hierarchy.isShapeOrAncestorLocked(shapeId);
1760
- }
1761
-
1762
- hasLockedDescendant(shapeId: ShapeId): boolean {
1763
- return this.hierarchy.hasLockedDescendant(shapeId);
1764
- }
1765
-
1766
- getOutermostSelectableShapeId(shapeId: ShapeId): ShapeId {
1767
- return this.hierarchy.getOutermostSelectableShapeId(shapeId);
1768
- }
1769
-
1770
- getShapeIdsIncludingDescendants(shapeIds: Iterable<ShapeId>): ShapeId[] {
1771
- return this.hierarchy.getShapeIdsIncludingDescendants(shapeIds);
1772
- }
1773
-
1774
- getShapeIdsForSelectionTransform(shapeIds: Iterable<ShapeId>): ShapeId[] {
1775
- return this.hierarchy.getShapeIdsForSelectionTransform(shapeIds);
1776
- }
1777
-
1778
- getShapeIdsForSelectionRotation(shapeIds: Iterable<ShapeId>): ShapeId[] {
1779
- return this.hierarchy.getShapeIdsForSelectionRotation(shapeIds);
1780
- }
1781
-
1782
- getSelectionTransformTargetShapes(): ShapeRecord[] {
1783
- return this.hierarchy.getSelectionTransformTargetShapes();
1784
- }
1785
-
1786
- getSelectionRotationTargetShapes(): ShapeRecord[] {
1787
- return this.hierarchy.getSelectionRotationTargetShapes();
1788
- }
1789
-
1790
- getShapeExportTraversalIds(shapeIds: Iterable<ShapeId>): ShapeId[] {
1791
- return this.hierarchy.getShapeExportTraversalIds(shapeIds);
1792
- }
1793
-
1794
- getShapeContainment(
1795
- containerId: ShapeId,
1796
- shapeId: ShapeId,
1797
- ): ShapeContainment | null {
1798
- return this.queries.getShapeContainment(containerId, shapeId);
1799
- }
1800
-
1801
- getContainingShapeParentId(
1802
- shapeIds: Iterable<ShapeId>,
1803
- ): ShapeParentId | null {
1804
- return this.queries.getContainingShapeParentId(shapeIds);
1805
- }
1806
-
1807
- getContainingParentIdForShapeRecord(shape: ShapeRecord): ShapeParentId | null {
1808
- return this.queries.getContainingParentIdForShapeRecord(shape);
1809
- }
1810
-
1811
- getShapeClipAncestorIds(shapeId: ShapeId): ShapeId[] {
1812
- return this.queries.getShapeClipAncestorIds(shapeId);
1813
- }
1814
-
1815
- getShapeClipAncestorIdsSignal(shapeId: ShapeId): Signal<ShapeId[]> {
1816
- return this.queries.getShapeClipAncestorIdsSignal(shapeId);
1817
- }
1818
-
1819
- isPagePointInShapeClip(shapeId: ShapeId, point: Vec): boolean {
1820
- return this.queries.isPagePointInShapeClip(shapeId, point);
1821
- }
1822
-
1823
- getShapeClippedPageBounds(shapeId: ShapeId): Box | null {
1824
- return this.queries.getShapeClippedPageBounds(shapeId);
1825
- }
1826
-
1827
- getShapeIdsInContainerBounds(
1828
- containerId: ShapeId,
1829
- options: ContainerBoundsQueryOptions = {},
1830
- ): ShapeId[] {
1831
- return this.hierarchy.getShapeIdsInContainerBounds(containerId, options);
1832
- }
1833
-
1834
- canUseShapeParent(parentId: ShapeParentId, childId?: ShapeId): boolean {
1835
- return this.hierarchy.canUseShapeParent(parentId, childId);
1836
- }
1837
-
1838
- getShapeUtil<S extends ShapeRecord>(shape: S): ShapeUtil<S> {
1839
- return this.shapeUtils.get(shape.type);
1840
- }
1841
-
1842
- getBindingUtil<B extends BindingRecord>(binding: B): BindingUtil<B> {
1843
- return this.bindingUtils.get(binding.type);
1844
- }
1845
-
1846
- // Pure geometry helpers operate only on the provided shape snapshot.
1847
- computeShapeBounds(shape: ShapeRecord): Box {
1848
- return this.geometry.computeShapeBounds(shape);
1849
- }
1850
-
1851
- computeShapeLocalBounds(shape: ShapeRecord): Box {
1852
- return this.geometry.computeShapeLocalBounds(shape);
1853
- }
1854
-
1855
- computeShapeRenderBounds(shape: ShapeRecord): Box {
1856
- return this.geometry.computeShapeRenderBounds(shape);
1857
- }
1858
-
1859
- computeShapeExportBounds(shape: ShapeRecord): Box {
1860
- return this.geometry.computeShapeExportBounds(shape);
1861
- }
1862
-
1863
- computeShapeLocalToPageTransform(shape: ShapeRecord): Mat {
1864
- return this.geometry.computeShapeLocalToPageTransform(shape);
1865
- }
1866
-
1867
- computeShapeRenderToPageTransform(shape: ShapeRecord): Mat {
1868
- return this.geometry.computeShapeRenderToPageTransform(shape);
1869
- }
1870
-
1871
- computeShapeExportToPageTransform(shape: ShapeRecord): Mat {
1872
- return this.geometry.computeShapeExportToPageTransform(shape);
1873
- }
1874
-
1875
- computeShapePageBounds(shape: ShapeRecord): Box {
1876
- return this.geometry.computeShapePageBounds(shape);
1877
- }
1878
-
1879
- computeShapeExportPageBounds(shape: ShapeRecord): Box {
1880
- return this.geometry.computeShapeExportPageBounds(shape);
1881
- }
1882
-
1883
- computeShapeGeometry(shape: ShapeRecord): ShapeGeometry {
1884
- return this.geometry.computeShapeGeometry(shape);
1885
- }
1886
-
1887
- computeShapePositionedToPageTransform(shape: ShapeRecord): Mat {
1888
- return this.geometry.computeShapePositionedToPageTransform(shape);
1889
- }
1890
-
1891
- computeShapePageCenter(shape: ShapeRecord): Vec {
1892
- return this.geometry.computeShapePageCenter(shape);
1893
- }
1894
-
1895
- computeShapePageCorners(shape: ShapeRecord): Vec[] {
1896
- return this.geometry.computeShapePageCorners(shape);
1897
- }
1898
-
1899
- computeShapePageOutlineVertices(shape: ShapeRecord): Vec[] {
1900
- return this.geometry.computeShapePageOutlineVertices(shape);
1901
- }
1902
-
1903
- // Query helpers always read the current editor state for a shape id.
1904
- getShapeBounds(shapeId: ShapeId): Box | null {
1905
- return this.geometry.getShapeBounds(shapeId);
1906
- }
1907
-
1908
- getShapePageBounds(shapeId: ShapeId): Box | null {
1909
- return this.geometry.getShapePageBounds(shapeId);
1910
- }
1911
-
1912
- getShapeGeometry(shapeId: ShapeId): ShapeGeometry | null {
1913
- return this.geometry.getShapeGeometry(shapeId);
1914
- }
1915
-
1916
- getShapePositionedToPageTransform(shapeId: ShapeId): Mat | null {
1917
- return this.geometry.getShapePositionedToPageTransform(shapeId);
1918
- }
1919
-
1920
- getShapePageCenter(shapeId: ShapeId): Vec | null {
1921
- return this.geometry.getShapePageCenter(shapeId);
1922
- }
1923
-
1924
- getShapePageCorners(shapeId: ShapeId): Vec[] | null {
1925
- return this.geometry.getShapePageCorners(shapeId);
1926
- }
1927
-
1928
- getShapePageOutlineVertices(shapeId: ShapeId): Vec[] {
1929
- return this.geometry.getShapePageOutlineVertices(shapeId);
1930
- }
1931
-
1932
- getSelectionPageBounds(): Box | null {
1933
- return this.geometry.getSelectionPageBounds();
1934
- }
1935
-
1936
- getSelectionFrame():
1937
- | SelectionFrame
1938
- | null {
1939
- return this.geometry.getSelectionFrame();
1940
- }
1941
-
1942
- isPointInSelectionBounds(point: Vec): boolean {
1943
- return this.geometry.isPointInSelectionBounds(point);
1944
- }
1945
-
1946
- getSelectionFrameLocalBoundsPoint(point: Vec): Vec | null {
1947
- return this.geometry.getSelectionFrameLocalBoundsPoint(point);
1948
- }
1949
-
1950
- getSelectionPageOutlineVertices(): Vec[] {
1951
- return this.geometry.getSelectionPageOutlineVertices();
1952
- }
1953
-
1954
- getSelectionToolbarAnchorPagePoint(): Vec | null {
1955
- return this.geometry.getSelectionToolbarAnchorPagePoint();
1956
- }
1957
-
1958
- hitTestSelectionHandle(point: Vec): SelectionHandle | null {
1959
- const selectedShapes = this.selectedShapesSignal.get();
1960
- const selectionFrame = this.getSelectionFrame();
1961
- if (selectedShapes.length === 0) {
1962
- return null;
1963
- }
1964
- const isOnlySelected = selectedShapes.length === 1;
1965
- const {
1966
- terminalHandles,
1967
- middleHandles,
1968
- customHandles,
1969
- rotateHandles,
1970
- resizeHandles,
1971
- } =
1972
- getSelectionHandleState(
1973
- selectedShapes,
1974
- selectionFrame,
1975
- this.getCurrentCamera().z,
1976
- (shape) =>
1977
- this.getShapeUtil(shape).getSelectionHandleAnchors(shape, {
1978
- isOnlySelected,
1979
- editor: this,
1980
- }),
1981
- (shape) =>
1982
- this.getShapeUtil(shape).canUseSelectionFrameHandles(shape, {
1983
- editor: this,
1984
- }),
1985
- );
1986
-
1987
- for (const handle of middleHandles) {
1988
- if (
1989
- handle.bounds
1990
- .expand(
1991
- SELECTION_HANDLE_HIT_PADDING_SCREEN / this.getCurrentCamera().z,
1992
- )
1993
- .containsPoint(point)
1994
- ) {
1995
- return handle;
1996
- }
1997
- }
1998
-
1999
- for (const handle of terminalHandles) {
2000
- if (
2001
- handle.bounds
2002
- .expand(
2003
- SELECTION_HANDLE_HIT_PADDING_SCREEN / this.getCurrentCamera().z,
2004
- )
2005
- .containsPoint(point)
2006
- ) {
2007
- return handle;
2008
- }
2009
- }
2010
-
2011
- for (const handle of customHandles) {
2012
- if (
2013
- handle.bounds
2014
- .expand(SELECTION_HANDLE_HIT_PADDING_SCREEN / this.getCurrentCamera().z)
2015
- .containsPoint(point)
2016
- ) {
2017
- return handle;
2018
- }
2019
- }
2020
-
2021
- for (const handle of resizeHandles) {
2022
- if (handle.bounds.containsPoint(point)) {
2023
- return handle;
2024
- }
2025
- }
2026
-
2027
- for (const handle of rotateHandles) {
2028
- if (
2029
- handle.bounds
2030
- .expand(SELECTION_HANDLE_HIT_PADDING_SCREEN / this.getCurrentCamera().z)
2031
- .containsPoint(point)
2032
- ) {
2033
- return handle;
2034
- }
2035
- }
2036
-
2037
- return null;
2038
- }
2039
-
2040
- setBrushBox(brushBox: Box | null): void {
2041
- this.transients.setBrushBox(brushBox);
2042
- }
2043
-
2044
- getErasingShapeIds(): ShapeId[] {
2045
- return this.transients.getErasingShapeIds();
2046
- }
2047
-
2048
- setErasingShapeIds(shapeIds: readonly ShapeId[]): void {
2049
- this.transients.setErasingShapeIds(shapeIds);
2050
- }
2051
-
2052
- clearErasingShapeIds(): void {
2053
- this.transients.clearErasingShapeIds();
2054
- }
2055
-
2056
- getEraserTrail(): Vec[] {
2057
- return this.transients.getEraserTrail();
2058
- }
2059
-
2060
- setEraserTrail(points: readonly Vec[]): void {
2061
- this.transients.setEraserTrail(points);
2062
- }
2063
-
2064
- clearEraserTrail(): void {
2065
- this.transients.clearEraserTrail();
2066
- }
2067
-
2068
- startLaserTrail(): number {
2069
- return this.transients.startLaserTrail();
2070
- }
2071
-
2072
- setLaserTrail(sessionId: number, points: readonly Vec[]): void {
2073
- this.transients.setLaserTrail(sessionId, points);
2074
- }
2075
-
2076
- finishLaserTrail(sessionId: number): void {
2077
- this.transients.finishLaserTrail(sessionId);
2078
- }
2079
-
2080
- clearLaserTrail(sessionId: number): void {
2081
- this.transients.clearLaserTrail(sessionId);
2082
- }
2083
-
2084
- setBindingPreview(preview: ArrowBindingPreviewState | null): void {
2085
- this.transients.setBindingPreview(preview);
2086
- }
2087
-
2088
- setDropTargetShapeId(shapeId: ShapeId | null): void {
2089
- this.transients.setDropTargetShapeId(shapeId);
2090
- }
2091
-
2092
- setSnapIndicators(indicators: SnapIndicatorState[] | null): void {
2093
- this.transients.setSnapIndicators(indicators);
2094
- }
2095
-
2096
- setArrowTerminalBindingResolver(
2097
- resolver: ArrowTerminalBindingResolver,
2098
- ): void {
2099
- this.transients.setArrowTerminalBindingResolver(resolver);
2100
- }
2101
-
2102
- resolveArrowTerminalBinding(
2103
- input: ArrowTerminalBindingResolverInput,
2104
- ): ResolvedArrowTerminalBinding {
2105
- return this.transients.resolveArrowTerminalBinding(input);
2106
- }
2107
-
2108
- clearSelectionTransients(): void {
2109
- this.transients.clearSelectionTransients();
2110
- }
2111
-
2112
- hitTestShape(point: Vec): ShapeRecord | null {
2113
- return this.hitTestShapesAtPoint(point)[0] ?? null;
2114
- }
2115
-
2116
- hitTestShapesAtPoint(
2117
- point: Vec,
2118
- options?: ShapeAtPointOptions,
2119
- ): ShapeRecord[] {
2120
- return this.spatialIndex.getShapesAtPoint(point, {
2121
- ...options,
2122
- filter: (shape) =>
2123
- !this.isShapeHidden(shape.id) &&
2124
- this.isPagePointInShapeClip(shape.id, point) &&
2125
- (options?.filter?.(shape) ?? true),
2126
- });
2127
- }
2128
-
2129
- hitTestShapesByLineSegment(
2130
- start: Vec,
2131
- end: Vec,
2132
- options?: ShapeLineSegmentHitTestOptions,
2133
- ): ShapeRecord[] {
2134
- return this.spatialIndex.getShapesHitByLineSegment(start, end, {
2135
- ...options,
2136
- filter: (shape) =>
2137
- !this.isShapeHidden(shape.id) && (options?.filter?.(shape) ?? true),
2138
- });
2139
- }
2140
-
2141
- getShapeIdsInBounds(bounds: Box, options?: SpatialQueryOptions): ShapeId[] {
2142
- return this.spatialIndex
2143
- .getShapeIdsInBounds(bounds, options)
2144
- .filter((shapeId) => !this.isShapeHidden(shapeId));
2145
- }
2146
-
2147
- getShapesInBounds(bounds: Box, options?: SpatialQueryOptions): ShapeRecord[] {
2148
- return this.spatialIndex
2149
- .getShapesInBounds(bounds, options)
2150
- .filter((shape) => !this.isShapeHidden(shape.id));
2151
- }
2152
-
2153
- getShapesInViewport(
2154
- bounds: Box,
2155
- options?: SpatialQueryOptions,
2156
- ): ShapeRecord[] {
2157
- return this.spatialIndex
2158
- .getShapesInViewport(bounds, options)
2159
- .filter((shape) => !this.isShapeHidden(shape.id));
2160
- }
2161
-
2162
- getDocumentSnapshot(): DocumentSnapshot {
2163
- return this.snapshots.getDocumentSnapshot();
2164
- }
2165
-
2166
- getSessionSnapshot(): SessionSnapshot {
2167
- return this.snapshots.getSessionSnapshot();
2168
- }
2169
-
2170
- getSvgString(
2171
- shapeIds: Iterable<ShapeId> = this.getSelectedShapeIds(),
2172
- options?: SvgExportOptions,
2173
- ): SvgExportResult | null {
2174
- return exportShapesToSvgString(
2175
- this,
2176
- shapeIds,
2177
- this.shapeSvgExporters,
2178
- options,
2179
- );
2180
- }
2181
-
2182
- getExportIntegrityReport(
2183
- shapeIds: Iterable<ShapeId> = this.getSelectedShapeIds(),
2184
- ): ExportIntegrityReport {
2185
- return getExportIntegrityReport({
2186
- editor: this,
2187
- exporters: this.shapeSvgExporters,
2188
- shapeIds,
2189
- });
2190
- }
2191
-
2192
- repairExportIntegrity(
2193
- shapeIds: Iterable<ShapeId> = this.getSelectedShapeIds(),
2194
- ): ExportIntegrityRepairResult {
2195
- return repairExportIntegrity({
2196
- editor: this,
2197
- exporters: this.shapeSvgExporters,
2198
- shapeIds,
2199
- });
2200
- }
2201
-
2202
- getShapeCapabilityManifest(): ShapeCapabilityManifest {
2203
- return getShapeCapabilityManifest({
2204
- definitions: this.shapeCapabilityDefinitions,
2205
- exporters: this.shapeSvgExporters,
2206
- shapeUtils: this.shapeUtils,
2207
- });
2208
- }
2209
-
2210
- createPageRecord(input?: {
2211
- name?: string;
2212
- index?: string;
2213
- meta?: Record<string, unknown>;
2214
- }): PageRecord {
2215
- const pageNumber = this.nextPageNumber;
2216
- return {
2217
- id: this.createPageId(pageNumber),
2218
- typeName: "page",
2219
- scope: "document",
2220
- name: input?.name ?? `Page ${pageNumber}`,
2221
- index: input?.index ?? this.createPageIndex(pageNumber),
2222
- meta: input?.meta ?? {},
2223
- };
2224
- }
2225
-
2226
- loadDocumentSnapshot(
2227
- snapshot: unknown,
2228
- options?: { source?: ChangeSource },
2229
- ): void {
2230
- this.snapshots.loadDocumentSnapshot(snapshot, options);
2231
- }
2232
-
2233
- loadSessionSnapshot(
2234
- snapshot: unknown,
2235
- options?: { source?: ChangeSource },
2236
- ): void {
2237
- this.snapshots.loadSessionSnapshot(snapshot, options);
2238
- }
2239
-
2240
- syncAfterDocumentRestore(): void {
2241
- this.snapshots.syncAfterDocumentRestore();
2242
- }
2243
-
2244
- cancelInteractionForCommand(): void {
2245
- this.cancelInteractionAndClearTransients("command");
2246
- }
2247
-
2248
- cancelInteractionAndClearTransients(
2249
- reason: CancelEditorEvent["reason"],
2250
- ): void {
2251
- this.tools.cancel(reason);
2252
- this.inputs.resetPointer();
2253
- this.clearSelectionTransients();
2254
- }
2255
-
2256
- syncToolStateFromSession(source: ChangeSource): void {
2257
- const { activeToolId, isToolLocked } = this.sessionSignal.get();
2258
-
2259
- if (this.tools.hasTool(activeToolId)) {
2260
- this.tools.setActiveTool(activeToolId, "restore");
2261
- } else {
2262
- this.tools.setActiveTool("select", "restore");
2263
- this.updateSession({ activeToolId: "select" }, source);
2264
- }
2265
-
2266
- this.tools.setToolLocked(isToolLocked);
2267
- }
2268
-
2269
- createShapeRecord(input: CreateShapeInput): ShapeRecord {
2270
- const parentId = input.parentId ?? this.sessionSignal.get().currentPageId;
2271
- if (!this.canUseShapeParent(parentId)) {
2272
- throw new Error(`Invalid parent id for shape`);
2273
- }
2274
- const shapeNumber = this.nextShapeNumber;
2275
- const id = this.createShapeId(shapeNumber);
2276
- const util = this.shapeUtils.get(input.type);
2277
- const props = util.validateProps({
2278
- ...this.getDefaultShapeProps(input.type),
2279
- ...input.props,
2280
- });
2281
-
2282
- return {
2283
- id,
2284
- typeName: "shape" as const,
2285
- scope: "document" as const,
2286
- type: input.type,
2287
- parentId,
2288
- index: input.index ?? this.createShapeIndex(shapeNumber),
2289
- x: input.x,
2290
- y: input.y,
2291
- rotation: input.rotation ?? 0,
2292
- scaleX: input.scaleX ?? 1,
2293
- scaleY: input.scaleY ?? 1,
2294
- opacity: input.opacity ?? 1,
2295
- isHidden: input.isHidden ?? false,
2296
- isLocked: input.isLocked ?? false,
2297
- props,
2298
- meta: input.meta ?? {},
2299
- } as ShapeRecord;
2300
- }
2301
-
2302
- createBindingRecord(input: CreateBindingInput): BindingRecord {
2303
- const bindingNumber = this.nextBindingNumber;
2304
- const id = input.id ?? this.createBindingId(bindingNumber);
2305
- const util = this.bindingUtils.get(input.type);
2306
- const props = util.validateProps({
2307
- ...util.getDefaultProps(),
2308
- ...input.props,
2309
- });
2310
-
2311
- return {
2312
- id,
2313
- typeName: "binding",
2314
- scope: "document",
2315
- type: input.type,
2316
- fromId: input.fromId,
2317
- toId: input.toId,
2318
- props,
2319
- meta: input.meta ?? {},
2320
- } as BindingRecord;
2321
- }
2322
-
2323
- createAssetRecord(input: CreateAssetInput): AssetRecord {
2324
- const assetNumber = this.nextAssetNumber;
2325
- const id = input.id ?? this.createAssetId(assetNumber);
2326
-
2327
- return {
2328
- id,
2329
- typeName: "asset",
2330
- scope: "document",
2331
- type: input.type,
2332
- props: input.props ?? {},
2333
- meta: input.meta ?? {},
2334
- } as AssetRecord;
2335
- }
2336
-
2337
- updateSession(
2338
- partial: Partial<SessionRecord>,
2339
- source: ChangeSource = "system",
2340
- ): void {
2341
- const current = this.sessionSignal.get();
2342
- this._internalStore.put(
2343
- [
2344
- {
2345
- ...current,
2346
- ...partial,
2347
- },
2348
- ],
2349
- source,
2350
- );
2351
- }
2352
-
2353
- setCurrentPage(pageId: PageId, source: ChangeSource = "system"): void {
2354
- if (!this.getPage(pageId)) {
2355
- return;
2356
- }
2357
-
2358
- if (pageId !== this.getCurrentPageId()) {
2359
- this.cancelInteractionAndClearTransients("page_switch");
2360
- this.completeEditing(source);
2361
- }
2362
-
2363
- const session = this.sessionSignal.get();
2364
- this.updateSession(
2365
- {
2366
- currentPageId: pageId,
2367
- pageCameraById: {
2368
- ...session.pageCameraById,
2369
- [pageId]: session.pageCameraById[pageId] ?? { ...DEFAULT_CAMERA },
2370
- },
2371
- pageSelectedShapeIdsById: {
2372
- ...session.pageSelectedShapeIdsById,
2373
- [pageId]: session.pageSelectedShapeIdsById[pageId] ?? [],
2374
- },
2375
- },
2376
- source,
2377
- );
2378
- }
2379
-
2380
- setSelectedShapeIds(
2381
- ids: ShapeId[],
2382
- options?: { pageId?: PageId; source?: ChangeSource },
2383
- ): void {
2384
- this.selection.setSelectedShapeIds(ids, options);
2385
- }
2386
-
2387
- removeShapeIdsFromSelection(
2388
- ids: ShapeId[],
2389
- source: ChangeSource = "system",
2390
- ): void {
2391
- this.selection.removeShapeIdsFromSelection(ids, source);
2392
- }
2393
-
2394
- removeShapeIdsFromEditingSession(
2395
- ids: ShapeId[],
2396
- source: ChangeSource = "system",
2397
- ): void {
2398
- this.editing.removeShapeIds(ids, source);
2399
- }
2400
-
2401
- ensurePageSessionState(
2402
- pageId: PageId,
2403
- source: ChangeSource = "system",
2404
- ): void {
2405
- const session = this.sessionSignal.get();
2406
- const nextCamera = session.pageCameraById[pageId] ?? { ...DEFAULT_CAMERA };
2407
- const nextSelection = session.pageSelectedShapeIdsById[pageId] ?? [];
2408
-
2409
- this.updateSession(
2410
- {
2411
- pageCameraById: {
2412
- ...session.pageCameraById,
2413
- [pageId]: nextCamera,
2414
- },
2415
- pageSelectedShapeIdsById: {
2416
- ...session.pageSelectedShapeIdsById,
2417
- [pageId]: nextSelection,
2418
- },
2419
- },
2420
- source,
2421
- );
2422
- }
2423
-
2424
- removePageSessionState(
2425
- pageId: PageId,
2426
- nextCurrentPageId: PageId,
2427
- source: ChangeSource = "system",
2428
- ): void {
2429
- const session = this.sessionSignal.get();
2430
- const nextCameraById = { ...session.pageCameraById };
2431
- const nextSelectionById = { ...session.pageSelectedShapeIdsById };
2432
- delete nextCameraById[pageId];
2433
- delete nextSelectionById[pageId];
2434
-
2435
- this.updateSession(
2436
- {
2437
- currentPageId: nextCurrentPageId,
2438
- pageCameraById: nextCameraById,
2439
- pageSelectedShapeIdsById: nextSelectionById,
2440
- },
2441
- source,
2442
- );
2443
- }
2444
-
2445
- setCamera(
2446
- partial: Partial<Camera>,
2447
- options?: { pageId?: PageId; source?: ChangeSource },
2448
- ): void {
2449
- this.camera.setCamera(partial, options);
2450
- }
2451
-
2452
- panCamera(delta: Vec, source: ChangeSource = "system"): void {
2453
- this.camera.panCamera(delta, source);
2454
- }
2455
-
2456
- zoomCameraAtScreenPoint(
2457
- screenPoint: Vec,
2458
- deltaY: number,
2459
- source: ChangeSource = "system",
2460
- ): void {
2461
- this.camera.zoomCameraAtScreenPoint(screenPoint, deltaY, source);
2462
- }
2463
-
2464
- zoomCameraToScreenPoint(
2465
- screenPoint: Vec,
2466
- zoom: number,
2467
- source: ChangeSource = "system",
2468
- ): void {
2469
- this.camera.zoomCameraToScreenPoint(screenPoint, zoom, source);
2470
- }
2471
-
2472
- zoomAtViewportCenter(deltaY: number, source: ChangeSource = "system"): void {
2473
- this.camera.zoomAtViewportCenter(deltaY, source);
2474
- }
2475
-
2476
- resetZoom(source: ChangeSource = "user"): void {
2477
- this.camera.resetZoom(source);
2478
- }
2479
-
2480
- setViewportScreenSize(size: { w: number; h: number }): void {
2481
- this.camera.setViewportScreenSize(size);
2482
- }
2483
-
2484
- /** Combined page bounds of every shape on a page, or null when empty. */
2485
- getCurrentPageBounds(pageId: PageId = this.getCurrentPageId()): Box | null {
2486
- return this.selectionLayout.getCurrentPageBounds(pageId);
2487
- }
2488
-
2489
- /**
2490
- * Move and zoom the camera so `bounds` fits inside the viewport with optional
2491
- * padding (screen px). Returns false when the viewport or bounds are empty.
2492
- */
2493
- zoomToBounds(
2494
- bounds: Box,
2495
- options?: { padding?: number; maxZoom?: number; source?: ChangeSource },
2496
- ): boolean {
2497
- return this.selectionLayout.zoomToBounds(bounds, options);
2498
- }
2499
-
2500
- /** Fit all shapes on the current page into the viewport. */
2501
- zoomToFit(options?: { padding?: number; source?: ChangeSource }): boolean {
2502
- return this.selectionLayout.zoomToFit(options);
2503
- }
2504
-
2505
- /** Fit the current selection into the viewport. */
2506
- zoomToSelection(options?: {
2507
- padding?: number;
2508
- source?: ChangeSource;
2509
- }): boolean {
2510
- return this.selectionLayout.zoomToSelection(options);
2511
- }
2512
-
2513
- private createShapeId(shapeNumber: number): ShapeId {
2514
- const id = `shape:${shapeNumber}` as ShapeId;
2515
- this.nextShapeNumber += 1;
2516
- return id;
2517
- }
2518
-
2519
- createShapeIndex(shapeNumber: number): string {
2520
- return String(shapeNumber).padStart(6, "0");
2521
- }
2522
-
2523
- private createBindingId(bindingNumber: number): BindingId {
2524
- const id = `binding:${bindingNumber}` as BindingId;
2525
- this.nextBindingNumber += 1;
2526
- return id;
2527
- }
2528
-
2529
- private createAssetId(assetNumber: number): AssetId {
2530
- const id = `asset:${assetNumber}` as AssetId;
2531
- this.nextAssetNumber += 1;
2532
- return id;
2533
- }
2534
-
2535
- syncShapeCounter(): void {
2536
- let maxShapeNumber = 0;
2537
- for (const record of this._internalStore.getAll()) {
2538
- if (!isShapeRecord(record)) continue;
2539
- const value = Number(record.id.split(":")[1] ?? 0);
2540
- if (Number.isFinite(value)) {
2541
- maxShapeNumber = Math.max(maxShapeNumber, value);
2542
- }
2543
- }
2544
- this.nextShapeNumber = maxShapeNumber + 1;
2545
- }
2546
-
2547
- syncPageCounter(): void {
2548
- let maxPageNumber = 0;
2549
- for (const record of this._internalStore.getAll()) {
2550
- if (!isPageRecord(record)) continue;
2551
- const suffix = record.id.split(":")[1] ?? "";
2552
- const value = Number(suffix === "default" ? 1 : suffix);
2553
- if (Number.isFinite(value)) {
2554
- maxPageNumber = Math.max(maxPageNumber, value);
2555
- }
2556
- }
2557
- this.nextPageNumber = maxPageNumber + 1;
2558
- }
2559
-
2560
- syncBindingCounter(): void {
2561
- let maxBindingNumber = 0;
2562
- for (const record of this._internalStore.getAll()) {
2563
- if (!isBindingRecord(record)) continue;
2564
- const value = Number(record.id.split(":")[1] ?? 0);
2565
- if (Number.isFinite(value)) {
2566
- maxBindingNumber = Math.max(maxBindingNumber, value);
2567
- }
2568
- }
2569
- this.nextBindingNumber = maxBindingNumber + 1;
2570
- }
2571
-
2572
- syncAssetCounter(): void {
2573
- let maxAssetNumber = 0;
2574
- for (const record of this._internalStore.getAll()) {
2575
- if (!isAssetRecord(record)) continue;
2576
- const value = Number(record.id.split(":")[1] ?? 0);
2577
- if (Number.isFinite(value)) {
2578
- maxAssetNumber = Math.max(maxAssetNumber, value);
2579
- }
2580
- }
2581
- this.nextAssetNumber = maxAssetNumber + 1;
2582
- }
2583
-
2584
- private createPageId(pageNumber: number): PageId {
2585
- const id = `page:${pageNumber}` as PageId;
2586
- this.nextPageNumber += 1;
2587
- return id;
2588
- }
2589
-
2590
- private createPageIndex(pageNumber: number): string {
2591
- return String(pageNumber).padStart(4, "0");
2592
- }
2593
-
2594
- private handleWheelEvent(
2595
- event: Extract<EditorEvent, { type: "wheel" }>,
2596
- ): void {
2597
- if (event.ctrlKey) {
2598
- const current = this.getCurrentCamera();
2599
- const deltaY = event.delta.y;
2600
- const zoomDelta =
2601
- (Math.abs(deltaY) > CAMERA_WHEEL_MAX_ZOOM_STEP
2602
- ? CAMERA_WHEEL_MAX_ZOOM_STEP * Math.sign(deltaY)
2603
- : deltaY) / 100;
2604
- this.zoomCameraToScreenPoint(
2605
- event.screenPoint,
2606
- current.z - zoomDelta * CAMERA_WHEEL_ZOOM_SPEED * current.z,
2607
- );
2608
- return;
2609
- }
2610
-
2611
- this.panCamera(event.delta);
2612
- }
2613
-
2614
- }