@tldraw/editor 3.16.0-internal.a478398270c6 → 3.16.0-internal.f8b97f0c414f
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.
- package/dist-cjs/index.d.ts +350 -142
- package/dist-cjs/index.js +13 -6
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +10 -8
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/MenuClickCapture.js +0 -5
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/SVGContainer.js +1 -1
- package/dist-cjs/lib/components/SVGContainer.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +11 -36
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultBrush.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +15 -24
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCursor.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultCursor.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultGrid.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultGrid.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultHandles.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultScribble.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +9 -1
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js +53 -0
- package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js.map +7 -0
- package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js +27 -15
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +3 -3
- package/dist-cjs/lib/config/TLUserPreferences.js +15 -3
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +174 -180
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +4 -0
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +14 -4
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/BaseBoxShapeUtil.js.map +1 -1
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +23 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.js.map +2 -2
- package/dist-cjs/lib/editor/tools/StateNode.js +20 -1
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js +35 -16
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +44 -35
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +5 -5
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditor.js +1 -4
- package/dist-cjs/lib/hooks/useEditor.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +2 -0
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js +1 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useGestureEvents.js +1 -1
- package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useHandleEvents.js +3 -3
- package/dist-cjs/lib/hooks/useHandleEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js +4 -1
- package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -1
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useSelectionEvents.js +4 -4
- package/dist-cjs/lib/hooks/useSelectionEvents.js.map +2 -2
- package/dist-cjs/lib/{utils/nearestMultiple.js → hooks/useStateAttribute.js} +15 -14
- package/dist-cjs/lib/hooks/useStateAttribute.js.map +7 -0
- package/dist-cjs/lib/license/LicenseManager.js +140 -53
- package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
- package/dist-cjs/lib/license/LicenseProvider.js +39 -1
- package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
- package/dist-cjs/lib/license/Watermark.js +75 -13
- package/dist-cjs/lib/license/Watermark.js.map +3 -3
- package/dist-cjs/lib/license/useLicenseManagerState.js.map +2 -2
- package/dist-cjs/lib/options.js +7 -0
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +3 -0
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/Vec.js +0 -4
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +3 -1
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +50 -20
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +8 -1
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/geometry-constants.js +2 -2
- package/dist-cjs/lib/primitives/geometry/geometry-constants.js.map +2 -2
- package/dist-cjs/lib/primitives/intersect.js +4 -4
- package/dist-cjs/lib/primitives/intersect.js.map +2 -2
- package/dist-cjs/lib/primitives/utils.js +4 -0
- package/dist-cjs/lib/primitives/utils.js.map +2 -2
- package/dist-cjs/lib/utils/EditorAtom.js +45 -0
- package/dist-cjs/lib/utils/EditorAtom.js.map +7 -0
- package/dist-cjs/lib/utils/dom.js +12 -1
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/lib/utils/getPointerInfo.js +2 -2
- package/dist-cjs/lib/utils/getPointerInfo.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js +2 -35
- package/dist-cjs/lib/utils/reparenting.js.map +3 -3
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +0 -1
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +350 -142
- package/dist-esm/index.mjs +24 -8
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +11 -9
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/MenuClickCapture.mjs +0 -5
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/SVGContainer.mjs +1 -1
- package/dist-esm/lib/components/SVGContainer.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +11 -36
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultBrush.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +16 -25
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +2 -2
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCursor.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultCursor.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultGrid.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultGrid.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultHandles.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +9 -1
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs +23 -0
- package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs.map +7 -0
- package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +17 -15
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs +15 -3
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +174 -180
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +4 -0
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +14 -4
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/BaseBoxShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +23 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/StateNode.mjs +20 -1
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +36 -16
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +47 -37
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +11 -6
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditor.mjs +1 -4
- package/dist-esm/lib/hooks/useEditor.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +4 -0
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs +2 -3
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useGestureEvents.mjs +2 -2
- package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useHandleEvents.mjs +9 -4
- package/dist-esm/lib/hooks/useHandleEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs +4 -1
- package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -1
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useSelectionEvents.mjs +6 -5
- package/dist-esm/lib/hooks/useSelectionEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useStateAttribute.mjs +15 -0
- package/dist-esm/lib/hooks/useStateAttribute.mjs.map +7 -0
- package/dist-esm/lib/license/LicenseManager.mjs +141 -54
- package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
- package/dist-esm/lib/license/LicenseProvider.mjs +39 -2
- package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
- package/dist-esm/lib/license/Watermark.mjs +76 -14
- package/dist-esm/lib/license/Watermark.mjs.map +3 -3
- package/dist-esm/lib/license/useLicenseManagerState.mjs.map +2 -2
- package/dist-esm/lib/options.mjs +7 -0
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +4 -1
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +0 -4
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +3 -1
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +53 -21
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +8 -1
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/geometry-constants.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/geometry-constants.mjs.map +2 -2
- package/dist-esm/lib/primitives/intersect.mjs +5 -5
- package/dist-esm/lib/primitives/intersect.mjs.map +2 -2
- package/dist-esm/lib/primitives/utils.mjs +4 -0
- package/dist-esm/lib/primitives/utils.mjs.map +2 -2
- package/dist-esm/lib/utils/EditorAtom.mjs +25 -0
- package/dist-esm/lib/utils/EditorAtom.mjs.map +7 -0
- package/dist-esm/lib/utils/dom.mjs +12 -1
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/lib/utils/getPointerInfo.mjs +2 -2
- package/dist-esm/lib/utils/getPointerInfo.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs +3 -40
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +0 -1
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +327 -315
- package/package.json +16 -38
- package/src/index.ts +19 -10
- package/src/lib/TldrawEditor.tsx +16 -21
- package/src/lib/components/MenuClickCapture.tsx +0 -8
- package/src/lib/components/SVGContainer.tsx +1 -1
- package/src/lib/components/Shape.tsx +12 -33
- package/src/lib/components/default-components/DefaultBrush.tsx +1 -1
- package/src/lib/components/default-components/DefaultCanvas.tsx +13 -24
- package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +2 -2
- package/src/lib/components/default-components/DefaultCursor.tsx +1 -1
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
- package/src/lib/components/default-components/DefaultGrid.tsx +1 -1
- package/src/lib/components/default-components/DefaultHandles.tsx +5 -1
- package/src/lib/components/default-components/DefaultScribble.tsx +1 -1
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +6 -2
- package/src/lib/components/default-components/DefaultShapeWrapper.tsx +35 -0
- package/src/lib/components/default-components/DefaultSnapIndictor.tsx +1 -1
- package/src/lib/components/default-components/DefaultSpinner.tsx +12 -12
- package/src/lib/config/TLUserPreferences.ts +15 -1
- package/src/lib/editor/Editor.test.ts +512 -8
- package/src/lib/editor/Editor.ts +252 -267
- package/src/lib/editor/derivations/notVisibleShapes.ts +6 -0
- package/src/lib/editor/derivations/parentsToChildren.ts +1 -1
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +15 -14
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +16 -15
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +49 -48
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +38 -27
- package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +7 -6
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +12 -11
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +57 -50
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +51 -26
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +14 -13
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +55 -26
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +14 -1
- package/src/lib/editor/shapes/BaseBoxShapeUtil.tsx +2 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +108 -8
- package/src/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.ts +2 -1
- package/src/lib/editor/tools/StateNode.test.ts +285 -0
- package/src/lib/editor/tools/StateNode.ts +27 -1
- package/src/lib/editor/types/misc-types.ts +73 -7
- package/src/lib/exports/getSvgJsx.test.ts +874 -0
- package/src/lib/exports/getSvgJsx.tsx +78 -21
- package/src/lib/hooks/useCanvasEvents.ts +60 -47
- package/src/lib/hooks/useDocumentEvents.ts +11 -6
- package/src/lib/hooks/useEditor.tsx +6 -5
- package/src/lib/hooks/useEditorComponents.tsx +8 -2
- package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +2 -2
- package/src/lib/hooks/useGestureEvents.ts +2 -2
- package/src/lib/hooks/useHandleEvents.ts +9 -4
- package/src/lib/hooks/usePassThroughMouseOverEvents.ts +4 -1
- package/src/lib/hooks/usePassThroughWheelEvents.ts +6 -1
- package/src/lib/hooks/useSelectionEvents.ts +6 -5
- package/src/lib/hooks/useStateAttribute.ts +15 -0
- package/src/lib/license/LicenseManager.test.ts +724 -383
- package/src/lib/license/LicenseManager.ts +201 -58
- package/src/lib/license/LicenseProvider.tsx +74 -2
- package/src/lib/license/Watermark.test.tsx +2 -1
- package/src/lib/license/Watermark.tsx +81 -14
- package/src/lib/license/useLicenseManagerState.ts +2 -2
- package/src/lib/options.ts +8 -0
- package/src/lib/primitives/Box.test.ts +126 -0
- package/src/lib/primitives/Box.ts +10 -1
- package/src/lib/primitives/Vec.ts +0 -5
- package/src/lib/primitives/geometry/Arc2d.ts +2 -2
- package/src/lib/primitives/geometry/Circle2d.ts +2 -2
- package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -1
- package/src/lib/primitives/geometry/Ellipse2d.ts +2 -2
- package/src/lib/primitives/geometry/Geometry2d.test.ts +420 -0
- package/src/lib/primitives/geometry/Geometry2d.ts +78 -21
- package/src/lib/primitives/geometry/Group2d.ts +10 -1
- package/src/lib/primitives/geometry/geometry-constants.ts +2 -1
- package/src/lib/primitives/intersect.test.ts +946 -0
- package/src/lib/primitives/intersect.ts +12 -5
- package/src/lib/primitives/utils.ts +11 -0
- package/src/lib/test/InFrontOfTheCanvas.test.tsx +187 -0
- package/src/lib/utils/EditorAtom.ts +37 -0
- package/src/lib/utils/dom.test.ts +94 -0
- package/src/lib/utils/dom.ts +38 -1
- package/src/lib/utils/getPointerInfo.ts +2 -1
- package/src/lib/utils/reparenting.ts +3 -69
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +2 -1
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +15 -15
- package/src/lib/utils/sync/TLLocalSyncClient.ts +0 -1
- package/src/version.ts +3 -3
- package/dist-cjs/lib/utils/nearestMultiple.js.map +0 -7
- package/dist-esm/lib/utils/nearestMultiple.mjs +0 -14
- package/dist-esm/lib/utils/nearestMultiple.mjs.map +0 -7
- package/src/lib/test/currentToolIdMask.test.ts +0 -49
- package/src/lib/utils/nearestMultiple.ts +0 -13
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -55,7 +55,6 @@ import {
|
|
|
55
55
|
TLStore,
|
|
56
56
|
TLStoreSnapshot,
|
|
57
57
|
TLUnknownBinding,
|
|
58
|
-
TLUnknownShape,
|
|
59
58
|
TLVideoAsset,
|
|
60
59
|
createBindingId,
|
|
61
60
|
createShapeId,
|
|
@@ -116,7 +115,6 @@ import {
|
|
|
116
115
|
} from '../constants'
|
|
117
116
|
import { exportToSvg } from '../exports/exportToSvg'
|
|
118
117
|
import { getSvgAsImage } from '../exports/getSvgAsImage'
|
|
119
|
-
import { tlenv } from '../globals/environment'
|
|
120
118
|
import { tlmenus } from '../globals/menus'
|
|
121
119
|
import { tltime } from '../globals/time'
|
|
122
120
|
import { TldrawOptions, defaultTldrawOptions } from '../options'
|
|
@@ -176,8 +174,10 @@ import {
|
|
|
176
174
|
RequiredKeys,
|
|
177
175
|
TLCameraMoveOptions,
|
|
178
176
|
TLCameraOptions,
|
|
177
|
+
TLGetShapeAtPointOptions,
|
|
179
178
|
TLImageExportOptions,
|
|
180
179
|
TLSvgExportOptions,
|
|
180
|
+
TLUpdatePointerOptions,
|
|
181
181
|
} from './types/misc-types'
|
|
182
182
|
import { TLAdjacentDirection, TLResizeHandle } from './types/selection-types'
|
|
183
183
|
|
|
@@ -242,16 +242,6 @@ export interface TLEditorOptions {
|
|
|
242
242
|
options?: Partial<TldrawOptions>
|
|
243
243
|
licenseKey?: string
|
|
244
244
|
fontAssetUrls?: { [key: string]: string | undefined }
|
|
245
|
-
/**
|
|
246
|
-
* A predicate that should return true if the given shape should be hidden.
|
|
247
|
-
*
|
|
248
|
-
* @deprecated Use {@link Editor#getShapeVisibility} instead.
|
|
249
|
-
*
|
|
250
|
-
* @param shape - The shape to check.
|
|
251
|
-
* @param editor - The editor instance.
|
|
252
|
-
*/
|
|
253
|
-
isShapeHidden?(shape: TLShape, editor: Editor): boolean
|
|
254
|
-
|
|
255
245
|
/**
|
|
256
246
|
* Provides a way to hide shapes.
|
|
257
247
|
*
|
|
@@ -307,21 +297,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
307
297
|
autoFocus,
|
|
308
298
|
inferDarkMode,
|
|
309
299
|
options,
|
|
310
|
-
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
311
|
-
isShapeHidden,
|
|
312
300
|
getShapeVisibility,
|
|
313
301
|
fontAssetUrls,
|
|
314
302
|
}: TLEditorOptions) {
|
|
315
303
|
super()
|
|
316
|
-
assert(
|
|
317
|
-
!(isShapeHidden && getShapeVisibility),
|
|
318
|
-
'Cannot use both isShapeHidden and getShapeVisibility'
|
|
319
|
-
)
|
|
320
304
|
|
|
321
|
-
this._getShapeVisibility =
|
|
322
|
-
? // eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
323
|
-
(shape: TLShape, editor: Editor) => (isShapeHidden(shape, editor) ? 'hidden' : 'inherit')
|
|
324
|
-
: getShapeVisibility
|
|
305
|
+
this._getShapeVisibility = getShapeVisibility
|
|
325
306
|
|
|
326
307
|
this.options = { ...defaultTldrawOptions, ...options }
|
|
327
308
|
|
|
@@ -905,14 +886,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
905
886
|
*/
|
|
906
887
|
readonly fonts: FontManager
|
|
907
888
|
|
|
908
|
-
/**
|
|
909
|
-
* A manager for the editor's environment.
|
|
910
|
-
*
|
|
911
|
-
* @deprecated This is deprecated and will be removed in a future version. Use the `tlenv` global export instead.
|
|
912
|
-
* @public
|
|
913
|
-
*/
|
|
914
|
-
readonly environment = tlenv
|
|
915
|
-
|
|
916
889
|
/**
|
|
917
890
|
* A manager for the editor's scribbles.
|
|
918
891
|
*
|
|
@@ -972,7 +945,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
972
945
|
*
|
|
973
946
|
* @public
|
|
974
947
|
*/
|
|
975
|
-
shapeUtils: { readonly [K in string]?: ShapeUtil<
|
|
948
|
+
shapeUtils: { readonly [K in string]?: ShapeUtil<TLShape> }
|
|
976
949
|
|
|
977
950
|
styleProps: { [key: string]: Map<StyleProp<any>, string> }
|
|
978
951
|
|
|
@@ -991,8 +964,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
991
964
|
*
|
|
992
965
|
* @public
|
|
993
966
|
*/
|
|
994
|
-
getShapeUtil<S extends
|
|
995
|
-
getShapeUtil<S extends
|
|
967
|
+
getShapeUtil<S extends TLShape>(shape: S | TLShapePartial<S>): ShapeUtil<S>
|
|
968
|
+
getShapeUtil<S extends TLShape>(type: S['type']): ShapeUtil<S>
|
|
996
969
|
getShapeUtil<T extends ShapeUtil>(type: T extends ShapeUtil<infer R> ? R['type'] : string): T
|
|
997
970
|
getShapeUtil(arg: string | { type: string }) {
|
|
998
971
|
const type = typeof arg === 'string' ? arg : arg.type
|
|
@@ -1006,8 +979,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1006
979
|
*
|
|
1007
980
|
* @param shape - A shape, shape partial, or shape type.
|
|
1008
981
|
*/
|
|
1009
|
-
hasShapeUtil
|
|
1010
|
-
hasShapeUtil
|
|
982
|
+
hasShapeUtil(shape: TLShape | TLShapePartial<TLShape>): boolean
|
|
983
|
+
hasShapeUtil(type: TLShape['type']): boolean
|
|
1011
984
|
hasShapeUtil<T extends ShapeUtil>(
|
|
1012
985
|
type: T extends ShapeUtil<infer R> ? R['type'] : string
|
|
1013
986
|
): boolean
|
|
@@ -1117,35 +1090,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1117
1090
|
return this.history.getNumRedos() > 0
|
|
1118
1091
|
}
|
|
1119
1092
|
|
|
1120
|
-
/**
|
|
1121
|
-
* Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear
|
|
1122
|
-
* any redos.
|
|
1123
|
-
*
|
|
1124
|
-
* @example
|
|
1125
|
-
* ```ts
|
|
1126
|
-
* editor.mark()
|
|
1127
|
-
* editor.mark('flip shapes')
|
|
1128
|
-
* ```
|
|
1129
|
-
*
|
|
1130
|
-
* @param markId - The mark's id, usually the reason for adding the mark.
|
|
1131
|
-
*
|
|
1132
|
-
* @public
|
|
1133
|
-
* @deprecated use {@link Editor.markHistoryStoppingPoint} instead
|
|
1134
|
-
*/
|
|
1135
|
-
mark(markId?: string): this {
|
|
1136
|
-
if (typeof markId === 'string') {
|
|
1137
|
-
console.warn(
|
|
1138
|
-
`[tldraw] \`editor.history.mark("${markId}")\` is deprecated. Please use \`const myMarkId = editor.markHistoryStoppingPoint()\` instead.`
|
|
1139
|
-
)
|
|
1140
|
-
} else {
|
|
1141
|
-
console.warn(
|
|
1142
|
-
'[tldraw] `editor.mark()` is deprecated. Use `editor.markHistoryStoppingPoint()` instead.'
|
|
1143
|
-
)
|
|
1144
|
-
}
|
|
1145
|
-
this.history._mark(markId ?? uniqueId())
|
|
1146
|
-
return this
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
1093
|
/**
|
|
1150
1094
|
* Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear
|
|
1151
1095
|
* any redos. You typically want to do this just before a user interaction begins or is handled.
|
|
@@ -1270,13 +1214,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1270
1214
|
return this
|
|
1271
1215
|
}
|
|
1272
1216
|
|
|
1273
|
-
/**
|
|
1274
|
-
* @deprecated Use `Editor.run` instead.
|
|
1275
|
-
*/
|
|
1276
|
-
batch(fn: () => void, opts?: TLEditorRunOptions): this {
|
|
1277
|
-
return this.run(fn, opts)
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
1217
|
/* --------------------- Errors --------------------- */
|
|
1281
1218
|
|
|
1282
1219
|
/** @internal */
|
|
@@ -1578,54 +1515,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1578
1515
|
|
|
1579
1516
|
menus = tlmenus.forContext(this.contextId)
|
|
1580
1517
|
|
|
1581
|
-
/**
|
|
1582
|
-
* @deprecated Use `editor.menus.getOpenMenus` instead.
|
|
1583
|
-
*
|
|
1584
|
-
* @public
|
|
1585
|
-
*/
|
|
1586
|
-
@computed getOpenMenus(): string[] {
|
|
1587
|
-
return this.menus.getOpenMenus()
|
|
1588
|
-
}
|
|
1589
|
-
|
|
1590
|
-
/**
|
|
1591
|
-
* @deprecated Use `editor.menus.addOpenMenu` instead.
|
|
1592
|
-
*
|
|
1593
|
-
* @public
|
|
1594
|
-
*/
|
|
1595
|
-
addOpenMenu(id: string): this {
|
|
1596
|
-
this.menus.addOpenMenu(id)
|
|
1597
|
-
return this
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
|
-
/**
|
|
1601
|
-
* @deprecated Use `editor.menus.deleteOpenMenu` instead.
|
|
1602
|
-
*
|
|
1603
|
-
* @public
|
|
1604
|
-
*/
|
|
1605
|
-
deleteOpenMenu(id: string): this {
|
|
1606
|
-
this.menus.deleteOpenMenu(id)
|
|
1607
|
-
return this
|
|
1608
|
-
}
|
|
1609
|
-
|
|
1610
|
-
/**
|
|
1611
|
-
* @deprecated Use `editor.menus.clearOpenMenus` instead.
|
|
1612
|
-
*
|
|
1613
|
-
* @public
|
|
1614
|
-
*/
|
|
1615
|
-
clearOpenMenus(): this {
|
|
1616
|
-
this.menus.clearOpenMenus()
|
|
1617
|
-
return this
|
|
1618
|
-
}
|
|
1619
|
-
|
|
1620
|
-
/**
|
|
1621
|
-
* @deprecated Use `editor.menus.hasAnyOpenMenus` instead.
|
|
1622
|
-
*
|
|
1623
|
-
* @public
|
|
1624
|
-
*/
|
|
1625
|
-
@computed getIsMenuOpen(): boolean {
|
|
1626
|
-
return this.menus.hasAnyOpenMenus()
|
|
1627
|
-
}
|
|
1628
|
-
|
|
1629
1518
|
/* --------------------- Cursor --------------------- */
|
|
1630
1519
|
|
|
1631
1520
|
/**
|
|
@@ -1803,7 +1692,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1803
1692
|
}
|
|
1804
1693
|
|
|
1805
1694
|
/**
|
|
1806
|
-
* Select all
|
|
1695
|
+
* Select all shapes. If the user has selected shapes that share a parent,
|
|
1696
|
+
* select all shapes within that parent. If the user has not selected any shapes,
|
|
1697
|
+
* or if the shapes shapes are only on select all shapes on the current page.
|
|
1807
1698
|
*
|
|
1808
1699
|
* @example
|
|
1809
1700
|
* ```ts
|
|
@@ -1813,11 +1704,34 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1813
1704
|
* @public
|
|
1814
1705
|
*/
|
|
1815
1706
|
selectAll(): this {
|
|
1816
|
-
|
|
1817
|
-
|
|
1707
|
+
let parentToSelectWithinId: TLParentId | null = null
|
|
1708
|
+
|
|
1709
|
+
const selectedShapeIds = this.getSelectedShapeIds()
|
|
1710
|
+
|
|
1711
|
+
// If we have selected shapes, try to find a parent to select within
|
|
1712
|
+
if (selectedShapeIds.length > 0) {
|
|
1713
|
+
for (const id of selectedShapeIds) {
|
|
1714
|
+
const shape = this.getShape(id)
|
|
1715
|
+
if (!shape) continue
|
|
1716
|
+
if (parentToSelectWithinId === null) {
|
|
1717
|
+
// If we haven't found a parent yet, set this parent as the parent to select within
|
|
1718
|
+
parentToSelectWithinId = shape.parentId
|
|
1719
|
+
} else if (parentToSelectWithinId !== shape.parentId) {
|
|
1720
|
+
// If we've found two different parents, we can't select all, do nothing
|
|
1721
|
+
return this
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
// If we haven't found a parent from our selected shapes, select the current page
|
|
1727
|
+
if (!parentToSelectWithinId) {
|
|
1728
|
+
parentToSelectWithinId = this.getCurrentPageId()
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
// Select all the unlocked shapes within the parent
|
|
1732
|
+
const ids = this.getSortedChildIdsForParent(parentToSelectWithinId)
|
|
1818
1733
|
if (ids.length <= 0) return this
|
|
1819
1734
|
this.setSelectedShapes(this._getUnlockedShapeIds(ids))
|
|
1820
|
-
|
|
1821
1735
|
return this
|
|
1822
1736
|
}
|
|
1823
1737
|
|
|
@@ -1838,10 +1752,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1838
1752
|
firstParentId &&
|
|
1839
1753
|
selectedShapeIds.every((shapeId) => this.getShape(shapeId)?.parentId === firstParentId) &&
|
|
1840
1754
|
!isPageId(firstParentId)
|
|
1755
|
+
const filteredShapes = isSelectedWithinContainer
|
|
1756
|
+
? this.getCurrentPageShapes().filter((shape) => shape.parentId === firstParentId)
|
|
1757
|
+
: this.getCurrentPageShapes().filter((shape) => isPageId(shape.parentId))
|
|
1841
1758
|
const readingOrderShapes = isSelectedWithinContainer
|
|
1842
|
-
? this._getShapesInReadingOrder(
|
|
1843
|
-
this.getCurrentPageShapes().filter((shape) => shape.parentId === firstParentId)
|
|
1844
|
-
)
|
|
1759
|
+
? this._getShapesInReadingOrder(filteredShapes)
|
|
1845
1760
|
: this.getCurrentPageShapesInReadingOrder()
|
|
1846
1761
|
const currentShapeId: TLShapeId | undefined =
|
|
1847
1762
|
selectedShapeIds.length === 1
|
|
@@ -1858,7 +1773,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1858
1773
|
adjacentShapeId = shapeIds[adjacentIndex]
|
|
1859
1774
|
} else {
|
|
1860
1775
|
if (!currentShapeId) return
|
|
1861
|
-
adjacentShapeId = this.getNearestAdjacentShape(currentShapeId, direction)
|
|
1776
|
+
adjacentShapeId = this.getNearestAdjacentShape(filteredShapes, currentShapeId, direction)
|
|
1862
1777
|
}
|
|
1863
1778
|
|
|
1864
1779
|
const shape = this.getShape(adjacentShapeId)
|
|
@@ -1957,6 +1872,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1957
1872
|
* @public
|
|
1958
1873
|
*/
|
|
1959
1874
|
getNearestAdjacentShape(
|
|
1875
|
+
shapes: TLShape[],
|
|
1960
1876
|
currentShapeId: TLShapeId,
|
|
1961
1877
|
direction: 'left' | 'right' | 'up' | 'down'
|
|
1962
1878
|
): TLShapeId {
|
|
@@ -1964,7 +1880,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1964
1880
|
const currentShape = this.getShape(currentShapeId)
|
|
1965
1881
|
if (!currentShape) return currentShapeId
|
|
1966
1882
|
|
|
1967
|
-
const shapes = this.getCurrentPageShapes()
|
|
1968
1883
|
const tabbableShapes = shapes.filter(
|
|
1969
1884
|
(shape) => this.getShapeUtil(shape).canTabTo(shape) && shape.id !== currentShapeId
|
|
1970
1885
|
)
|
|
@@ -3046,7 +2961,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3046
2961
|
// Dispatch a new pointer move because the pointer's page will have changed
|
|
3047
2962
|
// (its screen position will compute to a new page position given the new camera position)
|
|
3048
2963
|
const { currentScreenPoint, currentPagePoint } = this.inputs
|
|
3049
|
-
const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!
|
|
3050
2964
|
|
|
3051
2965
|
// compare the next page point (derived from the current camera) to the current page point
|
|
3052
2966
|
if (
|
|
@@ -3054,27 +2968,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3054
2968
|
currentScreenPoint.y / z - y !== currentPagePoint.y
|
|
3055
2969
|
) {
|
|
3056
2970
|
// If it's changed, dispatch a pointer event
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
target: 'canvas',
|
|
3060
|
-
name: 'pointer_move',
|
|
3061
|
-
// weird but true: we need to put the screen point back into client space
|
|
3062
|
-
point: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),
|
|
2971
|
+
this.updatePointer({
|
|
2972
|
+
immediate: opts?.immediate,
|
|
3063
2973
|
pointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,
|
|
3064
|
-
|
|
3065
|
-
altKey: this.inputs.altKey,
|
|
3066
|
-
shiftKey: this.inputs.shiftKey,
|
|
3067
|
-
metaKey: this.inputs.metaKey,
|
|
3068
|
-
accelKey: isAccelKey(this.inputs),
|
|
3069
|
-
button: 0,
|
|
3070
|
-
isPen: this.getInstanceState().isPenMode ?? false,
|
|
3071
|
-
}
|
|
3072
|
-
|
|
3073
|
-
if (opts?.immediate) {
|
|
3074
|
-
this._flushEventForTick(event)
|
|
3075
|
-
} else {
|
|
3076
|
-
this.dispatch(event)
|
|
3077
|
-
}
|
|
2974
|
+
})
|
|
3078
2975
|
}
|
|
3079
2976
|
|
|
3080
2977
|
this._tickCameraState()
|
|
@@ -4395,21 +4292,28 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4395
4292
|
*/
|
|
4396
4293
|
deletePage(page: TLPageId | TLPage): this {
|
|
4397
4294
|
const id = typeof page === 'string' ? page : page.id
|
|
4398
|
-
this.run(
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4295
|
+
this.run(
|
|
4296
|
+
() => {
|
|
4297
|
+
if (this.getIsReadonly()) return
|
|
4298
|
+
const pages = this.getPages()
|
|
4299
|
+
if (pages.length === 1) return
|
|
4402
4300
|
|
|
4403
|
-
|
|
4404
|
-
|
|
4301
|
+
const deletedPage = this.getPage(id)
|
|
4302
|
+
if (!deletedPage) return
|
|
4405
4303
|
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4304
|
+
if (id === this.getCurrentPageId()) {
|
|
4305
|
+
const index = pages.findIndex((page) => page.id === id)
|
|
4306
|
+
const next = pages[index - 1] ?? pages[index + 1]
|
|
4307
|
+
this.setCurrentPage(next.id)
|
|
4308
|
+
}
|
|
4309
|
+
|
|
4310
|
+
const shapes = this.getSortedChildIdsForParent(deletedPage.id)
|
|
4311
|
+
this.deleteShapes(shapes)
|
|
4312
|
+
|
|
4313
|
+
this.store.remove([deletedPage.id])
|
|
4314
|
+
},
|
|
4315
|
+
{ ignoreShapeLock: true }
|
|
4316
|
+
)
|
|
4413
4317
|
return this
|
|
4414
4318
|
}
|
|
4415
4319
|
|
|
@@ -4775,8 +4679,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4775
4679
|
return this.store.createComputedCache<Box, TLShape>('pageBoundsCache', (shape) => {
|
|
4776
4680
|
const pageTransform = this.getShapePageTransform(shape)
|
|
4777
4681
|
if (!pageTransform) return undefined
|
|
4778
|
-
|
|
4779
|
-
return Box.FromPoints(
|
|
4682
|
+
|
|
4683
|
+
return Box.FromPoints(
|
|
4684
|
+
pageTransform.applyToPoints(this.getShapeGeometry(shape).boundsVertices)
|
|
4685
|
+
)
|
|
4780
4686
|
})
|
|
4781
4687
|
}
|
|
4782
4688
|
|
|
@@ -4843,27 +4749,25 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4843
4749
|
return this.store.createComputedCache('pageMaskCache', (shape) => {
|
|
4844
4750
|
if (isPageId(shape.parentId)) return undefined
|
|
4845
4751
|
|
|
4846
|
-
const
|
|
4847
|
-
|
|
4848
|
-
)
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
return []
|
|
4866
|
-
})
|
|
4752
|
+
const clipPaths: Vec[][] = []
|
|
4753
|
+
// Get all ancestors that can potentially clip this shape
|
|
4754
|
+
for (const ancestor of this.getShapeAncestors(shape.id)) {
|
|
4755
|
+
const util = this.getShapeUtil(ancestor)
|
|
4756
|
+
const clipPath = util.getClipPath?.(ancestor)
|
|
4757
|
+
if (!clipPath) continue
|
|
4758
|
+
if (util.shouldClipChild?.(shape) === false) continue
|
|
4759
|
+
const pageTransform = this.getShapePageTransform(ancestor.id)
|
|
4760
|
+
clipPaths.push(pageTransform.applyToPoints(clipPath))
|
|
4761
|
+
}
|
|
4762
|
+
if (clipPaths.length === 0) return undefined
|
|
4763
|
+
|
|
4764
|
+
const pageMask = clipPaths.reduce((acc, b) => {
|
|
4765
|
+
const intersection = intersectPolygonPolygon(acc, b)
|
|
4766
|
+
if (intersection) {
|
|
4767
|
+
return intersection.map(Vec.Cast)
|
|
4768
|
+
}
|
|
4769
|
+
return []
|
|
4770
|
+
})
|
|
4867
4771
|
|
|
4868
4772
|
return pageMask
|
|
4869
4773
|
})
|
|
@@ -5138,20 +5042,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5138
5042
|
*
|
|
5139
5043
|
* @returns The shape at the given point, or undefined if there is no shape at the point.
|
|
5140
5044
|
*/
|
|
5141
|
-
getShapeAtPoint(
|
|
5142
|
-
point: VecLike,
|
|
5143
|
-
opts = {} as {
|
|
5144
|
-
renderingOnly?: boolean
|
|
5145
|
-
margin?: number
|
|
5146
|
-
hitInside?: boolean
|
|
5147
|
-
hitLocked?: boolean
|
|
5148
|
-
// TODO: we probably need to rename this, we don't quite _always_
|
|
5149
|
-
// respect this esp. in the part below that does "Check labels first"
|
|
5150
|
-
hitLabels?: boolean
|
|
5151
|
-
hitFrameInside?: boolean
|
|
5152
|
-
filter?(shape: TLShape): boolean
|
|
5153
|
-
}
|
|
5154
|
-
): TLShape | undefined {
|
|
5045
|
+
getShapeAtPoint(point: VecLike, opts: TLGetShapeAtPointOptions = {}): TLShape | undefined {
|
|
5155
5046
|
const zoomLevel = this.getZoomLevel()
|
|
5156
5047
|
const viewportPageBounds = this.getViewportPageBounds()
|
|
5157
5048
|
const {
|
|
@@ -5163,6 +5054,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5163
5054
|
hitFrameInside = false,
|
|
5164
5055
|
} = opts
|
|
5165
5056
|
|
|
5057
|
+
const [innerMargin, outerMargin] = Array.isArray(margin) ? margin : [margin, margin]
|
|
5058
|
+
|
|
5166
5059
|
let inHollowSmallestArea = Infinity
|
|
5167
5060
|
let inHollowSmallestAreaHit: TLShape | null = null
|
|
5168
5061
|
|
|
@@ -5182,7 +5075,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5182
5075
|
return false
|
|
5183
5076
|
const pageMask = this.getShapeMask(shape)
|
|
5184
5077
|
if (pageMask && !pointInPolygon(point, pageMask)) return false
|
|
5185
|
-
if (filter
|
|
5078
|
+
if (filter && !filter(shape)) return false
|
|
5186
5079
|
return true
|
|
5187
5080
|
})
|
|
5188
5081
|
|
|
@@ -5196,8 +5089,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5196
5089
|
// Check labels first
|
|
5197
5090
|
if (
|
|
5198
5091
|
this.isShapeOfType<TLFrameShape>(shape, 'frame') ||
|
|
5199
|
-
(this.isShapeOfType<TLArrowShape>(shape, 'arrow') && shape.props.text.trim()) ||
|
|
5200
5092
|
((this.isShapeOfType<TLNoteShape>(shape, 'note') ||
|
|
5093
|
+
this.isShapeOfType<TLArrowShape>(shape, 'arrow') ||
|
|
5201
5094
|
(this.isShapeOfType<TLGeoShape>(shape, 'geo') && shape.props.fill === 'none')) &&
|
|
5202
5095
|
this.getShapeUtil(shape).getText(shape)?.trim())
|
|
5203
5096
|
) {
|
|
@@ -5208,13 +5101,18 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5208
5101
|
}
|
|
5209
5102
|
}
|
|
5210
5103
|
|
|
5211
|
-
if (this.isShapeOfType(shape, 'frame')) {
|
|
5104
|
+
if (this.isShapeOfType<TLFrameShape>(shape, 'frame')) {
|
|
5212
5105
|
// On the rare case that we've hit a frame (not its label), test again hitInside to be forced true;
|
|
5213
5106
|
// this prevents clicks from passing through the body of a frame to shapes behind it.
|
|
5214
5107
|
|
|
5215
5108
|
// If the hit is within the frame's outer margin, then select the frame
|
|
5216
|
-
const distance = geometry.distanceToPoint(pointInShapeSpace,
|
|
5217
|
-
if (
|
|
5109
|
+
const distance = geometry.distanceToPoint(pointInShapeSpace, hitFrameInside)
|
|
5110
|
+
if (
|
|
5111
|
+
hitFrameInside
|
|
5112
|
+
? (distance > 0 && distance <= outerMargin) ||
|
|
5113
|
+
(distance <= 0 && distance > -innerMargin)
|
|
5114
|
+
: distance > 0 && distance <= outerMargin
|
|
5115
|
+
) {
|
|
5218
5116
|
return inMarginClosestToEdgeHit || shape
|
|
5219
5117
|
}
|
|
5220
5118
|
|
|
@@ -5253,11 +5151,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5253
5151
|
// If the margin is zero and the geometry has a very small width or height,
|
|
5254
5152
|
// then check the actual distance. This is to prevent a bug where straight
|
|
5255
5153
|
// lines would never pass the broad phase (point-in-bounds) check.
|
|
5256
|
-
if (
|
|
5154
|
+
if (outerMargin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {
|
|
5257
5155
|
distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)
|
|
5258
5156
|
} else {
|
|
5259
5157
|
// Broad phase
|
|
5260
|
-
if (geometry.bounds.containsPoint(pointInShapeSpace,
|
|
5158
|
+
if (geometry.bounds.containsPoint(pointInShapeSpace, outerMargin)) {
|
|
5261
5159
|
// Narrow phase (actual distance)
|
|
5262
5160
|
distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)
|
|
5263
5161
|
} else {
|
|
@@ -5272,7 +5170,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5272
5170
|
// the shape or negative if inside of the shape. If the distance
|
|
5273
5171
|
// is greater than the margin, then it's a miss. Otherwise...
|
|
5274
5172
|
|
|
5275
|
-
|
|
5173
|
+
// Are we close to the shape's edge?
|
|
5174
|
+
if (distance <= outerMargin || (hitInside && distance <= 0 && distance > -innerMargin)) {
|
|
5276
5175
|
if (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {
|
|
5277
5176
|
// If the shape is filled, then it's a hit. Remember, we're
|
|
5278
5177
|
// starting from the TOP-MOST shape in z-index order, so any
|
|
@@ -5282,11 +5181,21 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5282
5181
|
// If the shape is bigger than the viewport, then skip it.
|
|
5283
5182
|
if (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue
|
|
5284
5183
|
|
|
5285
|
-
//
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5184
|
+
// If we're close to the edge of the shape, and if it's the closest edge among
|
|
5185
|
+
// all the edges that we've gotten close to so far, then we will want to hit the
|
|
5186
|
+
// shape unless we hit something else or closer in later iterations.
|
|
5187
|
+
if (
|
|
5188
|
+
hitInside
|
|
5189
|
+
? // On hitInside, the distance will be negative for hits inside
|
|
5190
|
+
// If the distance is positive, check against the outer margin
|
|
5191
|
+
(distance > 0 && distance <= outerMargin) ||
|
|
5192
|
+
// If the distance is negative, check against the inner margin
|
|
5193
|
+
(distance <= 0 && distance > -innerMargin)
|
|
5194
|
+
: // If hitInside is false, then sadly _we do not know_ whether the
|
|
5195
|
+
// point is inside or outside of the shape, so we check against
|
|
5196
|
+
// the max of the two margins
|
|
5197
|
+
Math.abs(distance) <= Math.max(innerMargin, outerMargin)
|
|
5198
|
+
) {
|
|
5290
5199
|
if (Math.abs(distance) < inMarginClosestToEdgeDistance) {
|
|
5291
5200
|
inMarginClosestToEdgeDistance = Math.abs(distance)
|
|
5292
5201
|
inMarginClosestToEdgeHit = shape
|
|
@@ -5308,6 +5217,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5308
5217
|
} else {
|
|
5309
5218
|
// For open shapes (e.g. lines or draw shapes) always use the margin.
|
|
5310
5219
|
// If the distance is less than the margin, return the shape as the hit.
|
|
5220
|
+
// Use the editor's configurable hit test margin.
|
|
5311
5221
|
if (distance < this.options.hitTestMargin / zoomLevel) {
|
|
5312
5222
|
return shape
|
|
5313
5223
|
}
|
|
@@ -5480,15 +5390,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5480
5390
|
*
|
|
5481
5391
|
* @public
|
|
5482
5392
|
*/
|
|
5483
|
-
isShapeOfType<T extends
|
|
5484
|
-
isShapeOfType<T extends
|
|
5485
|
-
|
|
5486
|
-
type: T['type']
|
|
5487
|
-
): shapeId is T['id']
|
|
5488
|
-
isShapeOfType<T extends TLUnknownShape>(
|
|
5489
|
-
arg: TLUnknownShape | TLUnknownShape['id'],
|
|
5490
|
-
type: T['type']
|
|
5491
|
-
) {
|
|
5393
|
+
isShapeOfType<T extends TLShape>(shape: TLShape, type: T['type']): shape is T
|
|
5394
|
+
isShapeOfType<T extends TLShape = TLShape>(shapeId: TLShapeId, type: T['type']): boolean
|
|
5395
|
+
isShapeOfType(arg: TLShape | TLShapeId, type: TLShape['type']) {
|
|
5492
5396
|
const shape = typeof arg === 'string' ? this.getShape(arg) : arg
|
|
5493
5397
|
if (!shape) return false
|
|
5494
5398
|
return shape.type === type
|
|
@@ -5818,11 +5722,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5818
5722
|
return shapeIds
|
|
5819
5723
|
}
|
|
5820
5724
|
|
|
5821
|
-
/** @deprecated Use {@link Editor.getDraggingOverShape} instead */
|
|
5822
|
-
getDroppingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {
|
|
5823
|
-
return this.getDraggingOverShape(point, droppingShapes)
|
|
5824
|
-
}
|
|
5825
|
-
|
|
5826
5725
|
/**
|
|
5827
5726
|
* Get the shape that some shapes should be dropped on at a given point.
|
|
5828
5727
|
*
|
|
@@ -6310,7 +6209,17 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6310
6209
|
|
|
6311
6210
|
this.createShapes(shapesToCreate)
|
|
6312
6211
|
this.createBindings(bindingsToCreate)
|
|
6313
|
-
|
|
6212
|
+
|
|
6213
|
+
this.setSelectedShapes(
|
|
6214
|
+
compact(
|
|
6215
|
+
ids.map((oldId) => {
|
|
6216
|
+
const newId = shapeIds.get(oldId)
|
|
6217
|
+
if (!newId) return null
|
|
6218
|
+
if (!this.getShape(newId)) return null
|
|
6219
|
+
return newId
|
|
6220
|
+
})
|
|
6221
|
+
)
|
|
6222
|
+
)
|
|
6314
6223
|
|
|
6315
6224
|
if (offset !== undefined) {
|
|
6316
6225
|
// If we've offset the duplicated shapes, check to see whether their new bounds is entirely
|
|
@@ -7364,7 +7273,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7364
7273
|
if (
|
|
7365
7274
|
!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
7366
7275
|
type: 'stretch',
|
|
7367
|
-
shapes: shapesToStretchFirstPass,
|
|
7368
7276
|
})
|
|
7369
7277
|
) {
|
|
7370
7278
|
continue
|
|
@@ -7739,9 +7647,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7739
7647
|
*
|
|
7740
7648
|
* @public
|
|
7741
7649
|
*/
|
|
7742
|
-
canCreateShape<
|
|
7743
|
-
shape: OptionalKeys<TLShapePartial<T>, 'id'> | T['id']
|
|
7744
|
-
): boolean {
|
|
7650
|
+
canCreateShape(shape: OptionalKeys<TLShapePartial<TLShape>, 'id'> | TLShape['id']): boolean {
|
|
7745
7651
|
return this.canCreateShapes([shape])
|
|
7746
7652
|
}
|
|
7747
7653
|
|
|
@@ -7752,8 +7658,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7752
7658
|
*
|
|
7753
7659
|
* @public
|
|
7754
7660
|
*/
|
|
7755
|
-
canCreateShapes
|
|
7756
|
-
shapes: (
|
|
7661
|
+
canCreateShapes(
|
|
7662
|
+
shapes: (TLShape['id'] | OptionalKeys<TLShapePartial<TLShape>, 'id'>)[]
|
|
7757
7663
|
): boolean {
|
|
7758
7664
|
return shapes.length + this.getCurrentPageShapeIds().size <= this.options.maxShapesPerPage
|
|
7759
7665
|
}
|
|
@@ -7771,7 +7677,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7771
7677
|
*
|
|
7772
7678
|
* @public
|
|
7773
7679
|
*/
|
|
7774
|
-
createShape<
|
|
7680
|
+
createShape<TShape extends TLShape>(shape: OptionalKeys<TLShapePartial<TShape>, 'id'>): this {
|
|
7775
7681
|
this.createShapes([shape])
|
|
7776
7682
|
return this
|
|
7777
7683
|
}
|
|
@@ -7789,7 +7695,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7789
7695
|
*
|
|
7790
7696
|
* @public
|
|
7791
7697
|
*/
|
|
7792
|
-
createShapes<
|
|
7698
|
+
createShapes<TShape extends TLShape = TLShape>(
|
|
7699
|
+
shapes: OptionalKeys<TLShapePartial<TShape>, 'id'>[]
|
|
7700
|
+
): this {
|
|
7793
7701
|
if (!Array.isArray(shapes)) {
|
|
7794
7702
|
throw Error('Editor.createShapes: must provide an array of shapes or shape partials')
|
|
7795
7703
|
}
|
|
@@ -7835,31 +7743,38 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7835
7743
|
) {
|
|
7836
7744
|
let parentId: TLParentId = this.getFocusedGroupId()
|
|
7837
7745
|
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7746
|
+
const isPositioned = partial.x !== undefined && partial.y !== undefined
|
|
7747
|
+
|
|
7748
|
+
// If the shape has been explicitly positioned, we'll try to find a parent at
|
|
7749
|
+
// that position. If not, we'll assume the user isn't deliberately placing the
|
|
7750
|
+
// shape and the positioning will be handled later by another system.
|
|
7751
|
+
if (isPositioned) {
|
|
7752
|
+
for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
|
|
7753
|
+
const parent = currentPageShapesSorted[i]
|
|
7754
|
+
const util = this.getShapeUtil(parent)
|
|
7755
|
+
if (
|
|
7756
|
+
util.canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7757
|
+
!this.isShapeHidden(parent) &&
|
|
7758
|
+
this.isPointInShape(
|
|
7759
|
+
parent,
|
|
7760
|
+
// If no parent is provided, then we can treat the
|
|
7761
|
+
// shape's provided x/y as being in the page's space.
|
|
7762
|
+
{ x: partial.x ?? 0, y: partial.y ?? 0 },
|
|
7763
|
+
{
|
|
7764
|
+
margin: 0,
|
|
7765
|
+
hitInside: true,
|
|
7766
|
+
}
|
|
7767
|
+
)
|
|
7768
|
+
) {
|
|
7769
|
+
parentId = parent.id
|
|
7770
|
+
break
|
|
7771
|
+
}
|
|
7857
7772
|
}
|
|
7858
7773
|
}
|
|
7859
7774
|
|
|
7860
7775
|
const prevParentId = partial.parentId
|
|
7861
7776
|
|
|
7862
|
-
// a shape cannot be
|
|
7777
|
+
// a shape cannot be its own parent. This was a rare issue with frames/groups in the syncFuzz tests.
|
|
7863
7778
|
if (parentId === partial.id) {
|
|
7864
7779
|
parentId = focusedGroupId
|
|
7865
7780
|
}
|
|
@@ -8279,7 +8194,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8279
8194
|
*
|
|
8280
8195
|
* @public
|
|
8281
8196
|
*/
|
|
8282
|
-
updateShape<T extends
|
|
8197
|
+
updateShape<T extends TLShape = TLShape>(partial: TLShapePartial<T> | null | undefined) {
|
|
8283
8198
|
this.updateShapes([partial])
|
|
8284
8199
|
return this
|
|
8285
8200
|
}
|
|
@@ -8296,7 +8211,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8296
8211
|
*
|
|
8297
8212
|
* @public
|
|
8298
8213
|
*/
|
|
8299
|
-
updateShapes<T extends
|
|
8214
|
+
updateShapes<T extends TLShape>(partials: (TLShapePartial<T> | null | undefined)[]) {
|
|
8300
8215
|
const compactedPartials: TLShapePartial<T>[] = Array(partials.length)
|
|
8301
8216
|
|
|
8302
8217
|
for (let i = 0, n = partials.length; i < n; i++) {
|
|
@@ -8911,8 +8826,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8911
8826
|
* Handle external content, such as files, urls, embeds, or plain text which has been put into the app, for example by pasting external text or dropping external images onto canvas.
|
|
8912
8827
|
*
|
|
8913
8828
|
* @param info - Info about the external content.
|
|
8829
|
+
* @param opts - Options for handling external content, including force flag to bypass readonly checks.
|
|
8914
8830
|
*/
|
|
8915
|
-
async putExternalContent<E>(
|
|
8831
|
+
async putExternalContent<E>(
|
|
8832
|
+
info: TLExternalContent<E>,
|
|
8833
|
+
opts = {} as { force?: boolean }
|
|
8834
|
+
): Promise<void> {
|
|
8835
|
+
if (!opts.force && this.getIsReadonly()) return
|
|
8916
8836
|
return this.externalContentHandlers[info.type]?.(info as any)
|
|
8917
8837
|
}
|
|
8918
8838
|
|
|
@@ -8920,8 +8840,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
8920
8840
|
* Handle replacing external content.
|
|
8921
8841
|
*
|
|
8922
8842
|
* @param info - Info about the external content.
|
|
8843
|
+
* @param opts - Options for handling external content, including force flag to bypass readonly checks.
|
|
8923
8844
|
*/
|
|
8924
|
-
async replaceExternalContent<E>(
|
|
8845
|
+
async replaceExternalContent<E>(
|
|
8846
|
+
info: TLExternalContent<E>,
|
|
8847
|
+
opts = {} as { force?: boolean }
|
|
8848
|
+
): Promise<void> {
|
|
8849
|
+
if (!opts.force && this.getIsReadonly()) return
|
|
8925
8850
|
return this.externalContentHandlers[info.type]?.(info as any)
|
|
8926
8851
|
}
|
|
8927
8852
|
|
|
@@ -9422,13 +9347,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9422
9347
|
}
|
|
9423
9348
|
}
|
|
9424
9349
|
|
|
9425
|
-
/** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */
|
|
9426
|
-
async getSvg(shapes: TLShapeId[] | TLShape[], opts: TLSvgExportOptions = {}) {
|
|
9427
|
-
const result = await this.getSvgElement(shapes, opts)
|
|
9428
|
-
if (!result) return undefined
|
|
9429
|
-
return result.svg
|
|
9430
|
-
}
|
|
9431
|
-
|
|
9432
9350
|
/**
|
|
9433
9351
|
* Get an exported image of the given shapes.
|
|
9434
9352
|
*
|
|
@@ -9480,6 +9398,24 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9480
9398
|
}
|
|
9481
9399
|
}
|
|
9482
9400
|
|
|
9401
|
+
/**
|
|
9402
|
+
* Get an exported image of the given shapes as a data URL.
|
|
9403
|
+
*
|
|
9404
|
+
* @param shapes - The shapes (or shape ids) to export.
|
|
9405
|
+
* @param opts - Options for the export.
|
|
9406
|
+
*
|
|
9407
|
+
* @returns A data URL of the image.
|
|
9408
|
+
* @public
|
|
9409
|
+
*/
|
|
9410
|
+
async toImageDataUrl(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {
|
|
9411
|
+
const { blob, width, height } = await this.toImage(shapes, opts)
|
|
9412
|
+
return {
|
|
9413
|
+
url: await FileHelpers.blobToDataUrl(blob),
|
|
9414
|
+
width,
|
|
9415
|
+
height,
|
|
9416
|
+
}
|
|
9417
|
+
}
|
|
9418
|
+
|
|
9483
9419
|
/* --------------------- Events --------------------- */
|
|
9484
9420
|
|
|
9485
9421
|
/**
|
|
@@ -9647,6 +9583,52 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9647
9583
|
return this
|
|
9648
9584
|
}
|
|
9649
9585
|
|
|
9586
|
+
/**
|
|
9587
|
+
* Dispatch a pointer move event in the current position of the pointer. This is useful when
|
|
9588
|
+
* external circumstances have changed (e.g. the camera moved or a shape was moved) and you want
|
|
9589
|
+
* the current interaction to respond to that change.
|
|
9590
|
+
*
|
|
9591
|
+
* @example
|
|
9592
|
+
* ```ts
|
|
9593
|
+
* editor.updatePointer()
|
|
9594
|
+
* ```
|
|
9595
|
+
*
|
|
9596
|
+
* @param options - The options for updating the pointer.
|
|
9597
|
+
* @returns The editor instance.
|
|
9598
|
+
* @public
|
|
9599
|
+
*/
|
|
9600
|
+
updatePointer(options?: TLUpdatePointerOptions): this {
|
|
9601
|
+
const event: TLPointerEventInfo = {
|
|
9602
|
+
type: 'pointer',
|
|
9603
|
+
target: 'canvas',
|
|
9604
|
+
name: 'pointer_move',
|
|
9605
|
+
point:
|
|
9606
|
+
options?.point ??
|
|
9607
|
+
// weird but true: what `inputs` calls screen-space is actually viewport space. so
|
|
9608
|
+
// we need to convert back into true screen space first. we should fix this...
|
|
9609
|
+
Vec.Add(
|
|
9610
|
+
this.inputs.currentScreenPoint,
|
|
9611
|
+
this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!.screenBounds
|
|
9612
|
+
),
|
|
9613
|
+
pointerId: options?.pointerId ?? 0,
|
|
9614
|
+
button: options?.button ?? 0,
|
|
9615
|
+
isPen: options?.isPen ?? this.inputs.isPen,
|
|
9616
|
+
shiftKey: options?.shiftKey ?? this.inputs.shiftKey,
|
|
9617
|
+
altKey: options?.altKey ?? this.inputs.altKey,
|
|
9618
|
+
ctrlKey: options?.ctrlKey ?? this.inputs.ctrlKey,
|
|
9619
|
+
metaKey: options?.metaKey ?? this.inputs.metaKey,
|
|
9620
|
+
accelKey: options?.accelKey ?? isAccelKey(this.inputs),
|
|
9621
|
+
}
|
|
9622
|
+
|
|
9623
|
+
if (options?.immediate) {
|
|
9624
|
+
this._flushEventForTick(event)
|
|
9625
|
+
} else {
|
|
9626
|
+
this.dispatch(event)
|
|
9627
|
+
}
|
|
9628
|
+
|
|
9629
|
+
return this
|
|
9630
|
+
}
|
|
9631
|
+
|
|
9650
9632
|
/**
|
|
9651
9633
|
* Puts the editor into focused mode.
|
|
9652
9634
|
*
|
|
@@ -10665,7 +10647,10 @@ function alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {
|
|
|
10665
10647
|
|
|
10666
10648
|
function applyPartialToRecordWithProps<
|
|
10667
10649
|
T extends UnknownRecord & { type: string; props: object; meta: object },
|
|
10668
|
-
>(
|
|
10650
|
+
>(
|
|
10651
|
+
prev: T,
|
|
10652
|
+
partial?: T extends T ? Omit<Partial<T>, 'props'> & { props?: Partial<T['props']> } : never
|
|
10653
|
+
): T {
|
|
10669
10654
|
if (!partial) return prev
|
|
10670
10655
|
let next = null as null | T
|
|
10671
10656
|
const entries = Object.entries(partial)
|