@yuzhouu/canvas-kit 0.1.2 → 0.1.4

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 (563) hide show
  1. package/README.md +80 -78
  2. package/_vendor/canvas-core/bindings/bindingUtil.d.ts +45 -0
  3. package/_vendor/canvas-core/bindings/bindingUtilRegistry.d.ts +8 -0
  4. package/_vendor/canvas-core/bindings/terminalBinding.d.ts +28 -0
  5. package/_vendor/canvas-core/editor/camera.d.ts +3 -0
  6. package/_vendor/canvas-core/editor/clipboard.d.ts +43 -0
  7. package/_vendor/canvas-core/editor/commands.d.ts +131 -0
  8. package/_vendor/canvas-core/editor/createEditorWithPlugins.d.ts +6 -0
  9. package/_vendor/canvas-core/editor/edgeScroll.d.ts +5 -0
  10. package/_vendor/canvas-core/editor/editor.d.ts +559 -0
  11. package/_vendor/canvas-core/editor/editorComputedHelpers.d.ts +21 -0
  12. package/_vendor/canvas-core/editor/editorSelectionTransforms.d.ts +6 -0
  13. package/_vendor/canvas-core/editor/events.d.ts +71 -0
  14. package/_vendor/canvas-core/editor/historyManager.d.ts +18 -0
  15. package/_vendor/canvas-core/editor/index.d.ts +11 -0
  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 +55 -0
  24. package/_vendor/canvas-core/editor/managers/queryManager.d.ts +77 -0
  25. package/_vendor/canvas-core/editor/managers/queryState.d.ts +18 -0
  26. package/_vendor/canvas-core/editor/managers/renderWindowManager.d.ts +25 -0
  27. package/_vendor/canvas-core/editor/managers/selectionGeometry.d.ts +28 -0
  28. package/_vendor/canvas-core/editor/managers/selectionLayoutManager.d.ts +29 -0
  29. package/_vendor/canvas-core/editor/managers/selectionManager.d.ts +21 -0
  30. package/_vendor/canvas-core/editor/managers/selectionOverlayManager.d.ts +24 -0
  31. package/_vendor/canvas-core/editor/managers/shapeEditingManager.d.ts +29 -0
  32. package/_vendor/canvas-core/editor/managers/shapeGeometryManager.d.ts +42 -0
  33. package/_vendor/canvas-core/editor/managers/shapeHierarchyManager.d.ts +55 -0
  34. package/_vendor/canvas-core/editor/managers/shapeOrder.d.ts +14 -0
  35. package/_vendor/canvas-core/editor/managers/shapeReparenting.d.ts +6 -0
  36. package/_vendor/canvas-core/editor/managers/shortcutManager.d.ts +56 -0
  37. package/_vendor/canvas-core/editor/managers/sideEffectManager.d.ts +23 -0
  38. package/_vendor/canvas-core/editor/managers/snapCalculations.d.ts +40 -0
  39. package/_vendor/canvas-core/editor/managers/snapGeometry.d.ts +26 -0
  40. package/_vendor/canvas-core/editor/managers/snapIndicators.d.ts +22 -0
  41. package/_vendor/canvas-core/editor/managers/snapManager.d.ts +29 -0
  42. package/_vendor/canvas-core/editor/managers/snapSnapshotBuilder.d.ts +22 -0
  43. package/_vendor/canvas-core/editor/managers/snapTypes.d.ts +98 -0
  44. package/_vendor/canvas-core/editor/managers/spatialIndexManager.d.ts +30 -0
  45. package/_vendor/canvas-core/editor/managers/toolManager.d.ts +24 -0
  46. package/_vendor/canvas-core/editor/queries/shapeTransforms.d.ts +27 -0
  47. package/_vendor/canvas-core/editor/renderWindow.d.ts +30 -0
  48. package/_vendor/canvas-core/editor/resizeGeometry.d.ts +97 -0
  49. package/_vendor/canvas-core/editor/selection.d.ts +231 -0
  50. package/_vendor/canvas-core/editor/selectionHandleInteractions.d.ts +11 -0
  51. package/_vendor/canvas-core/editor/selectionOverlay.d.ts +33 -0
  52. package/_vendor/canvas-core/editor/stateNode.d.ts +31 -0
  53. package/_vendor/canvas-core/exports/integrity.d.ts +32 -0
  54. package/_vendor/canvas-core/exports/svg.d.ts +52 -0
  55. package/_vendor/canvas-core/geometry/box.d.ts +19 -0
  56. package/_vendor/canvas-core/geometry/ellipse2d.d.ts +16 -0
  57. package/_vendor/canvas-core/geometry/geometry2d.d.ts +15 -0
  58. package/_vendor/canvas-core/geometry/index.d.ts +8 -0
  59. package/_vendor/canvas-core/geometry/mat.d.ts +28 -0
  60. package/_vendor/canvas-core/geometry/polyline2d.d.ts +14 -0
  61. package/_vendor/canvas-core/geometry/rectangle2d.d.ts +16 -0
  62. package/_vendor/canvas-core/geometry/segments.d.ts +5 -0
  63. package/_vendor/canvas-core/geometry/vec.d.ts +37 -0
  64. package/_vendor/canvas-core/index.d.ts +59 -0
  65. package/_vendor/canvas-core/plugins/editorPlugin.d.ts +28 -0
  66. package/_vendor/canvas-core/plugins/index.d.ts +1 -0
  67. package/_vendor/canvas-core/reactivity.d.ts +4 -0
  68. package/_vendor/canvas-core/schema/records.d.ts +112 -0
  69. package/_vendor/canvas-core/schema/snapshotSupport.d.ts +43 -0
  70. package/_vendor/canvas-core/schema/snapshots.d.ts +31 -0
  71. package/_vendor/canvas-core/shapes/capabilities.d.ts +25 -0
  72. package/_vendor/canvas-core/shapes/colors.d.ts +26 -0
  73. package/_vendor/canvas-core/shapes/shapeUtil.d.ts +146 -0
  74. package/_vendor/canvas-core/shapes/shapeUtilRegistry.d.ts +9 -0
  75. package/_vendor/canvas-core/shapes/types.d.ts +2 -0
  76. package/_vendor/canvas-core/surfaces/actions.d.ts +35 -0
  77. package/_vendor/canvas-core/surfaces/contextMenu.d.ts +64 -0
  78. package/_vendor/canvas-core/surfaces/toolbar.d.ts +96 -0
  79. package/_vendor/canvas-core/tools/hand/handTool.d.ts +5 -0
  80. package/_vendor/canvas-core/tools/index.d.ts +2 -0
  81. package/_vendor/canvas-core/tools/select/selectContainment.d.ts +12 -0
  82. package/_vendor/canvas-core/tools/select/selectTool.d.ts +5 -0
  83. package/_vendor/canvas-core/tools/select/selectToolHelpers.d.ts +161 -0
  84. package/_vendor/canvas-core/tools/select/states/brushingState.d.ts +19 -0
  85. package/_vendor/canvas-core/tools/select/states/draggingSelectionHandleInteractionState.d.ts +15 -0
  86. package/_vendor/canvas-core/tools/select/states/idleState.d.ts +8 -0
  87. package/_vendor/canvas-core/tools/select/states/index.d.ts +11 -0
  88. package/_vendor/canvas-core/tools/select/states/pointingCanvasState.d.ts +11 -0
  89. package/_vendor/canvas-core/tools/select/states/pointingResizeHandleState.d.ts +10 -0
  90. package/_vendor/canvas-core/tools/select/states/pointingRotateHandleState.d.ts +10 -0
  91. package/_vendor/canvas-core/tools/select/states/pointingSelectionHandleInteractionState.d.ts +10 -0
  92. package/_vendor/canvas-core/tools/select/states/pointingShapeState.d.ts +12 -0
  93. package/_vendor/canvas-core/tools/select/states/resizingState.d.ts +16 -0
  94. package/_vendor/canvas-core/tools/select/states/rotatingState.d.ts +14 -0
  95. package/_vendor/canvas-core/tools/select/states/selectStateNode.d.ts +60 -0
  96. package/_vendor/canvas-core/tools/select/states/translatingState.d.ts +17 -0
  97. package/_vendor/canvas-react/components/CanvasView.d.ts +14 -0
  98. package/_vendor/canvas-react/components/OverlayLayer.d.ts +1 -0
  99. package/_vendor/canvas-react/components/PageSpace.d.ts +6 -0
  100. package/_vendor/canvas-react/components/ShapeLayer.d.ts +4 -0
  101. package/_vendor/canvas-react/components/index.d.ts +2 -0
  102. package/_vendor/canvas-react/components/overlays/BindingGuide.d.ts +24 -0
  103. package/_vendor/canvas-react/components/overlays/BindingPreviewOverlay.d.ts +1 -0
  104. package/_vendor/canvas-react/components/overlays/BrushBoxOverlay.d.ts +1 -0
  105. package/_vendor/canvas-react/components/overlays/OverlaySvgRoot.d.ts +1 -0
  106. package/_vendor/canvas-react/components/overlays/SelectionFrameOverlay.d.ts +1 -0
  107. package/_vendor/canvas-react/components/overlays/SelectionHandlesOverlay.d.ts +1 -0
  108. package/_vendor/canvas-react/components/overlays/SelectionOverlaySvg.d.ts +1 -0
  109. package/_vendor/canvas-react/components/overlays/SelectionPathOverlay.d.ts +1 -0
  110. package/_vendor/canvas-react/components/overlays/ShapeOutlineOverlay.d.ts +8 -0
  111. package/_vendor/canvas-react/components/overlays/SnapIndicatorsOverlay.d.ts +1 -0
  112. package/_vendor/canvas-react/components/useCanvasDomEvents.d.ts +21 -0
  113. package/_vendor/canvas-react/dom.d.ts +10 -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/canvasOverlayRegistryContext.d.ts +3 -0
  117. package/_vendor/canvas-react/host/canvasPlugin.d.ts +73 -0
  118. package/_vendor/canvas-react/host/canvasRendererRegistryContext.d.ts +3 -0
  119. package/_vendor/canvas-react/host/contextMenuRegistry.d.ts +12 -0
  120. package/_vendor/canvas-react/host/domEventGuards.d.ts +11 -0
  121. package/_vendor/canvas-react/host/extension.d.ts +37 -0
  122. package/_vendor/canvas-react/host/index.d.ts +13 -0
  123. package/_vendor/canvas-react/host/overlayRegistry.d.ts +18 -0
  124. package/_vendor/canvas-react/host/pluginHost.d.ts +2 -0
  125. package/_vendor/canvas-react/host/pluginHostManifest.d.ts +2 -0
  126. package/_vendor/canvas-react/host/pluginHostRuntime.d.ts +3 -0
  127. package/_vendor/canvas-react/host/pluginHostTypes.d.ts +102 -0
  128. package/_vendor/canvas-react/host/pluginHostValidation.d.ts +11 -0
  129. package/_vendor/canvas-react/host/rendererRegistry.d.ts +12 -0
  130. package/_vendor/canvas-react/host/toolbarRegistry.d.ts +24 -0
  131. package/_vendor/canvas-react/index.d.ts +4 -0
  132. package/_vendor/plugin-arrow/arrowBindingAnchors.d.ts +5 -0
  133. package/_vendor/plugin-arrow/arrowBindingGeometry.d.ts +28 -0
  134. package/_vendor/plugin-arrow/arrowBindingUtil.d.ts +27 -0
  135. package/_vendor/plugin-arrow/arrowGeometry.d.ts +74 -0
  136. package/_vendor/plugin-arrow/arrowShapeUtil.d.ts +21 -0
  137. package/_vendor/plugin-arrow/arrowTerminalBindingResolver.d.ts +20 -0
  138. package/_vendor/plugin-arrow/arrowTerminalCommands.d.ts +12 -0
  139. package/_vendor/plugin-arrow/arrowTool.d.ts +4 -0
  140. package/_vendor/plugin-arrow/canvas.d.ts +2 -0
  141. package/_vendor/plugin-arrow/editor.d.ts +7 -0
  142. package/_vendor/plugin-arrow/feature.d.ts +3 -0
  143. package/_vendor/plugin-arrow/index.d.ts +12 -0
  144. package/_vendor/plugin-arrow/selectionHandleInteractions.d.ts +3 -0
  145. package/_vendor/plugin-arrow/types.d.ts +31 -0
  146. package/_vendor/plugin-draw/DrawShapeRenderer.d.ts +10 -0
  147. package/_vendor/plugin-draw/canvas.d.ts +2 -0
  148. package/_vendor/plugin-draw/drawGeometry.d.ts +45 -0
  149. package/_vendor/plugin-draw/drawHitTest.d.ts +11 -0
  150. package/_vendor/plugin-draw/drawInterpolation.d.ts +5 -0
  151. package/_vendor/plugin-draw/drawPath.d.ts +37 -0
  152. package/_vendor/plugin-draw/drawSegments.d.ts +11 -0
  153. package/_vendor/plugin-draw/drawSelectionTransform.d.ts +18 -0
  154. package/_vendor/plugin-draw/drawShapeGeometry.d.ts +33 -0
  155. package/_vendor/plugin-draw/drawShapeUtil.d.ts +21 -0
  156. package/_vendor/plugin-draw/drawStrokeGeometry.d.ts +17 -0
  157. package/_vendor/plugin-draw/drawTool.d.ts +6 -0
  158. package/_vendor/plugin-draw/editor.d.ts +7 -0
  159. package/_vendor/plugin-draw/feature.d.ts +3 -0
  160. package/_vendor/plugin-draw/index.d.ts +13 -0
  161. package/_vendor/plugin-draw/types.d.ts +23 -0
  162. package/_vendor/plugin-eraser/canvas.d.ts +2 -0
  163. package/_vendor/plugin-eraser/editor.d.ts +2 -0
  164. package/_vendor/plugin-eraser/eraserTool.d.ts +5 -0
  165. package/_vendor/plugin-eraser/feature.d.ts +3 -0
  166. package/_vendor/plugin-eraser/{index.ts → index.d.ts} +2 -2
  167. package/_vendor/plugin-frame/canvas.d.ts +9 -0
  168. package/_vendor/plugin-frame/editor.d.ts +7 -0
  169. package/_vendor/plugin-frame/feature.d.ts +3 -0
  170. package/_vendor/plugin-frame/frameShapeUtil.d.ts +23 -0
  171. package/_vendor/plugin-frame/frameTool.d.ts +6 -0
  172. package/_vendor/plugin-frame/index.d.ts +6 -0
  173. package/_vendor/plugin-geo/canvas.d.ts +13 -0
  174. package/_vendor/plugin-geo/editor.d.ts +7 -0
  175. package/_vendor/plugin-geo/feature.d.ts +3 -0
  176. package/_vendor/plugin-geo/geoGeometry.d.ts +8 -0
  177. package/_vendor/plugin-geo/geoShapeUtil.d.ts +13 -0
  178. package/_vendor/plugin-geo/geoTools.d.ts +26 -0
  179. package/_vendor/plugin-geo/index.d.ts +7 -0
  180. package/_vendor/plugin-geo/types.d.ts +17 -0
  181. package/_vendor/plugin-group/canvas.d.ts +10 -0
  182. package/_vendor/plugin-group/editor.d.ts +7 -0
  183. package/_vendor/plugin-group/feature.d.ts +3 -0
  184. package/_vendor/plugin-group/groupShapeUtil.d.ts +15 -0
  185. package/_vendor/plugin-group/index.d.ts +5 -0
  186. package/_vendor/plugin-image/canvas.d.ts +2 -0
  187. package/_vendor/plugin-image/crop.d.ts +112 -0
  188. package/_vendor/plugin-image/cropInteractions.d.ts +3 -0
  189. package/_vendor/plugin-image/cropSession.d.ts +4 -0
  190. package/_vendor/plugin-image/editor.d.ts +16 -0
  191. package/_vendor/plugin-image/feature.d.ts +3 -0
  192. package/_vendor/plugin-image/imageShapeUtil.d.ts +11 -0
  193. package/_vendor/plugin-image/index.d.ts +8 -0
  194. package/_vendor/plugin-image/types.d.ts +37 -0
  195. package/_vendor/plugin-laser/canvas.d.ts +2 -0
  196. package/_vendor/plugin-laser/editor.d.ts +2 -0
  197. package/_vendor/plugin-laser/feature.d.ts +3 -0
  198. package/_vendor/plugin-laser/{index.ts → index.d.ts} +2 -2
  199. package/_vendor/plugin-laser/laserTool.d.ts +4 -0
  200. package/_vendor/plugin-text/arrowLabelBindingUtil.d.ts +42 -0
  201. package/_vendor/plugin-text/canvas.d.ts +2 -0
  202. package/_vendor/plugin-text/editor.d.ts +2 -0
  203. package/_vendor/plugin-text/feature.d.ts +3 -0
  204. package/_vendor/plugin-text/geoLabelBindingUtil.d.ts +45 -0
  205. package/_vendor/plugin-text/host/RichTextEditingBox.d.ts +5 -0
  206. package/_vendor/plugin-text/host/RichTextToolbar.d.ts +8 -0
  207. package/_vendor/plugin-text/host/TiptapTextEditor.d.ts +24 -0
  208. package/_vendor/plugin-text/host/richTextBubbleMenuPositionSync.d.ts +7 -0
  209. package/_vendor/plugin-text/host/richTextRendering.d.ts +3 -0
  210. package/_vendor/plugin-text/host/textDomSelection.d.ts +7 -0
  211. package/_vendor/plugin-text/host/textEditingBoxStyle.d.ts +3 -0
  212. package/_vendor/plugin-text/host/textEntryFocus.d.ts +22 -0
  213. package/_vendor/plugin-text/host/textFontLoader.d.ts +2 -0
  214. package/_vendor/plugin-text/host/textMeasurement.d.ts +12 -0
  215. package/_vendor/plugin-text/host/textMeasurementSync.d.ts +10 -0
  216. package/_vendor/plugin-text/host/textRangeSelection.d.ts +14 -0
  217. package/_vendor/plugin-text/host/textShapeRendererRuntime.d.ts +8 -0
  218. package/_vendor/plugin-text/host/textShapeSync.d.ts +17 -0
  219. package/_vendor/plugin-text/host/tiptapTextEditorController.d.ts +33 -0
  220. package/_vendor/plugin-text/index.d.ts +4 -0
  221. package/_vendor/plugin-text/richTextUtils.d.ts +18 -0
  222. package/_vendor/plugin-text/textInteractions.d.ts +2 -0
  223. package/_vendor/plugin-text/textLabelHelpers.d.ts +44 -0
  224. package/_vendor/plugin-text/textShapeHelpers.d.ts +21 -0
  225. package/_vendor/plugin-text/textShapeSvgExporter.d.ts +6 -0
  226. package/_vendor/plugin-text/textShapeUtil.d.ts +19 -0
  227. package/_vendor/plugin-text/textStyle.d.ts +9 -0
  228. package/_vendor/plugin-text/textTool.d.ts +4 -0
  229. package/_vendor/plugin-text/textTypes.d.ts +28 -0
  230. package/_vendor/signals/atom.d.ts +9 -0
  231. package/_vendor/signals/computed.d.ts +11 -0
  232. package/_vendor/signals/core.d.ts +17 -0
  233. package/_vendor/signals/effect.d.ts +29 -0
  234. package/_vendor/signals/types.d.ts +15 -0
  235. package/_vendor/store/diff.d.ts +9 -0
  236. package/_vendor/store/history.d.ts +37 -0
  237. package/_vendor/store/index.d.ts +5 -0
  238. package/_vendor/store/store.d.ts +32 -0
  239. package/_vendor/store/types.d.ts +27 -0
  240. package/browser/localSnapshotRestore.d.ts +13 -0
  241. package/browser/persistence.d.ts +46 -0
  242. package/builtins/controller/createBuiltInCanvasController.d.ts +16 -0
  243. package/builtins/controller/layerController.d.ts +9 -0
  244. package/builtins/controller/shapeCreationController.d.ts +74 -0
  245. package/builtins/extensions.d.ts +15 -0
  246. package/builtins/index.d.ts +5 -0
  247. package/chrome/CanvasKitFloatingToolbarLayer.d.ts +6 -0
  248. package/chrome/FloatingSelectionToolbarPageSpace.d.ts +9 -0
  249. package/chrome/bindings/useCanvasKitChromeControls.d.ts +27 -0
  250. package/chrome/bindings/useContextMenuSurface.d.ts +12 -0
  251. package/chrome/bindings/useSvgExport.d.ts +15 -0
  252. package/chrome/bindings/useToolbarSurfaces.d.ts +26 -0
  253. package/chrome/types.d.ts +66 -0
  254. package/chrome/useCanvasKitChromeContext.d.ts +19 -0
  255. package/controller/canvasKitController.d.ts +36 -0
  256. package/core/controller/canvasProductController.d.ts +114 -0
  257. package/core/controller/featureControllerRegistry.d.ts +12 -0
  258. package/core/controller/index.d.ts +4 -0
  259. package/core/controller/productLayerTree.d.ts +10 -0
  260. package/core/features/actions/canvasActionContext.d.ts +15 -0
  261. package/core/features/actions/canvasActions.d.ts +26 -0
  262. package/core/features/clipboard/clipboardContextMenuContributions.d.ts +2 -0
  263. package/core/features/clipboard/clipboardContribution.d.ts +19 -0
  264. package/core/features/clipboard/clipboardService.d.ts +10 -0
  265. package/core/features/context-menu/contextMenuActions.d.ts +12 -0
  266. package/core/features/context-menu/contextMenuContext.d.ts +6 -0
  267. package/core/features/context-menu/contextMenuContribution.d.ts +4 -0
  268. package/core/features/context-menu/viewContextMenuContributions.d.ts +2 -0
  269. package/core/features/export/svgExport.d.ts +33 -0
  270. package/core/features/hostActionIds.d.ts +1 -0
  271. package/core/features/toolbar/selectionContextMenuContributions.d.ts +2 -0
  272. package/core/features/toolbar/toolContextMenuContributions.d.ts +2 -0
  273. package/core/features/toolbar/toolbarContribution.d.ts +4 -0
  274. package/core/features/toolbar/toolbarLabels.d.ts +8 -0
  275. package/core/index.d.ts +23 -0
  276. package/core/runtime/productAssets.d.ts +18 -0
  277. package/core/runtime/productContributions.d.ts +9 -0
  278. package/core/runtime/productDefinition.d.ts +32 -0
  279. package/core/runtime/productEditor.d.ts +3 -0
  280. package/core/runtime/productHost.d.ts +17 -0
  281. package/core/runtime/productServices.d.ts +30 -0
  282. package/features/image/ImageImportController.d.ts +9 -0
  283. package/features/image/imageAssetService.d.ts +7 -0
  284. package/features/image/imageBlobStore.d.ts +25 -0
  285. package/features/image/imageFileHelpers.d.ts +35 -0
  286. package/features/image/imageHostActions.d.ts +36 -0
  287. package/features/image/imageHostExtension.d.ts +5 -0
  288. package/features/image/imageProductController.d.ts +22 -0
  289. package/features/image/imageProductToolbarActions.d.ts +2 -0
  290. package/features/image/imageToolbarHostBridge.d.ts +14 -0
  291. package/features/image/index.d.ts +15 -0
  292. package/features/image/svgImageAssetInliner.d.ts +3 -0
  293. package/features/image/useImageImport.d.ts +17 -0
  294. package/index.css +1 -2
  295. package/index.d.ts +12 -15
  296. package/index.mjs +66 -1
  297. package/package.json +1 -11
  298. package/product/canvasKitProduct.d.ts +59 -0
  299. package/react/CanvasKitPersistenceNotice.d.ts +4 -0
  300. package/react/CanvasKitRoot.d.ts +5 -0
  301. package/react/useCanvasKitController.d.ts +5 -0
  302. package/react/useCanvasKitKeyboardShortcuts.d.ts +6 -0
  303. package/react/useCanvasKitRuntime.d.ts +4 -0
  304. package/react/useCanvasKitStartup.d.ts +9 -0
  305. package/runtime/canvasKitHostExtensions.d.ts +19 -0
  306. package/runtime/canvasKitRuntime.d.ts +19 -0
  307. package/runtime/canvasKitRuntimeInitializer.d.ts +11 -0
  308. package/_vendor/canvas-core/bindings/BindingUtil.ts +0 -92
  309. package/_vendor/canvas-core/bindings/BindingUtilRegistry.ts +0 -22
  310. package/_vendor/canvas-core/bindings/arrow/arrowBindingHelpers.ts +0 -52
  311. package/_vendor/canvas-core/contextMenu.ts +0 -85
  312. package/_vendor/canvas-core/editor/Editor.ts +0 -2614
  313. package/_vendor/canvas-core/editor/HistoryManager.ts +0 -83
  314. package/_vendor/canvas-core/editor/StateNode.ts +0 -162
  315. package/_vendor/canvas-core/editor/camera.ts +0 -6
  316. package/_vendor/canvas-core/editor/clipboard.ts +0 -478
  317. package/_vendor/canvas-core/editor/commands.ts +0 -833
  318. package/_vendor/canvas-core/editor/edgeScroll.ts +0 -37
  319. package/_vendor/canvas-core/editor/editorComputedHelpers.ts +0 -257
  320. package/_vendor/canvas-core/editor/editorSelectionTransforms.ts +0 -116
  321. package/_vendor/canvas-core/editor/events.ts +0 -93
  322. package/_vendor/canvas-core/editor/index.ts +0 -12
  323. package/_vendor/canvas-core/editor/interactions.ts +0 -101
  324. package/_vendor/canvas-core/editor/internal.ts +0 -22
  325. package/_vendor/canvas-core/editor/managers/BindingManager.ts +0 -262
  326. package/_vendor/canvas-core/editor/managers/CameraManager.ts +0 -147
  327. package/_vendor/canvas-core/editor/managers/ClipboardManager.ts +0 -32
  328. package/_vendor/canvas-core/editor/managers/DocumentSnapshotManager.ts +0 -256
  329. package/_vendor/canvas-core/editor/managers/InputsManager.ts +0 -319
  330. package/_vendor/canvas-core/editor/managers/InteractionTransientManager.ts +0 -218
  331. package/_vendor/canvas-core/editor/managers/QueryManager.ts +0 -837
  332. package/_vendor/canvas-core/editor/managers/RenderWindowManager.ts +0 -347
  333. package/_vendor/canvas-core/editor/managers/SelectionLayoutManager.ts +0 -196
  334. package/_vendor/canvas-core/editor/managers/SelectionManager.ts +0 -98
  335. package/_vendor/canvas-core/editor/managers/SelectionOverlayManager.ts +0 -308
  336. package/_vendor/canvas-core/editor/managers/ShapeEditingManager.ts +0 -226
  337. package/_vendor/canvas-core/editor/managers/ShapeGeometryManager.ts +0 -162
  338. package/_vendor/canvas-core/editor/managers/ShapeHierarchyManager.ts +0 -797
  339. package/_vendor/canvas-core/editor/managers/SideEffectManager.ts +0 -83
  340. package/_vendor/canvas-core/editor/managers/SnapManager.ts +0 -433
  341. package/_vendor/canvas-core/editor/managers/SnapSnapshotBuilder.ts +0 -430
  342. package/_vendor/canvas-core/editor/managers/SpatialIndexManager.ts +0 -354
  343. package/_vendor/canvas-core/editor/managers/ToolManager.ts +0 -81
  344. package/_vendor/canvas-core/editor/managers/queryState.ts +0 -583
  345. package/_vendor/canvas-core/editor/managers/selectionGeometry.ts +0 -287
  346. package/_vendor/canvas-core/editor/managers/shapeOrder.ts +0 -350
  347. package/_vendor/canvas-core/editor/managers/shapeReparenting.ts +0 -160
  348. package/_vendor/canvas-core/editor/managers/snapCalculations.ts +0 -412
  349. package/_vendor/canvas-core/editor/managers/snapGeometry.ts +0 -202
  350. package/_vendor/canvas-core/editor/managers/snapIndicators.ts +0 -403
  351. package/_vendor/canvas-core/editor/managers/snapTypes.ts +0 -122
  352. package/_vendor/canvas-core/editor/queries/shapeTransforms.ts +0 -171
  353. package/_vendor/canvas-core/editor/renderWindow.ts +0 -439
  354. package/_vendor/canvas-core/editor/resizeGeometry.ts +0 -654
  355. package/_vendor/canvas-core/editor/selection.ts +0 -489
  356. package/_vendor/canvas-core/editor/selectionHandleInteractions.ts +0 -43
  357. package/_vendor/canvas-core/editor/selectionOverlay.ts +0 -567
  358. package/_vendor/canvas-core/exports/integrity.ts +0 -174
  359. package/_vendor/canvas-core/exports/svg.ts +0 -494
  360. package/_vendor/canvas-core/geometry/Box.ts +0 -80
  361. package/_vendor/canvas-core/geometry/Ellipse2d.ts +0 -67
  362. package/_vendor/canvas-core/geometry/Geometry2d.ts +0 -52
  363. package/_vendor/canvas-core/geometry/Mat.ts +0 -92
  364. package/_vendor/canvas-core/geometry/Polyline2d.ts +0 -63
  365. package/_vendor/canvas-core/geometry/Rectangle2d.ts +0 -64
  366. package/_vendor/canvas-core/geometry/Vec.ts +0 -123
  367. package/_vendor/canvas-core/geometry/index.ts +0 -13
  368. package/_vendor/canvas-core/geometry/segments.ts +0 -65
  369. package/_vendor/canvas-core/index.ts +0 -391
  370. package/_vendor/canvas-core/plugins/index.ts +0 -5
  371. package/_vendor/canvas-core/plugins/types.ts +0 -53
  372. package/_vendor/canvas-core/reactivity.ts +0 -16
  373. package/_vendor/canvas-core/schema/records.ts +0 -221
  374. package/_vendor/canvas-core/schema/snapshots.ts +0 -527
  375. package/_vendor/canvas-core/shapes/ShapeUtil.ts +0 -516
  376. package/_vendor/canvas-core/shapes/ShapeUtilRegistry.ts +0 -26
  377. package/_vendor/canvas-core/shapes/capabilities.ts +0 -67
  378. package/_vendor/canvas-core/shapes/types.ts +0 -20
  379. package/_vendor/canvas-core/toolbar.ts +0 -148
  380. package/_vendor/canvas-core/tools/hand/HandTool.ts +0 -75
  381. package/_vendor/canvas-core/tools/index.ts +0 -2
  382. package/_vendor/canvas-core/tools/select/SelectTool.ts +0 -33
  383. package/_vendor/canvas-core/tools/select/selectContainment.ts +0 -104
  384. package/_vendor/canvas-core/tools/select/selectToolHelpers.ts +0 -801
  385. package/_vendor/canvas-core/tools/select/states/BrushingState.ts +0 -145
  386. package/_vendor/canvas-core/tools/select/states/DraggingSelectionHandleInteractionState.ts +0 -116
  387. package/_vendor/canvas-core/tools/select/states/IdleState.ts +0 -159
  388. package/_vendor/canvas-core/tools/select/states/PointingCanvasState.ts +0 -41
  389. package/_vendor/canvas-core/tools/select/states/PointingResizeHandleState.ts +0 -78
  390. package/_vendor/canvas-core/tools/select/states/PointingRotateHandleState.ts +0 -64
  391. package/_vendor/canvas-core/tools/select/states/PointingSelectionHandleInteractionState.ts +0 -34
  392. package/_vendor/canvas-core/tools/select/states/PointingShapeState.ts +0 -140
  393. package/_vendor/canvas-core/tools/select/states/ResizingState.ts +0 -171
  394. package/_vendor/canvas-core/tools/select/states/RotatingState.ts +0 -124
  395. package/_vendor/canvas-core/tools/select/states/SelectStateNode.ts +0 -128
  396. package/_vendor/canvas-core/tools/select/states/TranslatingState.ts +0 -139
  397. package/_vendor/canvas-core/tools/select/states/index.ts +0 -11
  398. package/_vendor/canvas-plugin-api/feature.ts +0 -204
  399. package/_vendor/canvas-plugin-api/index.ts +0 -142
  400. package/_vendor/canvas-product-react/api/apiRegistry.ts +0 -35
  401. package/_vendor/canvas-product-react/api/canvasProductApi.ts +0 -422
  402. package/_vendor/canvas-product-react/api/index.ts +0 -31
  403. package/_vendor/canvas-product-react/capabilities/clipboard/clipboardService.ts +0 -36
  404. package/_vendor/canvas-product-react/capabilities/clipboard/systemClipboard.ts +0 -245
  405. package/_vendor/canvas-product-react/capabilities/context-menu/systemContextMenu.ts +0 -396
  406. package/_vendor/canvas-product-react/capabilities/context-menu/useContextMenuSurface.ts +0 -59
  407. package/_vendor/canvas-product-react/capabilities/export/useSvgExport.ts +0 -156
  408. package/_vendor/canvas-product-react/capabilities/history/useHistoryControls.ts +0 -23
  409. package/_vendor/canvas-product-react/capabilities/pages/usePageControls.ts +0 -41
  410. package/_vendor/canvas-product-react/capabilities/toolbar/systemToolbar.ts +0 -490
  411. package/_vendor/canvas-product-react/capabilities/toolbar/useToolbarSurfaces.ts +0 -92
  412. package/_vendor/canvas-product-react/capabilities/zoom/useZoomControls.ts +0 -27
  413. package/_vendor/canvas-product-react/index.ts +0 -84
  414. package/_vendor/canvas-product-react/persistence/index.ts +0 -18
  415. package/_vendor/canvas-product-react/persistence/localSnapshotPersistence.ts +0 -294
  416. package/_vendor/canvas-product-react/runtime/CanvasProductRoot.tsx +0 -250
  417. package/_vendor/canvas-product-react/runtime/productDefinition.ts +0 -72
  418. package/_vendor/canvas-product-react/runtime/productServices.ts +0 -96
  419. package/_vendor/canvas-react/components/CanvasView.tsx +0 -796
  420. package/_vendor/canvas-react/components/OverlayLayer.tsx +0 -879
  421. package/_vendor/canvas-react/components/PageSpace.tsx +0 -34
  422. package/_vendor/canvas-react/components/ShapeLayer.tsx +0 -428
  423. package/_vendor/canvas-react/components/index.ts +0 -4
  424. package/_vendor/canvas-react/hooks/useEditor.ts +0 -11
  425. package/_vendor/canvas-react/hooks/useValue.ts +0 -14
  426. package/_vendor/canvas-react/host/CanvasRendererRegistryContext.tsx +0 -14
  427. package/_vendor/canvas-react/host/contextMenuRegistry.ts +0 -61
  428. package/_vendor/canvas-react/host/domEventGuards.ts +0 -61
  429. package/_vendor/canvas-react/host/index.ts +0 -38
  430. package/_vendor/canvas-react/host/pluginHost.ts +0 -635
  431. package/_vendor/canvas-react/host/rendererRegistry.tsx +0 -58
  432. package/_vendor/canvas-react/host/toolbarRegistry.ts +0 -100
  433. package/_vendor/canvas-react/index.ts +0 -3
  434. package/_vendor/plugin-arrow/ArrowBindingUtil.ts +0 -239
  435. package/_vendor/plugin-arrow/ArrowShapeUtil.ts +0 -311
  436. package/_vendor/plugin-arrow/ArrowTool.ts +0 -208
  437. package/_vendor/plugin-arrow/arrowGeometry.ts +0 -441
  438. package/_vendor/plugin-arrow/arrowTerminalBindingResolver.ts +0 -253
  439. package/_vendor/plugin-arrow/arrowTerminalCommands.ts +0 -230
  440. package/_vendor/plugin-arrow/canvas.tsx +0 -92
  441. package/_vendor/plugin-arrow/core.ts +0 -409
  442. package/_vendor/plugin-arrow/feature.ts +0 -20
  443. package/_vendor/plugin-arrow/index.ts +0 -28
  444. package/_vendor/plugin-arrow/selectionHandleInteractions.ts +0 -154
  445. package/_vendor/plugin-arrow/types.ts +0 -63
  446. package/_vendor/plugin-draw/DrawShapeRenderer.tsx +0 -60
  447. package/_vendor/plugin-draw/DrawShapeUtil.ts +0 -372
  448. package/_vendor/plugin-draw/DrawTool.ts +0 -444
  449. package/_vendor/plugin-draw/canvas.tsx +0 -24
  450. package/_vendor/plugin-draw/core.ts +0 -515
  451. package/_vendor/plugin-draw/drawGeometry.ts +0 -491
  452. package/_vendor/plugin-draw/drawHitTest.ts +0 -271
  453. package/_vendor/plugin-draw/drawInterpolation.ts +0 -250
  454. package/_vendor/plugin-draw/drawPath.ts +0 -550
  455. package/_vendor/plugin-draw/drawSegments.ts +0 -106
  456. package/_vendor/plugin-draw/drawSelectionTransform.ts +0 -67
  457. package/_vendor/plugin-draw/drawShapeGeometry.ts +0 -307
  458. package/_vendor/plugin-draw/drawStrokeGeometry.ts +0 -454
  459. package/_vendor/plugin-draw/feature.ts +0 -20
  460. package/_vendor/plugin-draw/index.ts +0 -31
  461. package/_vendor/plugin-draw/types.ts +0 -36
  462. package/_vendor/plugin-eraser/EraserTool.ts +0 -297
  463. package/_vendor/plugin-eraser/canvas.tsx +0 -616
  464. package/_vendor/plugin-eraser/core.ts +0 -49
  465. package/_vendor/plugin-eraser/feature.ts +0 -20
  466. package/_vendor/plugin-frame/FrameShapeUtil.ts +0 -173
  467. package/_vendor/plugin-frame/FrameTool.ts +0 -225
  468. package/_vendor/plugin-frame/canvas.tsx +0 -75
  469. package/_vendor/plugin-frame/core.ts +0 -534
  470. package/_vendor/plugin-frame/feature.ts +0 -20
  471. package/_vendor/plugin-frame/index.ts +0 -6
  472. package/_vendor/plugin-geo/GeoShapeUtil.ts +0 -463
  473. package/_vendor/plugin-geo/GeoTools.ts +0 -247
  474. package/_vendor/plugin-geo/canvas.tsx +0 -90
  475. package/_vendor/plugin-geo/core.ts +0 -495
  476. package/_vendor/plugin-geo/feature.ts +0 -20
  477. package/_vendor/plugin-geo/index.ts +0 -7
  478. package/_vendor/plugin-geo/types.ts +0 -27
  479. package/_vendor/plugin-group/GroupShapeUtil.ts +0 -59
  480. package/_vendor/plugin-group/canvas.tsx +0 -59
  481. package/_vendor/plugin-group/core.ts +0 -40
  482. package/_vendor/plugin-group/feature.ts +0 -20
  483. package/_vendor/plugin-group/index.ts +0 -5
  484. package/_vendor/plugin-image/ImageShapeUtil.ts +0 -95
  485. package/_vendor/plugin-image/canvas.tsx +0 -212
  486. package/_vendor/plugin-image/core.ts +0 -542
  487. package/_vendor/plugin-image/crop.ts +0 -770
  488. package/_vendor/plugin-image/cropInteractions.ts +0 -350
  489. package/_vendor/plugin-image/cropSession.ts +0 -38
  490. package/_vendor/plugin-image/feature.ts +0 -20
  491. package/_vendor/plugin-image/index.ts +0 -29
  492. package/_vendor/plugin-image/types.ts +0 -55
  493. package/_vendor/plugin-image-product-react/ImageImportController.tsx +0 -143
  494. package/_vendor/plugin-image-product-react/imageAssetService.ts +0 -52
  495. package/_vendor/plugin-image-product-react/imageBlobStore.ts +0 -315
  496. package/_vendor/plugin-image-product-react/imageHostActions.ts +0 -438
  497. package/_vendor/plugin-image-product-react/imageProductApi.ts +0 -88
  498. package/_vendor/plugin-image-product-react/imageToolbarHostBridge.ts +0 -48
  499. package/_vendor/plugin-image-product-react/imageToolbarRuntime.ts +0 -21
  500. package/_vendor/plugin-image-product-react/index.ts +0 -60
  501. package/_vendor/plugin-image-product-react/snapshotGuards.ts +0 -33
  502. package/_vendor/plugin-image-product-react/svgImageAssetInliner.ts +0 -54
  503. package/_vendor/plugin-image-product-react/useImageImport.ts +0 -64
  504. package/_vendor/plugin-laser/LaserTool.ts +0 -154
  505. package/_vendor/plugin-laser/canvas.tsx +0 -645
  506. package/_vendor/plugin-laser/core.ts +0 -49
  507. package/_vendor/plugin-laser/feature.ts +0 -20
  508. package/_vendor/plugin-text/ArrowLabelBindingUtil.ts +0 -336
  509. package/_vendor/plugin-text/GeoLabelBindingUtil.ts +0 -391
  510. package/_vendor/plugin-text/TextShapeSvgExporter.ts +0 -101
  511. package/_vendor/plugin-text/TextShapeUtil.ts +0 -284
  512. package/_vendor/plugin-text/TextTool.ts +0 -228
  513. package/_vendor/plugin-text/canvas.tsx +0 -115
  514. package/_vendor/plugin-text/core.ts +0 -422
  515. package/_vendor/plugin-text/feature.ts +0 -20
  516. package/_vendor/plugin-text/host/RichTextEditingBox.tsx +0 -144
  517. package/_vendor/plugin-text/host/RichTextToolbar.tsx +0 -266
  518. package/_vendor/plugin-text/host/TiptapTextEditor.tsx +0 -191
  519. package/_vendor/plugin-text/host/richTextRendering.tsx +0 -49
  520. package/_vendor/plugin-text/host/textDomSelection.ts +0 -93
  521. package/_vendor/plugin-text/host/textEditingBoxStyle.ts +0 -36
  522. package/_vendor/plugin-text/host/textEntryFocus.ts +0 -307
  523. package/_vendor/plugin-text/host/textFontLoader.ts +0 -149
  524. package/_vendor/plugin-text/host/textMeasurement.ts +0 -258
  525. package/_vendor/plugin-text/host/textMeasurementSync.ts +0 -77
  526. package/_vendor/plugin-text/host/textRangeSelection.ts +0 -134
  527. package/_vendor/plugin-text/host/textShapeRendererRuntime.tsx +0 -89
  528. package/_vendor/plugin-text/host/textShapeSync.ts +0 -173
  529. package/_vendor/plugin-text/host/tiptapTextEditorController.ts +0 -148
  530. package/_vendor/plugin-text/index.ts +0 -18
  531. package/_vendor/plugin-text/richTextUtils.ts +0 -259
  532. package/_vendor/plugin-text/textInteractions.ts +0 -366
  533. package/_vendor/plugin-text/textLabelHelpers.ts +0 -235
  534. package/_vendor/plugin-text/textShapeHelpers.ts +0 -123
  535. package/_vendor/plugin-text/textStyle.ts +0 -96
  536. package/_vendor/plugin-text/textTypes.ts +0 -48
  537. package/_vendor/signals/atom.ts +0 -74
  538. package/_vendor/signals/computed.ts +0 -132
  539. package/_vendor/signals/core.ts +0 -130
  540. package/_vendor/signals/effect.ts +0 -117
  541. package/_vendor/signals/types.ts +0 -17
  542. package/_vendor/store/Store.ts +0 -171
  543. package/_vendor/store/diff.ts +0 -229
  544. package/_vendor/store/history.ts +0 -177
  545. package/_vendor/store/index.ts +0 -32
  546. package/_vendor/store/types.ts +0 -37
  547. package/api/canvasKitApi.d.ts +0 -29
  548. package/internal-modules.d.ts +0 -187
  549. package/product/Shell.d.ts +0 -19
  550. package/product/chromeContext.d.ts +0 -70
  551. package/product/createCanvasKitEditor.d.ts +0 -6
  552. package/product/index.d.ts +0 -7
  553. package/product/persistence.d.ts +0 -3
  554. package/product/product.d.ts +0 -22
  555. package/product/useCanvasClipboardShortcuts.d.ts +0 -6
  556. package/product-iyBbEPIs.mjs +0 -4
  557. package/product.mjs +0 -1
  558. package/standard/extensions.d.ts +0 -1
  559. package/standard/index.d.ts +0 -3
  560. package/standard/standardApi.d.ts +0 -91
  561. package/standard-BmrxwqpJ.mjs +0 -44
  562. package/standard.mjs +0 -1
  563. /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
- }