tldraw 5.4.0-next.ebc95cf01337 → 5.4.0
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/DOCS.md +2826 -3226
- package/RELEASE_NOTES.md +190 -2
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/defaultExternalContentHandlers.js +30 -14
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/curved-arrow.js +2 -2
- package/dist-cjs/lib/shapes/arrow/curved-arrow.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/elbow/getElbowArrowInfo.js +2 -2
- package/dist-cjs/lib/shapes/arrow/elbow/getElbowArrowInfo.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/getArrowInfo.js +1 -1
- package/dist-cjs/lib/shapes/arrow/getArrowInfo.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/straight-arrow.js +2 -2
- package/dist-cjs/lib/shapes/arrow/straight-arrow.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js +2 -3
- package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +7 -5
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +8 -6
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/getGeoShapePath.js +3 -1
- package/dist-cjs/lib/shapes/geo/getGeoShapePath.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/toolStates/Idle.js +2 -3
- package/dist-cjs/lib/shapes/geo/toolStates/Idle.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +1 -1
- package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +2 -6
- package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/noteHelpers.js +6 -5
- package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
- package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +1 -1
- package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/crop.js +1 -1
- package/dist-cjs/lib/shapes/shared/crop.js.map +2 -2
- package/dist-cjs/lib/shapes/text/toolStates/Idle.js +1 -1
- package/dist-cjs/lib/shapes/text/toolStates/Idle.js.map +2 -2
- package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +1 -0
- package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -2
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +2 -0
- package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js +6 -0
- package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/SelectTool.js +3 -0
- package/dist-cjs/lib/tools/SelectTool/SelectTool.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js +1 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/Crop.js +1 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/Crop.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +1 -3
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +6 -3
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +1 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js +3 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js +1 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +1 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +22 -30
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js +1 -3
- package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +4 -1
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/selectHelpers.js +10 -0
- package/dist-cjs/lib/tools/SelectTool/selectHelpers.js.map +2 -2
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +1 -8
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +6 -1
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/Dialogs.js +8 -0
- package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
- package/dist-cjs/lib/ui/components/EditLinkDialog.js +5 -5
- package/dist-cjs/lib/ui/components/EditLinkDialog.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +4 -20
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js +2 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +1 -0
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +10 -8
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +20 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +8 -7
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useCommentingEnabled.js +1 -1
- package/dist-cjs/lib/ui/hooks/useCommentingEnabled.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +30 -14
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/curved-arrow.mjs +2 -2
- package/dist-esm/lib/shapes/arrow/curved-arrow.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/elbow/getElbowArrowInfo.mjs +2 -2
- package/dist-esm/lib/shapes/arrow/elbow/getElbowArrowInfo.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/getArrowInfo.mjs +1 -1
- package/dist-esm/lib/shapes/arrow/getArrowInfo.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/straight-arrow.mjs +2 -2
- package/dist-esm/lib/shapes/arrow/straight-arrow.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs +3 -4
- package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +7 -5
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +8 -6
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/getGeoShapePath.mjs +3 -1
- package/dist-esm/lib/shapes/geo/getGeoShapePath.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs +3 -4
- package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +1 -1
- package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +2 -7
- package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +4 -4
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/noteHelpers.mjs +6 -5
- package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +1 -1
- package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/crop.mjs +1 -1
- package/dist-esm/lib/shapes/shared/crop.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/toolStates/Idle.mjs +2 -2
- package/dist-esm/lib/shapes/text/toolStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +1 -0
- package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -2
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +2 -0
- package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs +6 -0
- package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/SelectTool.mjs +3 -0
- package/dist-esm/lib/tools/SelectTool/SelectTool.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs +1 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/Crop.mjs +1 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/Crop.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +1 -3
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +6 -3
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +1 -1
- package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs +3 -0
- package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs +5 -1
- package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +1 -1
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +22 -31
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs +1 -3
- package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +4 -1
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs +10 -0
- package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +1 -8
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +7 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Dialogs.mjs +9 -1
- package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
- package/dist-esm/lib/ui/components/EditLinkDialog.mjs +5 -5
- package/dist-esm/lib/ui/components/EditLinkDialog.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +5 -22
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs +2 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +1 -0
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +10 -8
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +20 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +8 -7
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useCommentingEnabled.mjs +2 -2
- package/dist-esm/lib/ui/hooks/useCommentingEnabled.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +12 -6
- package/src/lib/defaultExternalContentHandlers.test.ts +43 -0
- package/src/lib/defaultExternalContentHandlers.ts +38 -16
- package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +17 -0
- package/src/lib/shapes/arrow/curved-arrow.ts +2 -2
- package/src/lib/shapes/arrow/elbow/getElbowArrowInfo.tsx +5 -3
- package/src/lib/shapes/arrow/getArrowInfo.ts +2 -1
- package/src/lib/shapes/arrow/straight-arrow.ts +2 -2
- package/src/lib/shapes/arrow/toolStates/Idle.tsx +3 -4
- package/src/lib/shapes/arrow/toolStates/Pointing.tsx +10 -6
- package/src/lib/shapes/draw/DrawShapeTool.test.ts +19 -0
- package/src/lib/shapes/draw/toolStates/Drawing.ts +12 -6
- package/src/lib/shapes/frame/FrameShapeTool.test.ts +17 -0
- package/src/lib/shapes/geo/GeoShapeTool.test.ts +28 -0
- package/src/lib/shapes/geo/getGeoShapePath.ts +3 -1
- package/src/lib/shapes/geo/toolStates/Idle.ts +3 -4
- package/src/lib/shapes/geo/toolStates/Pointing.ts +2 -1
- package/src/lib/shapes/line/LineShapeTool.test.ts +30 -1
- package/src/lib/shapes/line/toolStates/Pointing.ts +6 -7
- package/src/lib/shapes/note/NoteShapeTool.test.ts +45 -0
- package/src/lib/shapes/note/NoteShapeUtil.tsx +7 -4
- package/src/lib/shapes/note/noteHelpers.ts +18 -8
- package/src/lib/shapes/note/toolStates/Pointing.ts +2 -1
- package/src/lib/shapes/shared/crop.ts +7 -1
- package/src/lib/shapes/text/TextShapeTool.test.ts +33 -0
- package/src/lib/shapes/text/toolStates/Idle.ts +2 -2
- package/src/lib/shapes/text/toolStates/Pointing.ts +3 -0
- package/src/lib/shapes/video/VideoShapeUtil.tsx +4 -2
- package/src/lib/tools/EraserTool/childStates/Erasing.ts +5 -0
- package/src/lib/tools/HandTool/childStates/OneFingerZooming.ts +10 -0
- package/src/lib/tools/SelectTool/SelectTool.ts +4 -0
- package/src/lib/tools/SelectTool/childStates/Brushing.ts +4 -0
- package/src/lib/tools/SelectTool/childStates/Crop/Crop.ts +4 -0
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +3 -4
- package/src/lib/tools/SelectTool/childStates/Idle.ts +10 -3
- package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +1 -1
- package/src/lib/tools/SelectTool/childStates/PointingCanvas.ts +4 -0
- package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +6 -1
- package/src/lib/tools/SelectTool/childStates/PointingShape.ts +4 -1
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +30 -33
- package/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts +3 -3
- package/src/lib/tools/SelectTool/childStates/Translating.ts +6 -0
- package/src/lib/tools/SelectTool/selectHelpers.ts +21 -0
- package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +3 -9
- package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +8 -2
- package/src/lib/ui/components/Dialogs.tsx +17 -1
- package/src/lib/ui/components/EditLinkDialog.tsx +8 -7
- package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +5 -23
- package/src/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.tsx +2 -0
- package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +1 -0
- package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +13 -8
- package/src/lib/ui/components/primitives/TldrawUiSlider.test.tsx +92 -0
- package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +25 -1
- package/src/lib/ui/context/actions.tsx +25 -7
- package/src/lib/ui/hooks/useCommentingEnabled.ts +5 -3
- package/src/lib/ui/version.ts +3 -3
- package/src/test/ClickManager.test.ts +18 -0
- package/src/test/Editor.test.tsx +3 -0
- package/src/test/EraserTool.test.ts +18 -2
- package/src/test/HandTool.test.ts +21 -0
- package/src/test/LaserTool.test.ts +46 -0
- package/src/test/ScribbleManager.test.ts +19 -0
- package/src/test/SelectTool.test.ts +110 -0
- package/src/test/TldrawEditor.test.tsx +18 -0
- package/src/test/VideoShapeUtil.test.tsx +126 -0
- package/src/test/actions-menu-readonly.test.tsx +37 -0
- package/src/test/commands/__snapshots__/packShapes.test.ts.snap +6 -6
- package/src/test/commands/lockShapes.test.ts +11 -0
- package/src/test/commands/packShapes.test.ts +20 -0
- package/src/test/commands/putContent.test.ts +35 -1
- package/src/test/commands/setCamera.test.ts +69 -0
- package/src/test/commands/stackShapes.test.ts +12 -0
- package/src/test/commands/updateViewportPageBounds.test.ts +8 -0
- package/src/test/cropping.test.ts +162 -0
- package/src/test/customSnapping.test.tsx +32 -0
- package/src/test/defaultHandleExternalFileContent.test.ts +86 -0
- package/src/test/drawing.test.ts +60 -1
- package/src/test/duplicate.test.ts +22 -0
- package/src/test/frames.test.ts +51 -0
- package/src/test/getShapeAtPoint.test.ts +44 -1
- package/src/test/handleDeepLink.test.tsx +15 -0
- package/src/test/minimap-wheel.test.tsx +48 -0
- package/src/test/resizing.test.ts +46 -0
- package/src/test/selection-omnibus.test.ts +50 -0
- package/src/test/spacebarPanning.test.ts +58 -0
- package/src/test/translating.test.ts +42 -0
- package/src/test/ui/AltTextEditor.test.tsx +51 -0
- package/src/test/ui/ContextMenu.test.tsx +61 -2
- package/src/test/ui/EditLinkDialog.test.tsx +77 -0
- package/src/test/ui/ImageToolbar.test.tsx +58 -0
- package/src/test/ui/StylePanel.test.tsx +33 -2
- package/src/test/ui/keyboardShortcuts.test.tsx +27 -0
- package/src/test/ui/presenceActivity.test.tsx +44 -0
- package/src/test/ui/unlockAll.test.tsx +55 -0
- package/src/test/ui-outside-editor.test.tsx +74 -0
- package/src/test/viewport-following.test.ts +29 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/tools/SelectTool/childStates/PointingHandle.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tEditor,\n\tStateNode,\n\tTLClickEventInfo,\n\tTLHandle,\n\tTLNoteShape,\n\tTLPointerEventInfo,\n\tVec,\n} from '@tldraw/editor'\nimport {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAQO;AACP,
|
|
4
|
+
"sourcesContent": ["import {\n\tEditor,\n\tStateNode,\n\tTLClickEventInfo,\n\tTLHandle,\n\tTLNoteShape,\n\tTLPointerEventInfo,\n\tVec,\n} from '@tldraw/editor'\nimport {\n\tclearArrowTargetState,\n\tupdateArrowTargetState,\n} from '../../../shapes/arrow/arrowTargetState'\nimport { getArrowBindings } from '../../../shapes/arrow/shared'\nimport {\n\tgetNoteAdjacentPositions,\n\tgetNoteShapeForAdjacentPosition,\n} from '../../../shapes/note/noteHelpers'\nimport type { NoteShapeUtil } from '../../../shapes/note/NoteShapeUtil'\nimport { getDisplayValues } from '../../../shapes/shared/getDisplayValues'\nimport { startEditingShapeWithRichText } from '../selectHelpers'\n\nexport class PointingHandle extends StateNode {\n\tstatic override id = 'pointing_handle'\n\n\tdidCtrlOnEnter = false\n\n\tinfo = {} as TLPointerEventInfo & { target: 'handle' }\n\tisDoubleClick = false\n\n\toverride onEnter(info: TLPointerEventInfo & { target: 'handle' }) {\n\t\tthis.info = info\n\t\tthis.isDoubleClick = false\n\n\t\tthis.didCtrlOnEnter = info.accelKey\n\n\t\tconst { shape } = info\n\t\tif (this.editor.isShapeOfType(shape, 'arrow')) {\n\t\t\tconst initialBindings = getArrowBindings(this.editor, shape)\n\t\t\tconst currentBinding = initialBindings[info.handle.id as 'start' | 'end']\n\t\t\tconst oppositeBinding = initialBindings[info.handle.id === 'start' ? 'end' : 'start']\n\t\t\tconst arrowTransform = this.editor.getShapePageTransform(shape.id)!\n\n\t\t\tif (currentBinding) {\n\t\t\t\tupdateArrowTargetState({\n\t\t\t\t\teditor: this.editor,\n\t\t\t\t\tpointInPageSpace: arrowTransform.applyToPoint(info.handle),\n\t\t\t\t\tarrow: shape,\n\t\t\t\t\tisPrecise: currentBinding.props.isPrecise,\n\t\t\t\t\tcurrentBinding: currentBinding,\n\t\t\t\t\toppositeBinding: oppositeBinding,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tthis.editor.setCursor({ type: 'grabbing', rotation: 0 })\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.setHintingShapes([])\n\t\t// onEnter shows the arrow's binding target; a click without a drag would leave it showing\n\t\tclearArrowTargetState(this.editor)\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t}\n\n\toverride onPointerUp() {\n\t\tconst { shape, handle } = this.info\n\n\t\tif (this.isDoubleClick) {\n\t\t\tthis.parent.transition('idle')\n\t\t\tthis.parent.getCurrent()?.handleEvent({\n\t\t\t\t...this.info,\n\t\t\t\ttype: 'click',\n\t\t\t\tname: 'double_click',\n\t\t\t\tphase: 'down',\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tif (this.editor.isShapeOfType(shape, 'note')) {\n\t\t\tconst { editor } = this\n\t\t\tconst nextNote = getNoteForAdjacentPosition(editor, shape, handle, false)\n\t\t\tif (nextNote) {\n\t\t\t\tstartEditingShapeWithRichText(editor, nextNote, { selectAll: true })\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tthis.parent.transition('idle', this.info)\n\t}\n\n\toverride onDoubleClick(info: TLClickEventInfo) {\n\t\tif (\n\t\t\tthis.editor.inputs.getShiftKey() ||\n\t\t\tinfo.phase !== 'down' ||\n\t\t\tinfo.ctrlKey ||\n\t\t\tinfo.shiftKey\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.isDoubleClick = true\n\t}\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\tconst { editor } = this\n\t\tif (editor.inputs.getIsDragging()) {\n\t\t\tif (this.didCtrlOnEnter) {\n\t\t\t\tthis.parent.transition('brushing', info)\n\t\t\t} else {\n\t\t\t\tthis.startDraggingHandle()\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onLongPress() {\n\t\tthis.startDraggingHandle()\n\t}\n\n\tprivate startDraggingHandle() {\n\t\tconst { editor } = this\n\t\tif (editor.getIsReadonly()) return\n\t\tconst { shape, handle } = this.info\n\n\t\tif (editor.isShapeOfType(shape, 'note')) {\n\t\t\tconst noteUtil = editor.getShapeUtil(shape) as NoteShapeUtil\n\t\t\tconst dv = getDisplayValues(noteUtil, shape)\n\n\t\t\tconst nextNote = getNoteForAdjacentPosition(editor, shape, handle, true)\n\t\t\tif (nextNote) {\n\t\t\t\t// Center the shape on the current pointer\n\t\t\t\tconst centeredOnPointer = editor\n\t\t\t\t\t.getPointInParentSpace(nextNote, editor.inputs.getOriginPagePoint())\n\t\t\t\t\t.sub(\n\t\t\t\t\t\tVec.Rot(\n\t\t\t\t\t\t\tnew Vec(dv.noteWidth / 2, dv.noteHeight / 2).mul(shape.props.scale),\n\t\t\t\t\t\t\tnextNote.rotation\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\teditor.updateShape({ ...nextNote, x: centeredOnPointer.x, y: centeredOnPointer.y })\n\n\t\t\t\t// Then select and begin translating the shape\n\t\t\t\teditor\n\t\t\t\t\t.setHoveredShape(nextNote.id) // important!\n\t\t\t\t\t.select(nextNote.id)\n\t\t\t\t\t.setCurrentTool('select.translating', {\n\t\t\t\t\t\t...this.info,\n\t\t\t\t\t\ttarget: 'shape',\n\t\t\t\t\t\tshape: editor.getShape(nextNote),\n\t\t\t\t\t\tonInteractionEnd: 'note',\n\t\t\t\t\t\tisCreating: true,\n\t\t\t\t\t\tonCreate: () => {\n\t\t\t\t\t\t\t// When we're done, start editing it\n\t\t\t\t\t\t\tstartEditingShapeWithRichText(editor, nextNote, { selectAll: true })\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tthis.parent.transition('dragging_handle', this.info)\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.cancel()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\tthis.parent.transition('idle')\n\t}\n}\n\nfunction getNoteForAdjacentPosition(\n\teditor: Editor,\n\tshape: TLNoteShape,\n\thandle: TLHandle,\n\tforceNew: boolean\n) {\n\tconst noteUtil = editor.getShapeUtil(shape) as NoteShapeUtil\n\tconst dv = getDisplayValues(noteUtil, shape)\n\n\tconst pageTransform = editor.getShapePageTransform(shape.id)!\n\tconst pagePoint = pageTransform.point()\n\tconst pageRotation = pageTransform.rotation()\n\tconst positions = getNoteAdjacentPositions(editor, {\n\t\tpagePoint,\n\t\tpageRotation,\n\t\tgrowY: shape.props.growY * shape.props.scale,\n\t\textraHeight: 0,\n\t\tscale: shape.props.scale,\n\t\tnoteWidth: dv.noteWidth,\n\t\tnoteHeight: dv.noteHeight,\n\t})\n\tconst position = positions[handle.index]\n\tif (position) {\n\t\treturn getNoteShapeForAdjacentPosition(editor, {\n\t\t\tshape,\n\t\t\tcenter: position,\n\t\t\tpageRotation,\n\t\t\tnoteWidth: dv.noteWidth,\n\t\t\tnoteHeight: dv.noteHeight,\n\t\t\tforceNew,\n\t\t})\n\t}\n\treturn undefined\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -71,7 +71,7 @@ class PointingShape extends import_editor.StateNode {
|
|
|
71
71
|
const selectedShapeIds = this.editor.getSelectedShapeIds();
|
|
72
72
|
const focusedGroupId = this.editor.getFocusedGroupId();
|
|
73
73
|
const currentPagePoint = this.editor.inputs.getCurrentPagePoint();
|
|
74
|
-
const additiveSelectionKey = info.shiftKey || info.accelKey;
|
|
74
|
+
const additiveSelectionKey = (info.shiftKey || info.accelKey) && !info.altKey;
|
|
75
75
|
const hitShape = this.editor.getShapeAtPoint(currentPagePoint, {
|
|
76
76
|
margin: this.editor.getHitTestMargin(),
|
|
77
77
|
hitInside: true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/tools/SelectTool/childStates/PointingShape.ts"],
|
|
4
|
-
"sourcesContent": ["import { StateNode, TLClickEventInfo, TLPointerEventInfo, TLShape } from '@tldraw/editor'\nimport { isOverArrowLabel } from '../../../shapes/arrow/arrowLabel'\nimport { getTextLabels } from '../../../utils/shapes/shapes'\n\nexport class PointingShape extends StateNode {\n\tstatic override id = 'pointing_shape'\n\n\thitShape = {} as TLShape\n\thitShapeForPointerUp = {} as TLShape\n\tisDoubleClick = false\n\n\tdidCtrlOnEnter = false\n\tdidSelectOnEnter = false\n\n\toverride onEnter(info: TLPointerEventInfo & { target: 'shape' }) {\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tconst selectionBounds = this.editor.getSelectionRotatedPageBounds()\n\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\t\tconst { shiftKey, altKey, accelKey } = info\n\n\t\tthis.hitShape = info.shape\n\t\tthis.isDoubleClick = false\n\t\tthis.didCtrlOnEnter = accelKey\n\t\tconst outermostSelectingShape = this.editor.getOutermostSelectableShape(info.shape)\n\t\tconst selectedAncestor = this.editor.findShapeAncestor(outermostSelectingShape, (parent) =>\n\t\t\tselectedShapeIds.includes(parent.id)\n\t\t)\n\n\t\tif (\n\t\t\tthis.didCtrlOnEnter ||\n\t\t\t// If the shape has an onClick handler\n\t\t\tthis.editor.getShapeUtil(info.shape).onClick ||\n\t\t\t// ...or if the shape is the focused layer (e.g. group)\n\t\t\toutermostSelectingShape.id === focusedGroupId ||\n\t\t\t// ...or if the shape is within the selection\n\t\t\tselectedShapeIds.includes(outermostSelectingShape.id) ||\n\t\t\t// ...or if an ancestor of the shape is selected\n\t\t\tselectedAncestor ||\n\t\t\t// ...or if the current point is NOT within the selection bounds\n\t\t\t(selectedShapeIds.length > 1 && selectionBounds?.containsPoint(currentPagePoint))\n\t\t) {\n\t\t\t// We won't select the shape on enter, though we might select it on pointer up!\n\t\t\tthis.didSelectOnEnter = false\n\t\t\tthis.hitShapeForPointerUp = outermostSelectingShape\n\t\t\treturn\n\t\t}\n\n\t\tthis.didSelectOnEnter = true\n\n\t\tif (shiftKey && !altKey) {\n\t\t\tthis.editor.cancelDoubleClick()\n\t\t\tif (!selectedShapeIds.includes(outermostSelectingShape.id)) {\n\t\t\t\tthis.editor.markHistoryStoppingPoint('shift selecting shape')\n\t\t\t\tthis.editor.setSelectedShapes([...selectedShapeIds, outermostSelectingShape.id])\n\t\t\t}\n\t\t} else {\n\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\tthis.editor.setSelectedShapes([outermostSelectingShape.id])\n\t\t}\n\t}\n\n\toverride onPointerUp(info: TLPointerEventInfo) {\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\n\t\tconst additiveSelectionKey = info.shiftKey || info.accelKey\n\n\t\tconst hitShape =\n\t\t\tthis.editor.getShapeAtPoint(currentPagePoint, {\n\t\t\t\tmargin: this.editor.getHitTestMargin(),\n\t\t\t\thitInside: true,\n\t\t\t\trenderingOnly: true,\n\t\t\t}) ?? this.hitShape\n\n\t\t// The hit shape may have been deleted between pointer down and pointer up\n\t\t// (e.g. by a remote user or an undo), in which case the fallback hitShape\n\t\t// is stale. Bail to idle so we don't dereference a missing shape.\n\t\tif (!this.editor.getShape(hitShape.id)) {\n\t\t\tthis.parent.transition('idle', info)\n\t\t\treturn\n\t\t}\n\n\t\tconst selectingShape = hitShape\n\t\t\t? this.editor.getOutermostSelectableShape(hitShape)\n\t\t\t: this.hitShapeForPointerUp\n\n\t\tif (selectingShape) {\n\t\t\t// If the selecting shape has a click handler, call it instead of selecting the shape\n\t\t\tconst util = this.editor.getShapeUtil(selectingShape)\n\t\t\tif (util.onClick) {\n\t\t\t\tconst change = util.onClick?.(selectingShape)\n\t\t\t\tif (change) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('shape on click')\n\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\tthis.parent.transition('idle', info)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (selectingShape.id === focusedGroupId) {\n\t\t\t\tif (selectedShapeIds.length > 0) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('clearing shape ids')\n\t\t\t\t\tthis.editor.setSelectedShapes([])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t\t}\n\t\t\t\tthis.parent.transition('idle', info)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (!this.didSelectOnEnter) {\n\t\t\t// if the shape has an ancestor which is a focusable layer and it is not focused but it is selected\n\t\t\t// then we should focus the layer and select the shape\n\n\t\t\tconst outermostSelectableShape = this.editor.getOutermostSelectableShape(\n\t\t\t\thitShape,\n\t\t\t\t// if a group is selected, we want to stop before reaching that group\n\t\t\t\t// so we can drill down into the group\n\t\t\t\t(parent) => !selectedShapeIds.includes(parent.id)\n\t\t\t)\n\n\t\t\t// If the outermost shape is selected, then either select or deselect the SELECTING shape\n\t\t\tif (selectedShapeIds.includes(outermostSelectableShape.id)) {\n\t\t\t\t// same shape, so deselect it if shift is pressed, otherwise deselect all others\n\t\t\t\tif (additiveSelectionKey) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('deselecting on pointer up')\n\t\t\t\t\tthis.editor.deselect(selectingShape)\n\t\t\t\t} else {\n\t\t\t\t\tif (selectedShapeIds.includes(selectingShape.id)) {\n\t\t\t\t\t\t// todo\n\t\t\t\t\t\t// if the shape is editable and we're inside of an editable part of that shape, e.g. the label of a geo shape,\n\t\t\t\t\t\t// then we would want to begin editing the shape. At the moment we're relying on the shape label's onPointerUp\n\t\t\t\t\t\t// handler to do this logic, and prevent the regular pointer up event, so we won't be here in that case.\n\n\t\t\t\t\t\t// if the shape has a text label, and we're inside of the label, then we want to begin editing the label.\n\t\t\t\t\t\tif (selectedShapeIds.length === 1) {\n\t\t\t\t\t\t\tconst geometry = this.editor.getShapeUtil(selectingShape).getGeometry(selectingShape)\n\t\t\t\t\t\t\tconst textLabels = getTextLabels(geometry)\n\t\t\t\t\t\t\tconst textLabel = textLabels.length === 1 ? textLabels[0] : undefined\n\t\t\t\t\t\t\t// N.B. we're only interested if there is exactly one text label. We don't handle the\n\t\t\t\t\t\t\t// case if there's potentially more than one text label at the moment.\n\t\t\t\t\t\t\tif (textLabel) {\n\t\t\t\t\t\t\t\tconst pointInShapeSpace = this.editor.getPointInShapeSpace(\n\t\t\t\t\t\t\t\t\tselectingShape,\n\t\t\t\t\t\t\t\t\tcurrentPagePoint\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\ttextLabel.bounds.containsPoint(pointInShapeSpace, 0) &&\n\t\t\t\t\t\t\t\t\ttextLabel.hitTestPoint(pointInShapeSpace)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tthis.editor.run(() => {\n\t\t\t\t\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('editing on pointer up')\n\t\t\t\t\t\t\t\t\t\tthis.editor.select(selectingShape.id)\n\n\t\t\t\t\t\t\t\t\t\tif (!this.editor.canEditShape(selectingShape)) return\n\t\t\t\t\t\t\t\t\t\tthis.editor.setEditingShape(selectingShape.id)\n\t\t\t\t\t\t\t\t\t\tthis.editor.setCurrentTool('select.editing_shape')\n\n\t\t\t\t\t\t\t\t\t\tif (this.isDoubleClick) {\n\t\t\t\t\t\t\t\t\t\t\tthis.editor.emit('select-all-text', { shapeId: selectingShape.id })\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tthis.editor.emit('place-caret', {\n\t\t\t\t\t\t\t\t\t\t\t\tshapeId: selectingShape.id,\n\t\t\t\t\t\t\t\t\t\t\t\tpoint: info.point,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We just want to select the single shape from the selection\n\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t\t\tthis.editor.select(selectingShape.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t\t\tthis.editor.select(selectingShape)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (additiveSelectionKey) {\n\t\t\t\t// Different shape, so we are drilling down into a group with shift key held.\n\t\t\t\t// Deselect any ancestors and add the target shape to the selection\n\t\t\t\tconst ancestors = this.editor.getShapeAncestors(outermostSelectableShape)\n\n\t\t\t\tthis.editor.markHistoryStoppingPoint('shift deselecting on pointer up')\n\t\t\t\tthis.editor.setSelectedShapes([\n\t\t\t\t\t...this.editor.getSelectedShapeIds().filter((id) => !ancestors.find((a) => a.id === id)),\n\t\t\t\t\toutermostSelectableShape.id,\n\t\t\t\t])\n\t\t\t} else {\n\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t// different shape and we are drilling down, but no shift held so just select it straight up\n\t\t\t\tthis.editor.setSelectedShapes([outermostSelectableShape.id])\n\t\t\t}\n\t\t}\n\n\t\tthis.parent.transition('idle', info)\n\t}\n\n\toverride onDoubleClick(info: TLClickEventInfo) {\n\t\tthis.isDoubleClick = true\n\n\t\tif (\n\t\t\tthis.editor.inputs.getShiftKey() ||\n\t\t\tinfo.phase !== 'down' ||\n\t\t\tinfo.ctrlKey ||\n\t\t\tinfo.shiftKey\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tconst { shape: _shape, ...canvasInfo } = info as TLClickEventInfo & { target: 'shape' }\n\t\tthis.parent.transition('idle')\n\t\tthis.parent.getCurrent()?.handleEvent({\n\t\t\t...canvasInfo,\n\t\t\ttarget: 'canvas',\n\t\t})\n\t}\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\tif (isOverArrowLabel(this.editor, this.hitShape)) {\n\t\t\t\t// We're moving the label on a shape.\n\t\t\t\tthis.parent.transition('pointing_arrow_label', { ...info, shape: this.hitShape })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (this.didCtrlOnEnter) {\n\t\t\t\tthis.parent.transition('brushing', info)\n\t\t\t} else {\n\t\t\t\tthis.startTranslating(info)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onLongPress(info: TLPointerEventInfo) {\n\t\tthis.startTranslating(info)\n\t}\n\n\tprivate startTranslating(info: TLPointerEventInfo) {\n\t\tif (this.editor.getIsReadonly()) return\n\n\t\t// If we didn't select the shape on enter (e.g. because it has an onClick handler),\n\t\t// and there's no current selection, select it now before transitioning to translating.\n\t\tif (!this.didSelectOnEnter && !this.editor.getSelectedShapeIds().length) {\n\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\tthis.editor.setSelectedShapes([this.hitShapeForPointerUp.id])\n\t\t}\n\n\t\t// Re-focus the editor, just in case the text label of the shape has stolen focus\n\t\tthis.editor.focus()\n\t\tthis.parent.transition('translating', info)\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\toverride onComplete() {\n\t\tthis.cancel()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\tthis.parent.transition('idle')\n\t}\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAyE;AACzE,wBAAiC;AACjC,oBAA8B;AAEvB,MAAM,sBAAsB,wBAAU;AAAA,EAC5C,OAAgB,KAAK;AAAA,EAErB,WAAW,CAAC;AAAA,EACZ,uBAAuB,CAAC;AAAA,EACxB,gBAAgB;AAAA,EAEhB,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EAEV,QAAQ,MAAgD;AAChE,UAAM,mBAAmB,KAAK,OAAO,oBAAoB;AACzD,UAAM,kBAAkB,KAAK,OAAO,8BAA8B;AAClE,UAAM,iBAAiB,KAAK,OAAO,kBAAkB;AACrD,UAAM,mBAAmB,KAAK,OAAO,OAAO,oBAAoB;AAChE,UAAM,EAAE,UAAU,QAAQ,SAAS,IAAI;AAEvC,SAAK,WAAW,KAAK;AACrB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,UAAM,0BAA0B,KAAK,OAAO,4BAA4B,KAAK,KAAK;AAClF,UAAM,mBAAmB,KAAK,OAAO;AAAA,MAAkB;AAAA,MAAyB,CAAC,WAChF,iBAAiB,SAAS,OAAO,EAAE;AAAA,IACpC;AAEA,QACC,KAAK;AAAA,IAEL,KAAK,OAAO,aAAa,KAAK,KAAK,EAAE;AAAA,IAErC,wBAAwB,OAAO;AAAA,IAE/B,iBAAiB,SAAS,wBAAwB,EAAE;AAAA,IAEpD;AAAA,IAEC,iBAAiB,SAAS,KAAK,iBAAiB,cAAc,gBAAgB,GAC9E;AAED,WAAK,mBAAmB;AACxB,WAAK,uBAAuB;AAC5B;AAAA,IACD;AAEA,SAAK,mBAAmB;AAExB,QAAI,YAAY,CAAC,QAAQ;AACxB,WAAK,OAAO,kBAAkB;AAC9B,UAAI,CAAC,iBAAiB,SAAS,wBAAwB,EAAE,GAAG;AAC3D,aAAK,OAAO,yBAAyB,uBAAuB;AAC5D,aAAK,OAAO,kBAAkB,CAAC,GAAG,kBAAkB,wBAAwB,EAAE,CAAC;AAAA,MAChF;AAAA,IACD,OAAO;AACN,WAAK,OAAO,yBAAyB,iBAAiB;AACtD,WAAK,OAAO,kBAAkB,CAAC,wBAAwB,EAAE,CAAC;AAAA,IAC3D;AAAA,EACD;AAAA,EAES,YAAY,MAA0B;AAC9C,UAAM,mBAAmB,KAAK,OAAO,oBAAoB;AACzD,UAAM,iBAAiB,KAAK,OAAO,kBAAkB;AACrD,UAAM,mBAAmB,KAAK,OAAO,OAAO,oBAAoB;
|
|
4
|
+
"sourcesContent": ["import { StateNode, TLClickEventInfo, TLPointerEventInfo, TLShape } from '@tldraw/editor'\nimport { isOverArrowLabel } from '../../../shapes/arrow/arrowLabel'\nimport { getTextLabels } from '../../../utils/shapes/shapes'\n\nexport class PointingShape extends StateNode {\n\tstatic override id = 'pointing_shape'\n\n\thitShape = {} as TLShape\n\thitShapeForPointerUp = {} as TLShape\n\tisDoubleClick = false\n\n\tdidCtrlOnEnter = false\n\tdidSelectOnEnter = false\n\n\toverride onEnter(info: TLPointerEventInfo & { target: 'shape' }) {\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tconst selectionBounds = this.editor.getSelectionRotatedPageBounds()\n\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\t\tconst { shiftKey, altKey, accelKey } = info\n\n\t\tthis.hitShape = info.shape\n\t\tthis.isDoubleClick = false\n\t\tthis.didCtrlOnEnter = accelKey\n\t\tconst outermostSelectingShape = this.editor.getOutermostSelectableShape(info.shape)\n\t\tconst selectedAncestor = this.editor.findShapeAncestor(outermostSelectingShape, (parent) =>\n\t\t\tselectedShapeIds.includes(parent.id)\n\t\t)\n\n\t\tif (\n\t\t\tthis.didCtrlOnEnter ||\n\t\t\t// If the shape has an onClick handler\n\t\t\tthis.editor.getShapeUtil(info.shape).onClick ||\n\t\t\t// ...or if the shape is the focused layer (e.g. group)\n\t\t\toutermostSelectingShape.id === focusedGroupId ||\n\t\t\t// ...or if the shape is within the selection\n\t\t\tselectedShapeIds.includes(outermostSelectingShape.id) ||\n\t\t\t// ...or if an ancestor of the shape is selected\n\t\t\tselectedAncestor ||\n\t\t\t// ...or if the current point is NOT within the selection bounds\n\t\t\t(selectedShapeIds.length > 1 && selectionBounds?.containsPoint(currentPagePoint))\n\t\t) {\n\t\t\t// We won't select the shape on enter, though we might select it on pointer up!\n\t\t\tthis.didSelectOnEnter = false\n\t\t\tthis.hitShapeForPointerUp = outermostSelectingShape\n\t\t\treturn\n\t\t}\n\n\t\tthis.didSelectOnEnter = true\n\n\t\tif (shiftKey && !altKey) {\n\t\t\tthis.editor.cancelDoubleClick()\n\t\t\tif (!selectedShapeIds.includes(outermostSelectingShape.id)) {\n\t\t\t\tthis.editor.markHistoryStoppingPoint('shift selecting shape')\n\t\t\t\tthis.editor.setSelectedShapes([...selectedShapeIds, outermostSelectingShape.id])\n\t\t\t}\n\t\t} else {\n\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\tthis.editor.setSelectedShapes([outermostSelectingShape.id])\n\t\t}\n\t}\n\n\toverride onPointerUp(info: TLPointerEventInfo) {\n\t\tconst selectedShapeIds = this.editor.getSelectedShapeIds()\n\t\tconst focusedGroupId = this.editor.getFocusedGroupId()\n\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\n\t\t// Alt suppresses additive selection here as it does on enter and in\n\t\t// selectOnCanvasPointerUp; otherwise shift+alt or ctrl+alt releasing over\n\t\t// a selected shape would toggle it out of the selection.\n\t\tconst additiveSelectionKey = (info.shiftKey || info.accelKey) && !info.altKey\n\n\t\tconst hitShape =\n\t\t\tthis.editor.getShapeAtPoint(currentPagePoint, {\n\t\t\t\tmargin: this.editor.getHitTestMargin(),\n\t\t\t\thitInside: true,\n\t\t\t\trenderingOnly: true,\n\t\t\t}) ?? this.hitShape\n\n\t\t// The hit shape may have been deleted between pointer down and pointer up\n\t\t// (e.g. by a remote user or an undo), in which case the fallback hitShape\n\t\t// is stale. Bail to idle so we don't dereference a missing shape.\n\t\tif (!this.editor.getShape(hitShape.id)) {\n\t\t\tthis.parent.transition('idle', info)\n\t\t\treturn\n\t\t}\n\n\t\tconst selectingShape = hitShape\n\t\t\t? this.editor.getOutermostSelectableShape(hitShape)\n\t\t\t: this.hitShapeForPointerUp\n\n\t\tif (selectingShape) {\n\t\t\t// If the selecting shape has a click handler, call it instead of selecting the shape\n\t\t\tconst util = this.editor.getShapeUtil(selectingShape)\n\t\t\tif (util.onClick) {\n\t\t\t\tconst change = util.onClick?.(selectingShape)\n\t\t\t\tif (change) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('shape on click')\n\t\t\t\t\tthis.editor.updateShapes([change])\n\t\t\t\t\tthis.parent.transition('idle', info)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (selectingShape.id === focusedGroupId) {\n\t\t\t\tif (selectedShapeIds.length > 0) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('clearing shape ids')\n\t\t\t\t\tthis.editor.setSelectedShapes([])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.popFocusedGroupId()\n\t\t\t\t}\n\t\t\t\tthis.parent.transition('idle', info)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (!this.didSelectOnEnter) {\n\t\t\t// if the shape has an ancestor which is a focusable layer and it is not focused but it is selected\n\t\t\t// then we should focus the layer and select the shape\n\n\t\t\tconst outermostSelectableShape = this.editor.getOutermostSelectableShape(\n\t\t\t\thitShape,\n\t\t\t\t// if a group is selected, we want to stop before reaching that group\n\t\t\t\t// so we can drill down into the group\n\t\t\t\t(parent) => !selectedShapeIds.includes(parent.id)\n\t\t\t)\n\n\t\t\t// If the outermost shape is selected, then either select or deselect the SELECTING shape\n\t\t\tif (selectedShapeIds.includes(outermostSelectableShape.id)) {\n\t\t\t\t// same shape, so deselect it if shift is pressed, otherwise deselect all others\n\t\t\t\tif (additiveSelectionKey) {\n\t\t\t\t\tthis.editor.markHistoryStoppingPoint('deselecting on pointer up')\n\t\t\t\t\tthis.editor.deselect(selectingShape)\n\t\t\t\t} else {\n\t\t\t\t\tif (selectedShapeIds.includes(selectingShape.id)) {\n\t\t\t\t\t\t// todo\n\t\t\t\t\t\t// if the shape is editable and we're inside of an editable part of that shape, e.g. the label of a geo shape,\n\t\t\t\t\t\t// then we would want to begin editing the shape. At the moment we're relying on the shape label's onPointerUp\n\t\t\t\t\t\t// handler to do this logic, and prevent the regular pointer up event, so we won't be here in that case.\n\n\t\t\t\t\t\t// if the shape has a text label, and we're inside of the label, then we want to begin editing the label.\n\t\t\t\t\t\tif (selectedShapeIds.length === 1) {\n\t\t\t\t\t\t\tconst geometry = this.editor.getShapeUtil(selectingShape).getGeometry(selectingShape)\n\t\t\t\t\t\t\tconst textLabels = getTextLabels(geometry)\n\t\t\t\t\t\t\tconst textLabel = textLabels.length === 1 ? textLabels[0] : undefined\n\t\t\t\t\t\t\t// N.B. we're only interested if there is exactly one text label. We don't handle the\n\t\t\t\t\t\t\t// case if there's potentially more than one text label at the moment.\n\t\t\t\t\t\t\tif (textLabel) {\n\t\t\t\t\t\t\t\tconst pointInShapeSpace = this.editor.getPointInShapeSpace(\n\t\t\t\t\t\t\t\t\tselectingShape,\n\t\t\t\t\t\t\t\t\tcurrentPagePoint\n\t\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\ttextLabel.bounds.containsPoint(pointInShapeSpace, 0) &&\n\t\t\t\t\t\t\t\t\ttextLabel.hitTestPoint(pointInShapeSpace)\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tthis.editor.run(() => {\n\t\t\t\t\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('editing on pointer up')\n\t\t\t\t\t\t\t\t\t\tthis.editor.select(selectingShape.id)\n\n\t\t\t\t\t\t\t\t\t\tif (!this.editor.canEditShape(selectingShape)) return\n\t\t\t\t\t\t\t\t\t\tthis.editor.setEditingShape(selectingShape.id)\n\t\t\t\t\t\t\t\t\t\tthis.editor.setCurrentTool('select.editing_shape')\n\n\t\t\t\t\t\t\t\t\t\tif (this.isDoubleClick) {\n\t\t\t\t\t\t\t\t\t\t\tthis.editor.emit('select-all-text', { shapeId: selectingShape.id })\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tthis.editor.emit('place-caret', {\n\t\t\t\t\t\t\t\t\t\t\t\tshapeId: selectingShape.id,\n\t\t\t\t\t\t\t\t\t\t\t\tpoint: info.point,\n\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// We just want to select the single shape from the selection\n\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t\t\tthis.editor.select(selectingShape.id)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t\t\tthis.editor.select(selectingShape)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (additiveSelectionKey) {\n\t\t\t\t// Different shape, so we are drilling down into a group with shift key held.\n\t\t\t\t// Deselect any ancestors and add the target shape to the selection\n\t\t\t\tconst ancestors = this.editor.getShapeAncestors(outermostSelectableShape)\n\n\t\t\t\tthis.editor.markHistoryStoppingPoint('shift deselecting on pointer up')\n\t\t\t\tthis.editor.setSelectedShapes([\n\t\t\t\t\t...this.editor.getSelectedShapeIds().filter((id) => !ancestors.find((a) => a.id === id)),\n\t\t\t\t\toutermostSelectableShape.id,\n\t\t\t\t])\n\t\t\t} else {\n\t\t\t\tthis.editor.markHistoryStoppingPoint('selecting on pointer up')\n\t\t\t\t// different shape and we are drilling down, but no shift held so just select it straight up\n\t\t\t\tthis.editor.setSelectedShapes([outermostSelectableShape.id])\n\t\t\t}\n\t\t}\n\n\t\tthis.parent.transition('idle', info)\n\t}\n\n\toverride onDoubleClick(info: TLClickEventInfo) {\n\t\tthis.isDoubleClick = true\n\n\t\tif (\n\t\t\tthis.editor.inputs.getShiftKey() ||\n\t\t\tinfo.phase !== 'down' ||\n\t\t\tinfo.ctrlKey ||\n\t\t\tinfo.shiftKey\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tconst { shape: _shape, ...canvasInfo } = info as TLClickEventInfo & { target: 'shape' }\n\t\tthis.parent.transition('idle')\n\t\tthis.parent.getCurrent()?.handleEvent({\n\t\t\t...canvasInfo,\n\t\t\ttarget: 'canvas',\n\t\t})\n\t}\n\n\toverride onPointerMove(info: TLPointerEventInfo) {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\tif (isOverArrowLabel(this.editor, this.hitShape)) {\n\t\t\t\t// We're moving the label on a shape.\n\t\t\t\tthis.parent.transition('pointing_arrow_label', { ...info, shape: this.hitShape })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (this.didCtrlOnEnter) {\n\t\t\t\tthis.parent.transition('brushing', info)\n\t\t\t} else {\n\t\t\t\tthis.startTranslating(info)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onLongPress(info: TLPointerEventInfo) {\n\t\tthis.startTranslating(info)\n\t}\n\n\tprivate startTranslating(info: TLPointerEventInfo) {\n\t\tif (this.editor.getIsReadonly()) return\n\n\t\t// If we didn't select the shape on enter (e.g. because it has an onClick handler),\n\t\t// and there's no current selection, select it now before transitioning to translating.\n\t\tif (!this.didSelectOnEnter && !this.editor.getSelectedShapeIds().length) {\n\t\t\tthis.editor.markHistoryStoppingPoint('selecting shape')\n\t\t\tthis.editor.setSelectedShapes([this.hitShapeForPointerUp.id])\n\t\t}\n\n\t\t// Re-focus the editor, just in case the text label of the shape has stolen focus\n\t\tthis.editor.focus()\n\t\tthis.parent.transition('translating', info)\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\toverride onComplete() {\n\t\tthis.cancel()\n\t}\n\n\toverride onInterrupt() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\tthis.parent.transition('idle')\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -18,8 +18,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var Resizing_exports = {};
|
|
20
20
|
__export(Resizing_exports, {
|
|
21
|
-
Resizing: () => Resizing
|
|
22
|
-
rotateSelectionHandle: () => rotateSelectionHandle
|
|
21
|
+
Resizing: () => Resizing
|
|
23
22
|
});
|
|
24
23
|
module.exports = __toCommonJS(Resizing_exports);
|
|
25
24
|
var import_editor = require("@tldraw/editor");
|
|
@@ -32,6 +31,8 @@ class Resizing extends import_editor.StateNode {
|
|
|
32
31
|
markId = "";
|
|
33
32
|
// A switch to detect when the user is holding ctrl
|
|
34
33
|
didHoldCommand = false;
|
|
34
|
+
// Set by complete() and cancel(); see onExit for what happens when neither ran
|
|
35
|
+
didFinish = false;
|
|
35
36
|
// we transition into the resizing state from the geo pointing state, which starts with a shape of size w: 1, h: 1,
|
|
36
37
|
// so if the user drags x: +50, y: +50 after mouseDown, the shape will be w: 51, h: 51, which is too many pixels, alas
|
|
37
38
|
// so we allow passing a further offset into this state to negate such issues
|
|
@@ -41,6 +42,7 @@ class Resizing extends import_editor.StateNode {
|
|
|
41
42
|
const { isCreating = false, creatingMarkId, creationCursorOffset = { x: 0, y: 0 } } = info;
|
|
42
43
|
this.info = info;
|
|
43
44
|
this.didHoldCommand = false;
|
|
45
|
+
this.didFinish = false;
|
|
44
46
|
if (typeof info.onInteractionEnd === "string") {
|
|
45
47
|
this.parent.setCurrentToolIdMask(info.onInteractionEnd);
|
|
46
48
|
}
|
|
@@ -97,11 +99,13 @@ class Resizing extends import_editor.StateNode {
|
|
|
97
99
|
this.cancel();
|
|
98
100
|
}
|
|
99
101
|
cancel() {
|
|
102
|
+
this.didFinish = true;
|
|
100
103
|
const { shapeSnapshots } = this.snapshot;
|
|
101
104
|
shapeSnapshots.forEach(({ shape }) => {
|
|
102
105
|
const current = this.editor.getShape(shape.id);
|
|
103
106
|
if (current) {
|
|
104
107
|
const util = this.editor.getShapeUtil(shape);
|
|
108
|
+
if (!util.canResize(shape)) return;
|
|
105
109
|
util.onResizeCancel?.(shape, current);
|
|
106
110
|
}
|
|
107
111
|
});
|
|
@@ -118,6 +122,7 @@ class Resizing extends import_editor.StateNode {
|
|
|
118
122
|
this.parent.transition("idle");
|
|
119
123
|
}
|
|
120
124
|
complete() {
|
|
125
|
+
this.didFinish = true;
|
|
121
126
|
(0, import_editor.kickoutOccludedShapes)(this.editor, this.snapshot.selectedShapeIds);
|
|
122
127
|
this.handleResizeEnd();
|
|
123
128
|
if (this.info.isCreating && this.info.onCreate) {
|
|
@@ -143,6 +148,7 @@ class Resizing extends import_editor.StateNode {
|
|
|
143
148
|
const changes = [];
|
|
144
149
|
shapeSnapshots.forEach(({ shape }) => {
|
|
145
150
|
const util = this.editor.getShapeUtil(shape);
|
|
151
|
+
if (!util.canResize(shape)) return;
|
|
146
152
|
const change = util.onResizeStart?.(shape);
|
|
147
153
|
if (change) {
|
|
148
154
|
changes.push(change);
|
|
@@ -158,6 +164,7 @@ class Resizing extends import_editor.StateNode {
|
|
|
158
164
|
shapeSnapshots.forEach(({ shape }) => {
|
|
159
165
|
const current = this.editor.getShape(shape.id);
|
|
160
166
|
const util = this.editor.getShapeUtil(shape);
|
|
167
|
+
if (!util.canResize(shape)) return;
|
|
161
168
|
const change = util.onResizeEnd?.(shape, current);
|
|
162
169
|
if (change) {
|
|
163
170
|
changes.push(change);
|
|
@@ -200,14 +207,14 @@ class Resizing extends import_editor.StateNode {
|
|
|
200
207
|
currentPagePoint.snapToGrid(gridSize);
|
|
201
208
|
}
|
|
202
209
|
const dragHandle = info.handle;
|
|
203
|
-
const scaleOriginHandle = rotateSelectionHandle(dragHandle, Math.PI);
|
|
210
|
+
const scaleOriginHandle = (0, import_editor.rotateSelectionHandle)(dragHandle, Math.PI);
|
|
204
211
|
editor.snaps.clearIndicators();
|
|
205
212
|
const shouldSnap = editor.user.getIsSnapMode() ? !isHoldingAccel : isHoldingAccel;
|
|
206
213
|
if (shouldSnap && selectionRotation % import_editor.HALF_PI === 0) {
|
|
207
214
|
const { nudge } = editor.snaps.shapeBounds.snapResizeShapes({
|
|
208
215
|
dragDelta: import_editor.Vec.Sub(currentPagePoint, originPagePoint),
|
|
209
216
|
initialSelectionPageBounds,
|
|
210
|
-
handle: rotateSelectionHandle(dragHandle, selectionRotation),
|
|
217
|
+
handle: (0, import_editor.rotateSelectionHandle)(dragHandle, selectionRotation),
|
|
211
218
|
isAspectRatioLocked,
|
|
212
219
|
isResizingFromCenter: altKey
|
|
213
220
|
});
|
|
@@ -379,6 +386,9 @@ class Resizing extends import_editor.StateNode {
|
|
|
379
386
|
if (this.info.isCreating && this.editor.getHintingShapeIds().length > 0) {
|
|
380
387
|
this.editor.setHintingShapes([]);
|
|
381
388
|
}
|
|
389
|
+
if (this.info.isCreating && !this.didFinish) {
|
|
390
|
+
this.editor.bailToMark(this.markId);
|
|
391
|
+
}
|
|
382
392
|
}
|
|
383
393
|
_createSnapshot() {
|
|
384
394
|
const { editor } = this;
|
|
@@ -399,16 +409,14 @@ class Resizing extends import_editor.StateNode {
|
|
|
399
409
|
const shape = editor.getShape(shapeId);
|
|
400
410
|
if (!shape) return false;
|
|
401
411
|
const util = editor.getShapeUtil(shape);
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
});
|
|
411
|
-
}
|
|
412
|
+
const pageTransform = editor.getShapePageTransform(shape);
|
|
413
|
+
shapeSnapshots.set(shape.id, {
|
|
414
|
+
shape,
|
|
415
|
+
bounds: editor.getShapeGeometry(shape).bounds,
|
|
416
|
+
pageTransform,
|
|
417
|
+
pageRotation: import_editor.Mat.Decompose(pageTransform).rotation,
|
|
418
|
+
isAspectRatioLocked: util.isAspectRatioLocked(shape)
|
|
419
|
+
});
|
|
412
420
|
if (editor.isShapeFrameLike(shape)) {
|
|
413
421
|
frames.push({
|
|
414
422
|
id: shape.id,
|
|
@@ -463,20 +471,4 @@ class Resizing extends import_editor.StateNode {
|
|
|
463
471
|
};
|
|
464
472
|
}
|
|
465
473
|
}
|
|
466
|
-
const ORDERED_SELECTION_HANDLES = [
|
|
467
|
-
"top",
|
|
468
|
-
"top_right",
|
|
469
|
-
"right",
|
|
470
|
-
"bottom_right",
|
|
471
|
-
"bottom",
|
|
472
|
-
"bottom_left",
|
|
473
|
-
"left",
|
|
474
|
-
"top_left"
|
|
475
|
-
];
|
|
476
|
-
function rotateSelectionHandle(handle, rotation) {
|
|
477
|
-
rotation = rotation % import_editor.PI2;
|
|
478
|
-
const numSteps = Math.round(rotation / (import_editor.PI / 4));
|
|
479
|
-
const currentIndex = ORDERED_SELECTION_HANDLES.indexOf(handle);
|
|
480
|
-
return ORDERED_SELECTION_HANDLES[(currentIndex + numSteps) % ORDERED_SELECTION_HANDLES.length];
|
|
481
|
-
}
|
|
482
474
|
//# sourceMappingURL=Resizing.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/tools/SelectTool/childStates/Resizing.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBox,\n\tHALF_PI,\n\tMat,\n\tPI,\n\tPI2,\n\tSelectionCorner,\n\tSelectionEdge,\n\tStateNode,\n\tTLPointerEventInfo,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLTickEventInfo,\n\tVec,\n\tVecLike,\n\tareAnglesCompatible,\n\tcompact,\n\tisAccelKey,\n\tisShapeId,\n\tkickoutOccludedShapes,\n} from '@tldraw/editor'\nimport { getEnclosedShapeIds } from '../../../shapes/frame/FrameShapeTool'\nimport { batchMeasureGeoLabels, setBatchLabelSizeCache } from '../../../shapes/geo/GeoShapeUtil'\n\nexport type ResizingInfo = TLPointerEventInfo & {\n\ttarget: 'selection'\n\thandle: SelectionEdge | SelectionCorner\n\tisCreating?: boolean\n\tcreatingMarkId?: string\n\tonCreate?(shape: TLShape | null): void\n\tcreationCursorOffset?: VecLike\n\tonInteractionEnd?: string | (() => void)\n}\n\nexport class Resizing extends StateNode {\n\tstatic override id = 'resizing'\n\tstatic override trackPerformance = true\n\n\tinfo = {} as ResizingInfo\n\n\tmarkId = ''\n\n\t// A switch to detect when the user is holding ctrl\n\tprivate didHoldCommand = false\n\n\t// we transition into the resizing state from the geo pointing state, which starts with a shape of size w: 1, h: 1,\n\t// so if the user drags x: +50, y: +50 after mouseDown, the shape will be w: 51, h: 51, which is too many pixels, alas\n\t// so we allow passing a further offset into this state to negate such issues\n\tcreationCursorOffset = { x: 0, y: 0 } as VecLike\n\n\tprivate snapshot = {} as any as Snapshot\n\n\toverride onEnter(info: ResizingInfo) {\n\t\tconst { isCreating = false, creatingMarkId, creationCursorOffset = { x: 0, y: 0 } } = info\n\n\t\tthis.info = info\n\t\tthis.didHoldCommand = false\n\n\t\tif (typeof info.onInteractionEnd === 'string') {\n\t\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\t}\n\t\tthis.creationCursorOffset = creationCursorOffset\n\n\t\ttry {\n\t\t\t// On rare and mysterious occasions, the user can enter the resizing state with no shapes selected\n\t\t\tthis.snapshot = this._createSnapshot()\n\t\t} catch (e) {\n\t\t\tconsole.error(e)\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\n\t\tthis.markId = ''\n\n\t\tif (isCreating) {\n\t\t\tif (creatingMarkId) {\n\t\t\t\tthis.markId = creatingMarkId\n\t\t\t} else {\n\t\t\t\t// handle legacy implicit `creating:{shapeId}` marks\n\t\t\t\tconst markId = this.editor.getMarkIdMatching(\n\t\t\t\t\t`creating:${this.editor.getOnlySelectedShapeId()}`\n\t\t\t\t)\n\t\t\t\tif (markId) {\n\t\t\t\t\tthis.markId = markId\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint('starting resizing')\n\t\t}\n\n\t\tif (isCreating) {\n\t\t\tthis.editor.setCursor({ type: 'cross', rotation: 0 })\n\t\t}\n\n\t\tthis.handleResizeStart()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onTick({ elapsed }: TLTickEventInfo) {\n\t\tconst { editor } = this\n\t\tif (!editor.inputs.getIsDragging() || editor.inputs.getIsPanning()) return\n\t\teditor.edgeScrollManager.updateEdgeScrolling(elapsed)\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.updateShapes()\n\t}\n\toverride onKeyUp() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\t// Call onResizeCancel callback before resetting\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst current = this.editor.getShape(shape.id)\n\t\t\tif (current) {\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\t\tutil.onResizeCancel?.(shape, current)\n\t\t\t}\n\t\t})\n\n\t\tthis.editor.bailToMark(this.markId)\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, {})\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate complete() {\n\t\tkickoutOccludedShapes(this.editor, this.snapshot.selectedShapeIds)\n\n\t\tthis.handleResizeEnd()\n\n\t\tif (this.info.isCreating && this.info.onCreate) {\n\t\t\tthis.info.onCreate?.(this.editor.getOnlySelectedShape())\n\t\t\treturn\n\t\t}\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, {})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate handleResizeStart() {\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onResizeStart?.(shape)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprivate handleResizeEnd() {\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst current = this.editor.getShape(shape.id)!\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tconst change = util.onResizeEnd?.(shape, current)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprivate updateShapes() {\n\t\tconst {\n\t\t\teditor,\n\t\t\tinfo,\n\t\t\tsnapshot: {\n\t\t\t\tframes,\n\t\t\t\tshapeSnapshots,\n\t\t\t\tselectionBounds,\n\t\t\t\tcursorHandleOffset,\n\t\t\t\tselectedShapeIds,\n\t\t\t\tselectionRotation,\n\t\t\t\tcanShapesDeform,\n\t\t\t\tinitialSelectionPageBounds,\n\t\t\t\tresizeLevels,\n\t\t\t},\n\t\t} = this\n\t\tconst altKey = editor.inputs.getAltKey()\n\t\tconst shiftKey = editor.inputs.getShiftKey()\n\n\t\tlet isAspectRatioLocked = shiftKey || !canShapesDeform\n\n\t\tif (shapeSnapshots.size === 1) {\n\t\t\tconst onlySnapshot = [...shapeSnapshots.values()][0]!\n\t\t\tif (editor.isShapeOfType(onlySnapshot.shape, 'text')) {\n\t\t\t\tisAspectRatioLocked = !(info.handle === 'left' || info.handle === 'right')\n\t\t\t}\n\t\t}\n\n\t\t// first negate the 'cursor handle offset'\n\t\t// we need to do this because we do grid snapping based on the page point of the handle\n\t\t// rather than the page point of the cursor, so it's easier to pretend that the cursor\n\t\t// is really where the handle actually is\n\t\t//\n\t\t// *** Massively zoomed-in diagram of the initial mouseDown ***\n\t\t//\n\t\t//\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502corner handle\n\t\t// \u250C\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2510\n\t\t// selection \u2502 \u2502\n\t\t// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 x\u25C4\u2500\u2500\u253C\u2500\u2500\u2500\u2500 drag handle point \u25B2\n\t\t// \u2502 \u2502 \u2502\n\t\t// \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u251C\u2500 cursorHandleOffset.y\n\t\t// \u2502\n\t\t// originPagePoint\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25BAx\u2500\u2510 \u25BC\n\t\t// \u2502 \u2514\u2500\u2510\n\t\t// \u2502 \u2514\u2500\u2510\n\t\t// \u2502 \u2502 mouse (sorry)\n\t\t// \u2514\u2500\u2500\u2510 \u250C\u2518\n\t\t// \u2502 \u2502\n\t\t// \u2514\u2500\u2518\n\t\t// \u25C4\u2500\u2500\u252C\u2500\u2500\u25BA\n\t\t// \u2502\n\t\t// cursorHandleOffset.x\n\n\t\tconst isHoldingAccel = isAccelKey(editor.inputs)\n\n\t\tconst currentPagePoint = editor.inputs\n\t\t\t.getCurrentPagePoint()\n\t\t\t.clone()\n\t\t\t.sub(cursorHandleOffset)\n\t\t\t.sub(this.creationCursorOffset)\n\n\t\tconst originPagePoint = editor.inputs.getOriginPagePoint().clone().sub(cursorHandleOffset)\n\n\t\tif (editor.getInstanceState().isGridMode && !isHoldingAccel) {\n\t\t\tconst { gridSize } = editor.getDocumentSettings()\n\t\t\tcurrentPagePoint.snapToGrid(gridSize)\n\t\t}\n\n\t\tconst dragHandle = info.handle as SelectionCorner | SelectionEdge\n\t\tconst scaleOriginHandle = rotateSelectionHandle(dragHandle, Math.PI)\n\n\t\teditor.snaps.clearIndicators()\n\n\t\tconst shouldSnap = editor.user.getIsSnapMode() ? !isHoldingAccel : isHoldingAccel\n\n\t\tif (shouldSnap && selectionRotation % HALF_PI === 0) {\n\t\t\tconst { nudge } = editor.snaps.shapeBounds.snapResizeShapes({\n\t\t\t\tdragDelta: Vec.Sub(currentPagePoint, originPagePoint),\n\t\t\t\tinitialSelectionPageBounds: initialSelectionPageBounds,\n\t\t\t\thandle: rotateSelectionHandle(dragHandle, selectionRotation),\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tisResizingFromCenter: altKey,\n\t\t\t})\n\n\t\t\tcurrentPagePoint.add(nudge)\n\t\t}\n\n\t\t// get the page point of the selection handle opposite to the drag handle\n\t\t// or the center of the selection box if altKey is pressed\n\t\tconst scaleOriginPage = Vec.RotWith(\n\t\t\taltKey ? selectionBounds.center : selectionBounds.getHandlePoint(scaleOriginHandle),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\t// calculate the scale by measuring the current distance between the drag handle and the scale origin\n\t\t// and dividing by the original distance between the drag handle and the scale origin\n\n\t\t// bug: for edges, the page point doesn't matter, the\n\n\t\tconst distanceFromScaleOriginNow = Vec.Sub(currentPagePoint, scaleOriginPage).rot(\n\t\t\t-selectionRotation\n\t\t)\n\n\t\tconst distanceFromScaleOriginAtStart = Vec.Sub(originPagePoint, scaleOriginPage).rot(\n\t\t\t-selectionRotation\n\t\t)\n\n\t\tconst scale = Vec.DivV(distanceFromScaleOriginNow, distanceFromScaleOriginAtStart)\n\n\t\tif (!Number.isFinite(scale.x)) scale.x = 1\n\t\tif (!Number.isFinite(scale.y)) scale.y = 1\n\n\t\tconst isXLocked = dragHandle === 'top' || dragHandle === 'bottom'\n\t\tconst isYLocked = dragHandle === 'left' || dragHandle === 'right'\n\n\t\t// lock an axis if required\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (isYLocked) {\n\t\t\t\t// holding shift and dragging either the left or the right edge\n\t\t\t\tscale.y = Math.abs(scale.x)\n\t\t\t} else if (isXLocked) {\n\t\t\t\t// holding shift and dragging either the top or the bottom edge\n\t\t\t\tscale.x = Math.abs(scale.y)\n\t\t\t} else if (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\t// holding shift and the drag has moved further in the x dimension\n\t\t\t\tscale.y = Math.abs(scale.x) * (scale.y < 0 ? -1 : 1)\n\t\t\t} else {\n\t\t\t\t// holding shift and the drag has moved further in the y dimension\n\t\t\t\tscale.x = Math.abs(scale.y) * (scale.x < 0 ? -1 : 1)\n\t\t\t}\n\t\t} else {\n\t\t\t// not holding shift, but still need to lock axes if dragging an edge\n\t\t\tif (isXLocked) {\n\t\t\t\tscale.x = 1\n\t\t\t}\n\t\t\tif (isYLocked) {\n\t\t\t\tscale.y = 1\n\t\t\t}\n\t\t}\n\n\t\tif (!this.info.isCreating) {\n\t\t\tthis.updateCursor({\n\t\t\t\tdragHandle,\n\t\t\t\tisFlippedX: scale.x < 0,\n\t\t\t\tisFlippedY: scale.y < 0,\n\t\t\t\trotation: selectionRotation,\n\t\t\t})\n\t\t}\n\n\t\t// Batch-measure geo shape labels to avoid layout thrashing (only worth it for multiple shapes).\n\t\tif (shapeSnapshots.size > 1) {\n\t\t\tbatchMeasureGeoLabels(\n\t\t\t\tthis.editor,\n\t\t\t\tshapeSnapshots,\n\t\t\t\tscale,\n\t\t\t\tselectionRotation,\n\t\t\t\tisAspectRatioLocked\n\t\t\t)\n\t\t}\n\n\t\t// Resize all shapes (onResize will use the batch cache for geo shapes when available).\n\t\t// Collect the updates for each nesting level and commit them in a single batch, so that\n\t\t// each pointer move pays the store's per-commit costs once per level rather than once per\n\t\t// shape. Shapes that are rotated out of alignment with the selection can't be expressed\n\t\t// as a single update; getResizeShapePartial resizes those immediately and returns null.\n\t\tfor (const level of resizeLevels) {\n\t\t\tconst changes: TLShapePartial[] = []\n\n\t\t\tfor (const id of level) {\n\t\t\t\tconst snapshot = shapeSnapshots.get(id)!\n\n\t\t\t\tconst change = editor.getResizeShapePartial(id, scale, {\n\t\t\t\t\tinitialShape: snapshot.shape,\n\t\t\t\t\tinitialBounds: snapshot.bounds,\n\t\t\t\t\tinitialPageTransform: snapshot.pageTransform,\n\t\t\t\t\tdragHandle,\n\t\t\t\t\tmode:\n\t\t\t\t\t\tselectedShapeIds.length === 1 && id === selectedShapeIds[0]\n\t\t\t\t\t\t\t? 'resize_bounds'\n\t\t\t\t\t\t\t: 'scale_shape',\n\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\tisAspectRatioLocked,\n\t\t\t\t\tscaleAxisRotation: selectionRotation,\n\t\t\t\t\tskipStartAndEndCallbacks: true,\n\t\t\t\t})\n\n\t\t\t\tif (change) changes.push(change)\n\t\t\t}\n\n\t\t\tif (changes.length > 0) {\n\t\t\t\teditor.updateShapes(changes)\n\t\t\t}\n\t\t}\n\n\t\t// If there's only one shape snapshot and it's a frame and the user is holding ctrl,\n\t\t// then we preserve the position of the frame's children, almost like the user is cropping\n\t\t// the frame rather than resizing it.\n\t\tif (isHoldingAccel) {\n\t\t\tthis.didHoldCommand = true\n\n\t\t\tconst childChanges: TLShapePartial[] = []\n\n\t\t\tfor (const { id, children } of frames) {\n\t\t\t\tif (!children.length) continue\n\t\t\t\tconst initial = shapeSnapshots.get(id)!.shape\n\t\t\t\tconst current = this.editor.getShape(id)!\n\t\t\t\tif (!(initial && current)) continue\n\n\t\t\t\tconst dx = current.x - initial.x\n\t\t\t\tconst dy = current.y - initial.y\n\n\t\t\t\tconst delta = new Vec(dx, dy).rot(-initial.rotation)\n\n\t\t\t\tif (delta.x !== 0 || delta.y !== 0) {\n\t\t\t\t\tfor (const child of children) {\n\t\t\t\t\t\tchildChanges.push({\n\t\t\t\t\t\t\tid: child.id,\n\t\t\t\t\t\t\ttype: child.type,\n\t\t\t\t\t\t\tx: child.x - delta.x,\n\t\t\t\t\t\t\ty: child.y - delta.y,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (childChanges.length > 0) {\n\t\t\t\tthis.editor.updateShapes(childChanges)\n\t\t\t}\n\t\t} else if (this.didHoldCommand) {\n\t\t\t// If we're no longer holding the command key...\n\t\t\tthis.didHoldCommand = false\n\n\t\t\tconst childChanges: TLShapePartial[] = []\n\n\t\t\tfor (const { children } of frames) {\n\t\t\t\tfor (const child of children) {\n\t\t\t\t\tchildChanges.push({\n\t\t\t\t\t\tid: child.id,\n\t\t\t\t\t\ttype: child.type,\n\t\t\t\t\t\tx: child.x,\n\t\t\t\t\t\ty: child.y,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (childChanges.length > 0) {\n\t\t\t\tthis.editor.updateShapes(childChanges)\n\t\t\t}\n\t\t}\n\n\t\tthis.updateEnclosureHints()\n\t}\n\n\t// While drag-creating a frame, hint the sibling shapes that would become its children on pointer up\n\tprivate updateEnclosureHints() {\n\t\tif (!this.info.isCreating) return\n\n\t\tconst shape = this.editor.getOnlySelectedShape()\n\t\tif (!shape || !this.editor.isShapeOfType(shape, 'frame')) return\n\n\t\tconst hintingShapeIds = getEnclosedShapeIds(this.editor, shape)\n\t\tconst prevHintingShapeIds = this.editor.getHintingShapeIds()\n\t\tif (\n\t\t\thintingShapeIds.length === prevHintingShapeIds.length &&\n\t\t\thintingShapeIds.every((id, i) => id === prevHintingShapeIds[i])\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.editor.setHintingShapes(hintingShapeIds)\n\t}\n\n\t// ---\n\n\tprivate updateCursor({\n\t\tdragHandle,\n\t\tisFlippedX,\n\t\tisFlippedY,\n\t\trotation,\n\t}: {\n\t\tdragHandle: SelectionCorner | SelectionEdge\n\t\tisFlippedX: boolean\n\t\tisFlippedY: boolean\n\t\trotation: number\n\t}) {\n\t\tconst prevCursor = this.editor.getInstanceState().cursor\n\t\tlet nextCursorType = prevCursor.type\n\n\t\tswitch (dragHandle) {\n\t\t\tcase 'top_left':\n\t\t\tcase 'bottom_right': {\n\t\t\t\tnextCursorType = 'nwse-resize'\n\t\t\t\tif (isFlippedX !== isFlippedY) {\n\t\t\t\t\tnextCursorType = 'nesw-resize'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'top_right':\n\t\t\tcase 'bottom_left': {\n\t\t\t\tnextCursorType = 'nesw-resize'\n\t\t\t\tif (isFlippedX !== isFlippedY) {\n\t\t\t\t\tnextCursorType = 'nwse-resize'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// this runs on every pointer move, so skip the instance state update when nothing changed\n\t\tif (nextCursorType === prevCursor.type && rotation === prevCursor.rotation) return\n\n\t\tthis.editor.setCursor({ type: nextCursorType, rotation })\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.editor.snaps.clearIndicators()\n\t\tsetBatchLabelSizeCache(this.editor, null)\n\t\tif (this.info.isCreating && this.editor.getHintingShapeIds().length > 0) {\n\t\t\tthis.editor.setHintingShapes([])\n\t\t}\n\t}\n\n\tprivate _createSnapshot() {\n\t\tconst { editor } = this\n\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\t\tconst selectionRotation = editor.getSelectionRotation()\n\t\tconst originPagePoint = editor.inputs.getOriginPagePoint()\n\n\t\tconst selectionBounds = editor.getSelectionRotatedPageBounds()\n\t\tif (!selectionBounds) throw Error('Resizing but nothing is selected')\n\n\t\tconst dragHandlePoint = Vec.RotWith(\n\t\t\tselectionBounds.getHandlePoint(this.info.handle!),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\tconst cursorHandleOffset = Vec.Sub(originPagePoint, dragHandlePoint)\n\n\t\tconst shapeSnapshots = new Map<\n\t\t\tTLShapeId,\n\t\t\t{\n\t\t\t\tshape: TLShape\n\t\t\t\tbounds: Box\n\t\t\t\tpageTransform: Mat\n\t\t\t\tpageRotation: number\n\t\t\t\tisAspectRatioLocked: boolean\n\t\t\t}\n\t\t>()\n\n\t\tconst frames: { id: TLShapeId; children: TLShape[] }[] = []\n\n\t\tconst populateResizingShapes = (shapeId: TLShapeId): false | undefined => {\n\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\tif (!shape) return false\n\n\t\t\tconst util = editor.getShapeUtil(shape)\n\n\t\t\t// If the shape can resize, add it to the resizing shapes snapshots\n\t\t\tif (util.canResize(shape)) {\n\t\t\t\tconst pageTransform = editor.getShapePageTransform(shape)!\n\t\t\t\tshapeSnapshots.set(shape.id, {\n\t\t\t\t\tshape,\n\t\t\t\t\tbounds: editor.getShapeGeometry(shape).bounds,\n\t\t\t\t\tpageTransform,\n\t\t\t\t\tpageRotation: Mat.Decompose(pageTransform).rotation,\n\t\t\t\t\tisAspectRatioLocked: util.isAspectRatioLocked(shape),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Special case:\n\t\t\t// For frames, we don't want to resize children but we DO want to get a snapshot of their children so that we can restore their\n\t\t\t// positions with the accel key behavior. We could break this further into APIs, for example by collecting snapshots of all\n\t\t\t// descendants (easy) but also flagging with behavior like \"resize\" or \"keep absolute position\" or \"reposition only with accel key\",\n\t\t\t// though I'm not sure where that would be defined; perhaps better handled with onResizeStart / onResize callbacks on the util, and\n\t\t\t// pass `accelKeyIsPressed` as well as `accelKeyWasPressed`?\n\t\t\tif (editor.isShapeFrameLike(shape)) {\n\t\t\t\tframes.push({\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\tchildren: compact(\n\t\t\t\t\t\teditor.getSortedChildIdsForParent(shape).map((id) => editor.getShape(id))\n\t\t\t\t\t),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// This will stop the traversal of descendants\n\t\t\tif (!util.canResizeChildren(shape)) return false\n\n\t\t\treturn undefined\n\t\t}\n\n\t\tselectedShapeIds.forEach((shapeId) => {\n\t\t\tconst keepDescending = populateResizingShapes(shapeId)\n\t\t\tif (keepDescending === false) return\n\t\t\teditor.visitDescendants(shapeId, populateResizingShapes)\n\t\t})\n\n\t\tconst canShapesDeform = ![...shapeSnapshots.values()].some(\n\t\t\t(shape) =>\n\t\t\t\t!areAnglesCompatible(shape.pageRotation, selectionRotation) || shape.isAspectRatioLocked\n\t\t)\n\n\t\t// Group the shapes into levels of relative nesting so that each level can be resized in a\n\t\t// single batched update. A shape whose ancestor is also resizing must commit after that\n\t\t// ancestor, because its new position is computed against the parent's current transform.\n\t\t// In the common case (no resizing shape is parented to another resizing shape) there is a\n\t\t// single level, so each pointer move commits one update for all shapes.\n\t\tconst resizeLevels: TLShapeId[][] = []\n\t\tconst levelByShapeId = new Map<TLShapeId, number>()\n\t\tconst getLevel = (id: TLShapeId): number => {\n\t\t\tconst cached = levelByShapeId.get(id)\n\t\t\tif (cached !== undefined) return cached\n\t\t\tlet level = 0\n\t\t\tlet parentId = editor.getShape(id)?.parentId\n\t\t\twhile (parentId && isShapeId(parentId)) {\n\t\t\t\tif (shapeSnapshots.has(parentId)) {\n\t\t\t\t\tlevel = getLevel(parentId) + 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tparentId = editor.getShape(parentId)?.parentId\n\t\t\t}\n\t\t\tlevelByShapeId.set(id, level)\n\t\t\treturn level\n\t\t}\n\t\tfor (const id of shapeSnapshots.keys()) {\n\t\t\tconst level = getLevel(id)\n\t\t\twhile (resizeLevels.length <= level) resizeLevels.push([])\n\t\t\tresizeLevels[level].push(id)\n\t\t}\n\n\t\treturn {\n\t\t\tshapeSnapshots,\n\t\t\tselectionBounds,\n\t\t\tcursorHandleOffset,\n\t\t\tselectionRotation,\n\t\t\tselectedShapeIds,\n\t\t\tcanShapesDeform,\n\t\t\tinitialSelectionPageBounds: this.editor.getSelectionPageBounds()!,\n\t\t\tframes,\n\t\t\tresizeLevels,\n\t\t}\n\t}\n}\n\ntype Snapshot = ReturnType<Resizing['_createSnapshot']>\n\nconst ORDERED_SELECTION_HANDLES: (SelectionEdge | SelectionCorner)[] = [\n\t'top',\n\t'top_right',\n\t'right',\n\t'bottom_right',\n\t'bottom',\n\t'bottom_left',\n\t'left',\n\t'top_left',\n]\n\nexport function rotateSelectionHandle(handle: SelectionEdge | SelectionCorner, rotation: number) {\n\t// first find out how many tau we need to rotate by\n\trotation = rotation % PI2\n\tconst numSteps = Math.round(rotation / (PI / 4))\n\n\tconst currentIndex = ORDERED_SELECTION_HANDLES.indexOf(handle)\n\treturn ORDERED_SELECTION_HANDLES[(currentIndex + numSteps) % ORDERED_SELECTION_HANDLES.length]\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n\tBox,\n\tHALF_PI,\n\tMat,\n\tSelectionCorner,\n\tSelectionEdge,\n\tStateNode,\n\tTLPointerEventInfo,\n\tTLShape,\n\tTLShapeId,\n\tTLShapePartial,\n\tTLTickEventInfo,\n\tVec,\n\tVecLike,\n\tareAnglesCompatible,\n\tcompact,\n\tisAccelKey,\n\tisShapeId,\n\tkickoutOccludedShapes,\n\trotateSelectionHandle,\n} from '@tldraw/editor'\nimport { getEnclosedShapeIds } from '../../../shapes/frame/FrameShapeTool'\nimport { batchMeasureGeoLabels, setBatchLabelSizeCache } from '../../../shapes/geo/GeoShapeUtil'\n\nexport type ResizingInfo = TLPointerEventInfo & {\n\ttarget: 'selection'\n\thandle: SelectionEdge | SelectionCorner\n\tisCreating?: boolean\n\tcreatingMarkId?: string\n\tonCreate?(shape: TLShape | null): void\n\tcreationCursorOffset?: VecLike\n\tonInteractionEnd?: string | (() => void)\n}\n\nexport class Resizing extends StateNode {\n\tstatic override id = 'resizing'\n\tstatic override trackPerformance = true\n\n\tinfo = {} as ResizingInfo\n\n\tmarkId = ''\n\n\t// A switch to detect when the user is holding ctrl\n\tprivate didHoldCommand = false\n\n\t// Set by complete() and cancel(); see onExit for what happens when neither ran\n\tprivate didFinish = false\n\n\t// we transition into the resizing state from the geo pointing state, which starts with a shape of size w: 1, h: 1,\n\t// so if the user drags x: +50, y: +50 after mouseDown, the shape will be w: 51, h: 51, which is too many pixels, alas\n\t// so we allow passing a further offset into this state to negate such issues\n\tcreationCursorOffset = { x: 0, y: 0 } as VecLike\n\n\tprivate snapshot = {} as any as Snapshot\n\n\toverride onEnter(info: ResizingInfo) {\n\t\tconst { isCreating = false, creatingMarkId, creationCursorOffset = { x: 0, y: 0 } } = info\n\n\t\tthis.info = info\n\t\tthis.didHoldCommand = false\n\t\tthis.didFinish = false\n\n\t\tif (typeof info.onInteractionEnd === 'string') {\n\t\t\tthis.parent.setCurrentToolIdMask(info.onInteractionEnd)\n\t\t}\n\t\tthis.creationCursorOffset = creationCursorOffset\n\n\t\ttry {\n\t\t\t// On rare and mysterious occasions, the user can enter the resizing state with no shapes selected\n\t\t\tthis.snapshot = this._createSnapshot()\n\t\t} catch (e) {\n\t\t\tconsole.error(e)\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\n\t\tthis.markId = ''\n\n\t\tif (isCreating) {\n\t\t\tif (creatingMarkId) {\n\t\t\t\tthis.markId = creatingMarkId\n\t\t\t} else {\n\t\t\t\t// handle legacy implicit `creating:{shapeId}` marks\n\t\t\t\tconst markId = this.editor.getMarkIdMatching(\n\t\t\t\t\t`creating:${this.editor.getOnlySelectedShapeId()}`\n\t\t\t\t)\n\t\t\t\tif (markId) {\n\t\t\t\t\tthis.markId = markId\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.markId = this.editor.markHistoryStoppingPoint('starting resizing')\n\t\t}\n\n\t\tif (isCreating) {\n\t\t\tthis.editor.setCursor({ type: 'cross', rotation: 0 })\n\t\t}\n\n\t\tthis.handleResizeStart()\n\t\tthis.updateShapes()\n\t}\n\n\toverride onTick({ elapsed }: TLTickEventInfo) {\n\t\tconst { editor } = this\n\t\tif (!editor.inputs.getIsDragging() || editor.inputs.getIsPanning()) return\n\t\teditor.edgeScrollManager.updateEdgeScrolling(elapsed)\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.updateShapes()\n\t}\n\toverride onKeyUp() {\n\t\tthis.updateShapes()\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\tprivate cancel() {\n\t\tthis.didFinish = true\n\n\t\t// Call onResizeCancel callback before resetting\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst current = this.editor.getShape(shape.id)\n\t\t\tif (current) {\n\t\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\t\tif (!util.canResize(shape)) return\n\t\t\t\tutil.onResizeCancel?.(shape, current)\n\t\t\t}\n\t\t})\n\n\t\tthis.editor.bailToMark(this.markId)\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, {})\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate complete() {\n\t\tthis.didFinish = true\n\n\t\tkickoutOccludedShapes(this.editor, this.snapshot.selectedShapeIds)\n\n\t\tthis.handleResizeEnd()\n\n\t\tif (this.info.isCreating && this.info.onCreate) {\n\t\t\tthis.info.onCreate?.(this.editor.getOnlySelectedShape())\n\t\t\treturn\n\t\t}\n\n\t\tconst { onInteractionEnd } = this.info\n\t\tif (onInteractionEnd) {\n\t\t\tif (typeof onInteractionEnd === 'string') {\n\t\t\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\t\t\tthis.editor.setCurrentTool(onInteractionEnd, {})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tonInteractionEnd()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate handleResizeStart() {\n\t\t// Non-resizable shapes are in the snapshot only to be repositioned, so they don't get the\n\t\t// resize lifecycle callbacks (matching Editor.resizeShape).\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tif (!util.canResize(shape)) return\n\t\t\tconst change = util.onResizeStart?.(shape)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprivate handleResizeEnd() {\n\t\tconst { shapeSnapshots } = this.snapshot\n\n\t\tconst changes: TLShapePartial[] = []\n\n\t\tshapeSnapshots.forEach(({ shape }) => {\n\t\t\tconst current = this.editor.getShape(shape.id)!\n\t\t\tconst util = this.editor.getShapeUtil(shape)\n\t\t\tif (!util.canResize(shape)) return\n\t\t\tconst change = util.onResizeEnd?.(shape, current)\n\t\t\tif (change) {\n\t\t\t\tchanges.push(change)\n\t\t\t}\n\t\t})\n\n\t\tif (changes.length > 0) {\n\t\t\tthis.editor.updateShapes(changes)\n\t\t}\n\t}\n\n\tprivate updateShapes() {\n\t\tconst {\n\t\t\teditor,\n\t\t\tinfo,\n\t\t\tsnapshot: {\n\t\t\t\tframes,\n\t\t\t\tshapeSnapshots,\n\t\t\t\tselectionBounds,\n\t\t\t\tcursorHandleOffset,\n\t\t\t\tselectedShapeIds,\n\t\t\t\tselectionRotation,\n\t\t\t\tcanShapesDeform,\n\t\t\t\tinitialSelectionPageBounds,\n\t\t\t\tresizeLevels,\n\t\t\t},\n\t\t} = this\n\t\tconst altKey = editor.inputs.getAltKey()\n\t\tconst shiftKey = editor.inputs.getShiftKey()\n\n\t\tlet isAspectRatioLocked = shiftKey || !canShapesDeform\n\n\t\tif (shapeSnapshots.size === 1) {\n\t\t\tconst onlySnapshot = [...shapeSnapshots.values()][0]!\n\t\t\tif (editor.isShapeOfType(onlySnapshot.shape, 'text')) {\n\t\t\t\tisAspectRatioLocked = !(info.handle === 'left' || info.handle === 'right')\n\t\t\t}\n\t\t}\n\n\t\t// first negate the 'cursor handle offset'\n\t\t// we need to do this because we do grid snapping based on the page point of the handle\n\t\t// rather than the page point of the cursor, so it's easier to pretend that the cursor\n\t\t// is really where the handle actually is\n\t\t//\n\t\t// *** Massively zoomed-in diagram of the initial mouseDown ***\n\t\t//\n\t\t//\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502\n\t\t// \u2502corner handle\n\t\t// \u250C\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2510\n\t\t// selection \u2502 \u2502\n\t\t// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524 x\u25C4\u2500\u2500\u253C\u2500\u2500\u2500\u2500 drag handle point \u25B2\n\t\t// \u2502 \u2502 \u2502\n\t\t// \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u251C\u2500 cursorHandleOffset.y\n\t\t// \u2502\n\t\t// originPagePoint\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25BAx\u2500\u2510 \u25BC\n\t\t// \u2502 \u2514\u2500\u2510\n\t\t// \u2502 \u2514\u2500\u2510\n\t\t// \u2502 \u2502 mouse (sorry)\n\t\t// \u2514\u2500\u2500\u2510 \u250C\u2518\n\t\t// \u2502 \u2502\n\t\t// \u2514\u2500\u2518\n\t\t// \u25C4\u2500\u2500\u252C\u2500\u2500\u25BA\n\t\t// \u2502\n\t\t// cursorHandleOffset.x\n\n\t\tconst isHoldingAccel = isAccelKey(editor.inputs)\n\n\t\tconst currentPagePoint = editor.inputs\n\t\t\t.getCurrentPagePoint()\n\t\t\t.clone()\n\t\t\t.sub(cursorHandleOffset)\n\t\t\t.sub(this.creationCursorOffset)\n\n\t\tconst originPagePoint = editor.inputs.getOriginPagePoint().clone().sub(cursorHandleOffset)\n\n\t\tif (editor.getInstanceState().isGridMode && !isHoldingAccel) {\n\t\t\tconst { gridSize } = editor.getDocumentSettings()\n\t\t\tcurrentPagePoint.snapToGrid(gridSize)\n\t\t}\n\n\t\tconst dragHandle = info.handle as SelectionCorner | SelectionEdge\n\t\tconst scaleOriginHandle = rotateSelectionHandle(dragHandle, Math.PI)\n\n\t\teditor.snaps.clearIndicators()\n\n\t\tconst shouldSnap = editor.user.getIsSnapMode() ? !isHoldingAccel : isHoldingAccel\n\n\t\tif (shouldSnap && selectionRotation % HALF_PI === 0) {\n\t\t\tconst { nudge } = editor.snaps.shapeBounds.snapResizeShapes({\n\t\t\t\tdragDelta: Vec.Sub(currentPagePoint, originPagePoint),\n\t\t\t\tinitialSelectionPageBounds: initialSelectionPageBounds,\n\t\t\t\thandle: rotateSelectionHandle(dragHandle, selectionRotation),\n\t\t\t\tisAspectRatioLocked,\n\t\t\t\tisResizingFromCenter: altKey,\n\t\t\t})\n\n\t\t\tcurrentPagePoint.add(nudge)\n\t\t}\n\n\t\t// get the page point of the selection handle opposite to the drag handle\n\t\t// or the center of the selection box if altKey is pressed\n\t\tconst scaleOriginPage = Vec.RotWith(\n\t\t\taltKey ? selectionBounds.center : selectionBounds.getHandlePoint(scaleOriginHandle),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\t// calculate the scale by measuring the current distance between the drag handle and the scale origin\n\t\t// and dividing by the original distance between the drag handle and the scale origin\n\n\t\t// bug: for edges, the page point doesn't matter, the\n\n\t\tconst distanceFromScaleOriginNow = Vec.Sub(currentPagePoint, scaleOriginPage).rot(\n\t\t\t-selectionRotation\n\t\t)\n\n\t\tconst distanceFromScaleOriginAtStart = Vec.Sub(originPagePoint, scaleOriginPage).rot(\n\t\t\t-selectionRotation\n\t\t)\n\n\t\tconst scale = Vec.DivV(distanceFromScaleOriginNow, distanceFromScaleOriginAtStart)\n\n\t\tif (!Number.isFinite(scale.x)) scale.x = 1\n\t\tif (!Number.isFinite(scale.y)) scale.y = 1\n\n\t\tconst isXLocked = dragHandle === 'top' || dragHandle === 'bottom'\n\t\tconst isYLocked = dragHandle === 'left' || dragHandle === 'right'\n\n\t\t// lock an axis if required\n\t\tif (isAspectRatioLocked) {\n\t\t\tif (isYLocked) {\n\t\t\t\t// holding shift and dragging either the left or the right edge\n\t\t\t\tscale.y = Math.abs(scale.x)\n\t\t\t} else if (isXLocked) {\n\t\t\t\t// holding shift and dragging either the top or the bottom edge\n\t\t\t\tscale.x = Math.abs(scale.y)\n\t\t\t} else if (Math.abs(scale.x) > Math.abs(scale.y)) {\n\t\t\t\t// holding shift and the drag has moved further in the x dimension\n\t\t\t\tscale.y = Math.abs(scale.x) * (scale.y < 0 ? -1 : 1)\n\t\t\t} else {\n\t\t\t\t// holding shift and the drag has moved further in the y dimension\n\t\t\t\tscale.x = Math.abs(scale.y) * (scale.x < 0 ? -1 : 1)\n\t\t\t}\n\t\t} else {\n\t\t\t// not holding shift, but still need to lock axes if dragging an edge\n\t\t\tif (isXLocked) {\n\t\t\t\tscale.x = 1\n\t\t\t}\n\t\t\tif (isYLocked) {\n\t\t\t\tscale.y = 1\n\t\t\t}\n\t\t}\n\n\t\tif (!this.info.isCreating) {\n\t\t\tthis.updateCursor({\n\t\t\t\tdragHandle,\n\t\t\t\tisFlippedX: scale.x < 0,\n\t\t\t\tisFlippedY: scale.y < 0,\n\t\t\t\trotation: selectionRotation,\n\t\t\t})\n\t\t}\n\n\t\t// Batch-measure geo shape labels to avoid layout thrashing (only worth it for multiple shapes).\n\t\tif (shapeSnapshots.size > 1) {\n\t\t\tbatchMeasureGeoLabels(\n\t\t\t\tthis.editor,\n\t\t\t\tshapeSnapshots,\n\t\t\t\tscale,\n\t\t\t\tselectionRotation,\n\t\t\t\tisAspectRatioLocked\n\t\t\t)\n\t\t}\n\n\t\t// Resize all shapes (onResize will use the batch cache for geo shapes when available).\n\t\t// Collect the updates for each nesting level and commit them in a single batch, so that\n\t\t// each pointer move pays the store's per-commit costs once per level rather than once per\n\t\t// shape. Shapes that are rotated out of alignment with the selection can't be expressed\n\t\t// as a single update; getResizeShapePartial resizes those immediately and returns null.\n\t\tfor (const level of resizeLevels) {\n\t\t\tconst changes: TLShapePartial[] = []\n\n\t\t\tfor (const id of level) {\n\t\t\t\tconst snapshot = shapeSnapshots.get(id)!\n\n\t\t\t\tconst change = editor.getResizeShapePartial(id, scale, {\n\t\t\t\t\tinitialShape: snapshot.shape,\n\t\t\t\t\tinitialBounds: snapshot.bounds,\n\t\t\t\t\tinitialPageTransform: snapshot.pageTransform,\n\t\t\t\t\tdragHandle,\n\t\t\t\t\tmode:\n\t\t\t\t\t\tselectedShapeIds.length === 1 && id === selectedShapeIds[0]\n\t\t\t\t\t\t\t? 'resize_bounds'\n\t\t\t\t\t\t\t: 'scale_shape',\n\t\t\t\t\tscaleOrigin: scaleOriginPage,\n\t\t\t\t\tisAspectRatioLocked,\n\t\t\t\t\tscaleAxisRotation: selectionRotation,\n\t\t\t\t\tskipStartAndEndCallbacks: true,\n\t\t\t\t})\n\n\t\t\t\tif (change) changes.push(change)\n\t\t\t}\n\n\t\t\tif (changes.length > 0) {\n\t\t\t\teditor.updateShapes(changes)\n\t\t\t}\n\t\t}\n\n\t\t// If there's only one shape snapshot and it's a frame and the user is holding ctrl,\n\t\t// then we preserve the position of the frame's children, almost like the user is cropping\n\t\t// the frame rather than resizing it.\n\t\tif (isHoldingAccel) {\n\t\t\tthis.didHoldCommand = true\n\n\t\t\tconst childChanges: TLShapePartial[] = []\n\n\t\t\tfor (const { id, children } of frames) {\n\t\t\t\tif (!children.length) continue\n\t\t\t\tconst initial = shapeSnapshots.get(id)!.shape\n\t\t\t\tconst current = this.editor.getShape(id)!\n\t\t\t\tif (!(initial && current)) continue\n\n\t\t\t\tconst dx = current.x - initial.x\n\t\t\t\tconst dy = current.y - initial.y\n\n\t\t\t\tconst delta = new Vec(dx, dy).rot(-initial.rotation)\n\n\t\t\t\tif (delta.x !== 0 || delta.y !== 0) {\n\t\t\t\t\tfor (const child of children) {\n\t\t\t\t\t\tchildChanges.push({\n\t\t\t\t\t\t\tid: child.id,\n\t\t\t\t\t\t\ttype: child.type,\n\t\t\t\t\t\t\tx: child.x - delta.x,\n\t\t\t\t\t\t\ty: child.y - delta.y,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (childChanges.length > 0) {\n\t\t\t\tthis.editor.updateShapes(childChanges)\n\t\t\t}\n\t\t} else if (this.didHoldCommand) {\n\t\t\t// If we're no longer holding the command key...\n\t\t\tthis.didHoldCommand = false\n\n\t\t\tconst childChanges: TLShapePartial[] = []\n\n\t\t\tfor (const { children } of frames) {\n\t\t\t\tfor (const child of children) {\n\t\t\t\t\tchildChanges.push({\n\t\t\t\t\t\tid: child.id,\n\t\t\t\t\t\ttype: child.type,\n\t\t\t\t\t\tx: child.x,\n\t\t\t\t\t\ty: child.y,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (childChanges.length > 0) {\n\t\t\t\tthis.editor.updateShapes(childChanges)\n\t\t\t}\n\t\t}\n\n\t\tthis.updateEnclosureHints()\n\t}\n\n\t// While drag-creating a frame, hint the sibling shapes that would become its children on pointer up\n\tprivate updateEnclosureHints() {\n\t\tif (!this.info.isCreating) return\n\n\t\tconst shape = this.editor.getOnlySelectedShape()\n\t\tif (!shape || !this.editor.isShapeOfType(shape, 'frame')) return\n\n\t\tconst hintingShapeIds = getEnclosedShapeIds(this.editor, shape)\n\t\tconst prevHintingShapeIds = this.editor.getHintingShapeIds()\n\t\tif (\n\t\t\thintingShapeIds.length === prevHintingShapeIds.length &&\n\t\t\thintingShapeIds.every((id, i) => id === prevHintingShapeIds[i])\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.editor.setHintingShapes(hintingShapeIds)\n\t}\n\n\t// ---\n\n\tprivate updateCursor({\n\t\tdragHandle,\n\t\tisFlippedX,\n\t\tisFlippedY,\n\t\trotation,\n\t}: {\n\t\tdragHandle: SelectionCorner | SelectionEdge\n\t\tisFlippedX: boolean\n\t\tisFlippedY: boolean\n\t\trotation: number\n\t}) {\n\t\tconst prevCursor = this.editor.getInstanceState().cursor\n\t\tlet nextCursorType = prevCursor.type\n\n\t\tswitch (dragHandle) {\n\t\t\tcase 'top_left':\n\t\t\tcase 'bottom_right': {\n\t\t\t\tnextCursorType = 'nwse-resize'\n\t\t\t\tif (isFlippedX !== isFlippedY) {\n\t\t\t\t\tnextCursorType = 'nesw-resize'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'top_right':\n\t\t\tcase 'bottom_left': {\n\t\t\t\tnextCursorType = 'nesw-resize'\n\t\t\t\tif (isFlippedX !== isFlippedY) {\n\t\t\t\t\tnextCursorType = 'nwse-resize'\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// this runs on every pointer move, so skip the instance state update when nothing changed\n\t\tif (nextCursorType === prevCursor.type && rotation === prevCursor.rotation) return\n\n\t\tthis.editor.setCursor({ type: nextCursorType, rotation })\n\t}\n\n\toverride onExit() {\n\t\tthis.parent.setCurrentToolIdMask(undefined)\n\t\tthis.editor.setCursor({ type: 'default', rotation: 0 })\n\t\tthis.editor.snaps.clearIndicators()\n\t\tsetBatchLabelSizeCache(this.editor, null)\n\t\tif (this.info.isCreating && this.editor.getHintingShapeIds().length > 0) {\n\t\t\tthis.editor.setHintingShapes([])\n\t\t}\n\t\t// Exited mid-creation without complete() or cancel(), e.g. a tool shortcut pressed while\n\t\t// dragging out a text box: the shape created at the drag threshold was never committed and\n\t\t// would otherwise be left behind, empty and invisible (#10401)\n\t\tif (this.info.isCreating && !this.didFinish) {\n\t\t\tthis.editor.bailToMark(this.markId)\n\t\t}\n\t}\n\n\tprivate _createSnapshot() {\n\t\tconst { editor } = this\n\t\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\t\tconst selectionRotation = editor.getSelectionRotation()\n\t\tconst originPagePoint = editor.inputs.getOriginPagePoint()\n\n\t\tconst selectionBounds = editor.getSelectionRotatedPageBounds()\n\t\tif (!selectionBounds) throw Error('Resizing but nothing is selected')\n\n\t\tconst dragHandlePoint = Vec.RotWith(\n\t\t\tselectionBounds.getHandlePoint(this.info.handle!),\n\t\t\tselectionBounds.point,\n\t\t\tselectionRotation\n\t\t)\n\n\t\tconst cursorHandleOffset = Vec.Sub(originPagePoint, dragHandlePoint)\n\n\t\tconst shapeSnapshots = new Map<\n\t\t\tTLShapeId,\n\t\t\t{\n\t\t\t\tshape: TLShape\n\t\t\t\tbounds: Box\n\t\t\t\tpageTransform: Mat\n\t\t\t\tpageRotation: number\n\t\t\t\tisAspectRatioLocked: boolean\n\t\t\t}\n\t\t>()\n\n\t\tconst frames: { id: TLShapeId; children: TLShape[] }[] = []\n\n\t\tconst populateResizingShapes = (shapeId: TLShapeId): false | undefined => {\n\t\t\tconst shape = editor.getShape(shapeId)\n\t\t\tif (!shape) return false\n\n\t\t\tconst util = editor.getShapeUtil(shape)\n\n\t\t\t// Shapes that can't resize are snapshotted too: getResizeShapePartial repositions them\n\t\t\t// so they keep their place in the selection instead of being left behind.\n\t\t\tconst pageTransform = editor.getShapePageTransform(shape)!\n\t\t\tshapeSnapshots.set(shape.id, {\n\t\t\t\tshape,\n\t\t\t\tbounds: editor.getShapeGeometry(shape).bounds,\n\t\t\t\tpageTransform,\n\t\t\t\tpageRotation: Mat.Decompose(pageTransform).rotation,\n\t\t\t\tisAspectRatioLocked: util.isAspectRatioLocked(shape),\n\t\t\t})\n\n\t\t\t// Special case:\n\t\t\t// For frames, we don't want to resize children but we DO want to get a snapshot of their children so that we can restore their\n\t\t\t// positions with the accel key behavior. We could break this further into APIs, for example by collecting snapshots of all\n\t\t\t// descendants (easy) but also flagging with behavior like \"resize\" or \"keep absolute position\" or \"reposition only with accel key\",\n\t\t\t// though I'm not sure where that would be defined; perhaps better handled with onResizeStart / onResize callbacks on the util, and\n\t\t\t// pass `accelKeyIsPressed` as well as `accelKeyWasPressed`?\n\t\t\tif (editor.isShapeFrameLike(shape)) {\n\t\t\t\tframes.push({\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\tchildren: compact(\n\t\t\t\t\t\teditor.getSortedChildIdsForParent(shape).map((id) => editor.getShape(id))\n\t\t\t\t\t),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// This will stop the traversal of descendants\n\t\t\tif (!util.canResizeChildren(shape)) return false\n\n\t\t\treturn undefined\n\t\t}\n\n\t\tselectedShapeIds.forEach((shapeId) => {\n\t\t\tconst keepDescending = populateResizingShapes(shapeId)\n\t\t\tif (keepDescending === false) return\n\t\t\teditor.visitDescendants(shapeId, populateResizingShapes)\n\t\t})\n\n\t\tconst canShapesDeform = ![...shapeSnapshots.values()].some(\n\t\t\t(shape) =>\n\t\t\t\t!areAnglesCompatible(shape.pageRotation, selectionRotation) || shape.isAspectRatioLocked\n\t\t)\n\n\t\t// Group the shapes into levels of relative nesting so that each level can be resized in a\n\t\t// single batched update. A shape whose ancestor is also resizing must commit after that\n\t\t// ancestor, because its new position is computed against the parent's current transform.\n\t\t// In the common case (no resizing shape is parented to another resizing shape) there is a\n\t\t// single level, so each pointer move commits one update for all shapes.\n\t\tconst resizeLevels: TLShapeId[][] = []\n\t\tconst levelByShapeId = new Map<TLShapeId, number>()\n\t\tconst getLevel = (id: TLShapeId): number => {\n\t\t\tconst cached = levelByShapeId.get(id)\n\t\t\tif (cached !== undefined) return cached\n\t\t\tlet level = 0\n\t\t\tlet parentId = editor.getShape(id)?.parentId\n\t\t\twhile (parentId && isShapeId(parentId)) {\n\t\t\t\tif (shapeSnapshots.has(parentId)) {\n\t\t\t\t\tlevel = getLevel(parentId) + 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tparentId = editor.getShape(parentId)?.parentId\n\t\t\t}\n\t\t\tlevelByShapeId.set(id, level)\n\t\t\treturn level\n\t\t}\n\t\tfor (const id of shapeSnapshots.keys()) {\n\t\t\tconst level = getLevel(id)\n\t\t\twhile (resizeLevels.length <= level) resizeLevels.push([])\n\t\t\tresizeLevels[level].push(id)\n\t\t}\n\n\t\treturn {\n\t\t\tshapeSnapshots,\n\t\t\tselectionBounds,\n\t\t\tcursorHandleOffset,\n\t\t\tselectionRotation,\n\t\t\tselectedShapeIds,\n\t\t\tcanShapesDeform,\n\t\t\tinitialSelectionPageBounds: this.editor.getSelectionPageBounds()!,\n\t\t\tframes,\n\t\t\tresizeLevels,\n\t\t}\n\t}\n}\n\ntype Snapshot = ReturnType<Resizing['_createSnapshot']>\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -31,9 +31,7 @@ class ScribbleBrushing extends import_editor.StateNode {
|
|
|
31
31
|
initialSelectedShapeIds = /* @__PURE__ */ new Set();
|
|
32
32
|
newlySelectedShapeIds = /* @__PURE__ */ new Set();
|
|
33
33
|
onEnter() {
|
|
34
|
-
this.initialSelectedShapeIds = new Set(
|
|
35
|
-
this.editor.inputs.getShiftKey() ? this.editor.getSelectedShapeIds() : []
|
|
36
|
-
);
|
|
34
|
+
this.initialSelectedShapeIds = new Set(this.editor.getSelectedShapeIds());
|
|
37
35
|
this.newlySelectedShapeIds = /* @__PURE__ */ new Set();
|
|
38
36
|
this.size = 0;
|
|
39
37
|
this.hits.clear();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBox,\n\tGeometry2d,\n\tStateNode,\n\tTLShape,\n\tTLShapeId,\n\tVec,\n\tintersectLineSegmentPolygon,\n\tpointInPolygon,\n} from '@tldraw/editor'\n\nexport class ScribbleBrushing extends StateNode {\n\tstatic override id = 'scribble_brushing'\n\tstatic override trackPerformance = true\n\n\thits = new Set<TLShapeId>()\n\n\tsize = 0\n\n\tscribbleId = 'id'\n\n\tinitialSelectedShapeIds = new Set<TLShapeId>()\n\tnewlySelectedShapeIds = new Set<TLShapeId>()\n\n\toverride onEnter() {\n\t\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBASO;AAEA,MAAM,yBAAyB,wBAAU;AAAA,EAC/C,OAAgB,KAAK;AAAA,EACrB,OAAgB,mBAAmB;AAAA,EAEnC,OAAO,oBAAI,IAAe;AAAA,EAE1B,OAAO;AAAA,EAEP,aAAa;AAAA,EAEb,0BAA0B,oBAAI,IAAe;AAAA,EAC7C,wBAAwB,oBAAI,IAAe;AAAA,EAElC,UAAU;
|
|
4
|
+
"sourcesContent": ["import {\n\tBox,\n\tGeometry2d,\n\tStateNode,\n\tTLShape,\n\tTLShapeId,\n\tVec,\n\tintersectLineSegmentPolygon,\n\tpointInPolygon,\n} from '@tldraw/editor'\n\nexport class ScribbleBrushing extends StateNode {\n\tstatic override id = 'scribble_brushing'\n\tstatic override trackPerformance = true\n\n\thits = new Set<TLShapeId>()\n\n\tsize = 0\n\n\tscribbleId = 'id'\n\n\tinitialSelectedShapeIds = new Set<TLShapeId>()\n\tnewlySelectedShapeIds = new Set<TLShapeId>()\n\n\toverride onEnter() {\n\t\t// Captured regardless of shift so cancel() can restore it like the rectangle\n\t\t// brush does (#10429); shift only decides whether it merges into the live selection.\n\t\tthis.initialSelectedShapeIds = new Set<TLShapeId>(this.editor.getSelectedShapeIds())\n\t\tthis.newlySelectedShapeIds = new Set<TLShapeId>()\n\t\tthis.size = 0\n\t\tthis.hits.clear()\n\n\t\tconst scribbleItem = this.editor.scribbles.addScribble({\n\t\t\tcolor: 'selection-stroke',\n\t\t\topacity: 0.32,\n\t\t\tsize: 12,\n\t\t})\n\n\t\tthis.scribbleId = scribbleItem.id\n\n\t\tthis.updateScribbleSelection(true)\n\n\t\tthis.editor.updateInstanceState({ brush: null })\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.scribbles.stop(this.scribbleId)\n\t}\n\n\toverride onPointerMove() {\n\t\tthis.updateScribbleSelection(true)\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onKeyDown() {\n\t\tthis.updateScribbleSelection(false)\n\t}\n\n\toverride onKeyUp() {\n\t\tif (!this.editor.inputs.getAltKey()) {\n\t\t\tthis.parent.transition('brushing')\n\t\t} else {\n\t\t\tthis.updateScribbleSelection(false)\n\t\t}\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\tprivate pushPointToScribble() {\n\t\tconst { x, y } = this.editor.inputs.getCurrentPagePoint()\n\t\tthis.editor.scribbles.addPoint(this.scribbleId, x, y)\n\t}\n\n\tprivate updateScribbleSelection(addPoint: boolean) {\n\t\tconst { editor } = this\n\t\tconst shiftKey = this.editor.inputs.getShiftKey()\n\t\tconst originPagePoint = this.editor.inputs.getOriginPagePoint()\n\t\tconst previousPagePoint = this.editor.inputs.getPreviousPagePoint()\n\t\tconst currentPagePoint = this.editor.inputs.getCurrentPagePoint()\n\n\t\tconst { newlySelectedShapeIds, initialSelectedShapeIds } = this\n\n\t\tif (addPoint) {\n\t\t\tthis.pushPointToScribble()\n\t\t}\n\n\t\tconst minDist = 0 // this.editor.options.hitTestMargin / zoomLevel\n\n\t\t// Create bounds around line segment with margin\n\t\tconst lineBounds = Box.FromPoints([previousPagePoint, currentPagePoint]).expandBy(minDist)\n\t\tconst candidateIds = editor.getShapeIdsInsideBounds(lineBounds)\n\n\t\t// Early return if no candidates - avoid expensive getCurrentPageRenderingShapesSorted()\n\t\t// But still update selection based on current state\n\t\tif (candidateIds.size === 0) {\n\t\t\tconst current = editor.getSelectedShapeIds()\n\t\t\tconst next = new Set<TLShapeId>(\n\t\t\t\tshiftKey\n\t\t\t\t\t? [...newlySelectedShapeIds, ...initialSelectedShapeIds]\n\t\t\t\t\t: [...newlySelectedShapeIds]\n\t\t\t)\n\t\t\tif (current.length !== next.size || current.some((id) => !next.has(id))) {\n\t\t\t\tthis.editor.setSelectedShapes(Array.from(next))\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tconst allShapes = this.editor.getCurrentPageRenderingShapesSorted()\n\t\tconst currentPageShapes = allShapes.filter((shape) => candidateIds.has(shape.id))\n\n\t\tconst shapes = currentPageShapes\n\t\tlet shape: TLShape, geometry: Geometry2d, A: Vec, B: Vec\n\n\t\tfor (let i = 0, n = shapes.length; i < n; i++) {\n\t\t\tshape = shapes[i]\n\n\t\t\t// If the shape is a group or is already selected, don't select it.\n\t\t\t// Also skip locked shapes unless the selectLockedShapes option is enabled.\n\t\t\tif (\n\t\t\t\teditor.isShapeOfType(shape, 'group') ||\n\t\t\t\tnewlySelectedShapeIds.has(shape.id) ||\n\t\t\t\t(!editor.options.selectLockedShapes && editor.isShapeOrAncestorLocked(shape))\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tgeometry = editor.getShapeGeometry(shape)\n\n\t\t\t// If the scribble started inside of a frame-like shape, don't select it\n\t\t\tif (\n\t\t\t\teditor.isShapeFrameLike(shape) &&\n\t\t\t\tgeometry.bounds.containsPoint(editor.getPointInShapeSpace(shape, originPagePoint))\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Hit test the shape using a line segment\n\t\t\tconst pageTransform = editor.getShapePageTransform(shape)\n\t\t\tif (!geometry || !pageTransform) continue\n\t\t\tconst pt = pageTransform.clone().invert()\n\t\t\tA = pt.applyToPoint(previousPagePoint)\n\t\t\tB = pt.applyToPoint(currentPagePoint)\n\n\t\t\t// If the line segment is entirely above / below / left / right of the shape's bounding box, skip the hit test\n\t\t\tconst { bounds } = geometry\n\t\t\tif (\n\t\t\t\tbounds.minX - minDist > Math.max(A.x, B.x) ||\n\t\t\t\tbounds.minY - minDist > Math.max(A.y, B.y) ||\n\t\t\t\tbounds.maxX + minDist < Math.min(A.x, B.x) ||\n\t\t\t\tbounds.maxY + minDist < Math.min(A.y, B.y)\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (geometry.hitTestLineSegment(A, B, minDist)) {\n\t\t\t\tconst outermostShape = this.editor.getOutermostSelectableShape(shape)\n\t\t\t\tconst pageMask = this.editor.getShapeMask(outermostShape.id)\n\t\t\t\tif (pageMask) {\n\t\t\t\t\tconst intersection = intersectLineSegmentPolygon(\n\t\t\t\t\t\tpreviousPagePoint,\n\t\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\t\tpageMask\n\t\t\t\t\t)\n\t\t\t\t\tif (intersection !== null) {\n\t\t\t\t\t\tconst isInMask = pointInPolygon(currentPagePoint, pageMask)\n\t\t\t\t\t\tif (!isInMask) continue\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tnewlySelectedShapeIds.add(outermostShape.id)\n\t\t\t}\n\t\t}\n\n\t\tconst current = editor.getSelectedShapeIds()\n\t\tconst next = new Set<TLShapeId>(\n\t\t\tshiftKey ? [...newlySelectedShapeIds, ...initialSelectedShapeIds] : [...newlySelectedShapeIds]\n\t\t)\n\t\tif (current.length !== next.size || current.some((id) => !next.has(id))) {\n\t\t\tthis.editor.setSelectedShapes(Array.from(next))\n\t\t}\n\t}\n\n\tprivate complete() {\n\t\tthis.updateScribbleSelection(true)\n\t\tthis.parent.transition('idle')\n\t}\n\n\tprivate cancel() {\n\t\tthis.editor.setSelectedShapes([...this.initialSelectedShapeIds])\n\t\tthis.parent.transition('idle')\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["current", "next", "shape"]
|
|
7
7
|
}
|
|
@@ -136,6 +136,7 @@ class Translating extends import_editor.StateNode {
|
|
|
136
136
|
this.markId = this.editor.markHistoryStoppingPoint("translate cloning");
|
|
137
137
|
this.editor.duplicateShapes(Array.from(this.editor.getSelectedShapeIds()));
|
|
138
138
|
this.snapshot = getTranslatingSnapshot(this.editor);
|
|
139
|
+
this.dragAndDropManager.clear();
|
|
139
140
|
this.handleStart();
|
|
140
141
|
this.updateShapes();
|
|
141
142
|
}
|
|
@@ -144,6 +145,7 @@ class Translating extends import_editor.StateNode {
|
|
|
144
145
|
this.snapshot = this.selectionSnapshot;
|
|
145
146
|
this.reset();
|
|
146
147
|
this.markId = this.editor.markHistoryStoppingPoint("translate");
|
|
148
|
+
this.dragAndDropManager.clear();
|
|
147
149
|
this.updateShapes();
|
|
148
150
|
}
|
|
149
151
|
reset() {
|
|
@@ -351,7 +353,8 @@ function getTranslatingSnapshot(editor) {
|
|
|
351
353
|
scale: noteSnapshot.shape.props.scale,
|
|
352
354
|
extraHeight: noteSnapshot.shape.props.growY ?? 0,
|
|
353
355
|
noteWidth: dv.noteWidth,
|
|
354
|
-
noteHeight: dv.noteHeight
|
|
356
|
+
noteHeight: dv.noteHeight,
|
|
357
|
+
excludeShapeIds: selectedShapeIds
|
|
355
358
|
});
|
|
356
359
|
noteCenterOffset = new import_editor.Vec(dv.noteWidth / 2, dv.noteHeight / 2);
|
|
357
360
|
}
|