tldraw 5.2.0-next.e2b8d10bf10e → 5.2.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 +20294 -0
- package/README.md +13 -1
- package/RELEASE_NOTES.md +2908 -0
- package/dist-cjs/index.d.ts +110 -23
- package/dist-cjs/index.js +3 -3
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawImage.js +0 -1
- package/dist-cjs/lib/TldrawImage.js.map +2 -2
- package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js +2 -1
- package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
- package/dist-cjs/lib/defaultEmbedDefinitions.js +3 -2
- package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
- package/dist-cjs/lib/defaultOverlayUtils.js +11 -11
- package/dist-cjs/lib/defaultOverlayUtils.js.map +2 -2
- package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js +76 -64
- package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js.map +2 -2
- package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js +1 -1
- package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js.map +2 -2
- package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js +107 -0
- package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +12 -3
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js +54 -6
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/getPath.js +1 -1
- package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +45 -47
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/FrameShapeTool.js +23 -18
- package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +11 -7
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -11
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +5 -1
- package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +31 -41
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/noteHelpers.js +1 -1
- package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
- package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +28 -6
- package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +3 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js +3 -3
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js +17 -3
- package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/core.js +424 -0
- package/dist-cjs/lib/shapes/shared/freehand/core.js.map +7 -0
- package/dist-cjs/lib/shapes/shared/freehand/fmt.js +106 -0
- package/dist-cjs/lib/shapes/shared/freehand/fmt.js.map +7 -0
- package/dist-cjs/lib/shapes/shared/freehand/getStroke.js +6 -6
- package/dist-cjs/lib/shapes/shared/freehand/getStroke.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js +320 -86
- package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js.map +3 -3
- package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js +20 -96
- package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js.map +3 -3
- package/dist-cjs/lib/shapes/shared/freehand/svg.js +55 -19
- package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/svgInk.js +189 -97
- package/dist-cjs/lib/shapes/shared/freehand/svgInk.js.map +3 -3
- package/dist-cjs/lib/shapes/shared/freehand/types.js.map +1 -1
- package/dist-cjs/lib/shapes/shared/interpolate-props.js +6 -2
- package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
- package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/HandTool.js +16 -6
- package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +10 -1
- package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js +84 -0
- package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js.map +7 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +12 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +4 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +107 -46
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +4 -3
- package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
- package/dist-cjs/lib/ui/components/A11y.js +2 -0
- package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +14 -1
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js +0 -6
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +2 -2
- package/dist-cjs/lib/ui/components/Dialogs.js +17 -37
- package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
- package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js +19 -4
- package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +12 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +47 -70
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +25 -46
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js +1 -1
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +1 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/menu-items.js +7 -0
- package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js +2 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +14 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +2 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +0 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js +1 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +70 -1
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/asset-urls.js +5 -8
- package/dist-cjs/lib/ui/context/asset-urls.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +13 -0
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
- package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +2 -0
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.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-cjs/lib/utils/embeds/embeds.js +4 -4
- package/dist-cjs/lib/utils/embeds/embeds.js.map +2 -2
- package/dist-cjs/lib/utils/test-helpers.js +2 -2
- package/dist-cjs/lib/utils/test-helpers.js.map +2 -2
- package/dist-cjs/lib/utils/text/richText.js +3 -1
- package/dist-cjs/lib/utils/text/richText.js.map +2 -2
- package/dist-esm/index.d.mts +110 -23
- package/dist-esm/index.mjs +5 -3
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawImage.mjs +0 -1
- package/dist-esm/lib/TldrawImage.mjs.map +2 -2
- package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs +2 -1
- package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
- package/dist-esm/lib/defaultEmbedDefinitions.mjs +3 -2
- package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
- package/dist-esm/lib/defaultOverlayUtils.mjs +11 -11
- package/dist-esm/lib/defaultOverlayUtils.mjs.map +2 -2
- package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs +77 -65
- package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs.map +2 -2
- package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs +1 -1
- package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs.map +2 -2
- package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs +87 -0
- package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +9 -1
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +15 -3
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +54 -6
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -1
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/getPath.mjs +1 -1
- package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +46 -47
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs +23 -18
- package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +4 -0
- package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +12 -7
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -11
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +6 -1
- package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +32 -42
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/noteHelpers.mjs +1 -1
- package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +29 -6
- package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +3 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +4 -3
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs +17 -3
- package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/core.mjs +404 -0
- package/dist-esm/lib/shapes/shared/freehand/core.mjs.map +7 -0
- package/dist-esm/lib/shapes/shared/freehand/fmt.mjs +86 -0
- package/dist-esm/lib/shapes/shared/freehand/fmt.mjs.map +7 -0
- package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs +7 -7
- package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs +332 -86
- package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs.map +3 -3
- package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs +31 -96
- package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs.map +3 -3
- package/dist-esm/lib/shapes/shared/freehand/svg.mjs +55 -19
- package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs +214 -99
- package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs.map +3 -3
- package/dist-esm/lib/shapes/shared/interpolate-props.mjs +6 -2
- package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +4 -0
- package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/HandTool.mjs +16 -6
- package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +10 -1
- package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs +64 -0
- package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs.map +7 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +12 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +4 -0
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +108 -46
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/ui/TldrawUi.mjs +4 -3
- package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
- package/dist-esm/lib/ui/components/A11y.mjs +2 -0
- package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +21 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs +0 -6
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Dialogs.mjs +19 -39
- package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
- package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs +20 -5
- package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +12 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +47 -70
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +25 -46
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs +1 -1
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +1 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/menu-items.mjs +7 -0
- package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs +2 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +14 -3
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +2 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +2 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +0 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs +1 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +71 -1
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/asset-urls.mjs +5 -8
- package/dist-esm/lib/ui/context/asset-urls.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +13 -0
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
- package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +2 -0
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/dist-esm/lib/utils/embeds/embeds.mjs +4 -4
- package/dist-esm/lib/utils/embeds/embeds.mjs.map +2 -2
- package/dist-esm/lib/utils/test-helpers.mjs +2 -2
- package/dist-esm/lib/utils/test-helpers.mjs.map +2 -2
- package/dist-esm/lib/utils/text/richText.mjs +3 -1
- package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
- package/package.json +11 -6
- package/src/index.ts +6 -1
- package/src/lib/TldrawImage.tsx +2 -2
- package/src/lib/bindings/arrow/ArrowBindingUtil.ts +5 -1
- package/src/lib/defaultEmbedDefinitions.ts +28 -6
- package/src/lib/defaultOverlayUtils.ts +11 -11
- package/src/lib/overlays/SelectionForegroundOverlayUtil.ts +91 -72
- package/src/lib/overlays/ShapeHandleOverlayUtil.ts +3 -1
- package/src/lib/overlays/ShapeIndicatorOverlayUtil.ts +133 -0
- package/src/lib/shapes/arrow/toolStates/Pointing.tsx +11 -1
- package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +16 -3
- package/src/lib/shapes/bookmark/bookmarks.ts +105 -15
- package/src/lib/shapes/draw/DrawShapeUtil.tsx +7 -5
- package/src/lib/shapes/draw/getPath.ts +1 -1
- package/src/lib/shapes/draw/toolStates/Drawing.ts +55 -48
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +14 -4
- package/src/lib/shapes/frame/FrameShapeTool.ts +35 -24
- package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +46 -0
- package/src/lib/shapes/geo/GeoShapeUtil.tsx +2 -1
- package/src/lib/shapes/geo/toolStates/Pointing.ts +5 -0
- package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +14 -11
- package/src/lib/shapes/image/ImageShapeUtil.tsx +7 -11
- package/src/lib/shapes/line/LineShapeTool.test.ts +41 -0
- package/src/lib/shapes/line/toolStates/Pointing.ts +12 -2
- package/src/lib/shapes/note/NoteShapeUtil.tsx +36 -51
- package/src/lib/shapes/note/noteCloning.test.ts +5 -5
- package/src/lib/shapes/note/noteHelpers.ts +1 -1
- package/src/lib/shapes/note/toolStates/Pointing.ts +40 -7
- package/src/lib/shapes/shared/PlainTextLabel.tsx +3 -3
- package/src/lib/shapes/shared/RichTextLabel.tsx +4 -3
- package/src/lib/shapes/shared/defaultStyleDefs.tsx +25 -3
- package/src/lib/shapes/shared/freehand/core.ts +547 -0
- package/src/lib/shapes/shared/freehand/fmt.ts +106 -0
- package/src/lib/shapes/shared/freehand/getStroke.ts +7 -7
- package/src/lib/shapes/shared/freehand/getStrokeOutlinePoints.ts +451 -139
- package/src/lib/shapes/shared/freehand/getStrokePoints.ts +33 -153
- package/src/lib/shapes/shared/freehand/svg.ts +72 -23
- package/src/lib/shapes/shared/freehand/svgInk.ts +281 -136
- package/src/lib/shapes/shared/freehand/types.ts +0 -1
- package/src/lib/shapes/shared/interpolate-props.ts +6 -2
- package/src/lib/shapes/text/toolStates/Pointing.ts +5 -0
- package/src/lib/tools/HandTool/HandTool.ts +19 -6
- package/src/lib/tools/HandTool/childStates/Dragging.ts +17 -1
- package/src/lib/tools/HandTool/childStates/OneFingerZooming.ts +79 -0
- package/src/lib/tools/SelectTool/childStates/Idle.ts +16 -2
- package/src/lib/tools/SelectTool/childStates/PointingShape.ts +8 -0
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +137 -49
- package/src/lib/ui/TldrawUi.tsx +3 -3
- package/src/lib/ui/components/A11y.tsx +2 -0
- package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +32 -2
- package/src/lib/ui/components/ContextMenu/DefaultContextMenuContent.tsx +5 -6
- package/src/lib/ui/components/DefaultFollowingIndicator.tsx +2 -2
- package/src/lib/ui/components/Dialogs.tsx +20 -23
- package/src/lib/ui/components/HelperButtons/BackToContent.tsx +32 -4
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +10 -0
- package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +60 -74
- package/src/lib/ui/components/Minimap/MinimapManager.ts +35 -57
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.tsx +2 -2
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuContent.tsx +2 -1
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.tsx +2 -1
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuItem.tsx +3 -3
- package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +5 -0
- package/src/lib/ui/components/menu-items.tsx +9 -0
- package/src/lib/ui/components/primitives/TldrawUiDropdownMenu.tsx +3 -1
- package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +15 -3
- package/src/lib/ui/components/primitives/TldrawUiInput.tsx +4 -0
- package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +7 -0
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +0 -2
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.tsx +0 -1
- package/src/lib/ui/context/actions.tsx +88 -1
- package/src/lib/ui/context/asset-urls.tsx +9 -8
- package/src/lib/ui/context/events.tsx +2 -0
- package/src/lib/ui/hooks/useKeyboardShortcuts.ts +45 -7
- package/src/lib/ui/hooks/useTools.tsx +7 -1
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +20 -9
- package/src/lib/utils/embeds/embeds.test.ts +14 -12
- package/src/lib/utils/embeds/embeds.ts +10 -4
- package/src/lib/utils/test-helpers.ts +3 -3
- package/src/lib/utils/text/richText.test.ts +36 -0
- package/src/lib/utils/text/richText.ts +9 -1
- package/src/test/HandTool.test.ts +93 -0
- package/src/test/ImageShapeUtil.test.ts +88 -0
- package/src/test/SelectTool.test.ts +102 -1
- package/src/test/__snapshots__/drawing.test.ts.snap +2 -1
- package/src/test/attribution.test.ts +40 -29
- package/src/test/bookmark-shapes.test.ts +256 -28
- package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +2 -2
- package/src/test/commands/clipboardCallbacks.test.ts +3 -1
- package/src/test/commands/getSvgString.test.ts +30 -0
- package/src/test/commands/penmode.test.ts +97 -1
- package/src/test/commands/setCamera.test.ts +12 -0
- package/src/test/dragFromToolbar.test.ts +67 -0
- package/src/test/drawing.test.ts +48 -7
- package/src/test/frames.test.ts +72 -0
- package/src/test/freehand/corpus/presets.ts +71 -0
- package/src/test/freehand/corpus/real.ts +370 -0
- package/src/test/freehand/corpus/strokes.ts +50 -0
- package/src/test/freehand/svg.test.ts +20 -0
- package/src/test/freehand/wellformed.test.ts +30 -0
- package/src/test/long-press-create.test.ts +102 -0
- package/src/test/overlays/CollaboratorBrushOverlayUtil.test.ts +4 -4
- package/src/test/overlays/CollaboratorCursorOverlayUtil.test.ts +18 -18
- package/src/test/overlays/CollaboratorHintOverlayUtil.test.ts +7 -7
- package/src/test/overlays/CollaboratorScribbleOverlayUtil.test.ts +3 -3
- package/src/test/overlays/OverlayManager.test.ts +1 -1
- package/src/test/overlays/SelectionForegroundOverlayUtil.test.ts +58 -0
- package/src/test/overlays/ShapeHandleOverlayUtil.test.ts +2 -2
- package/src/test/overlays/ShapeIndicatorOverlayUtil.test.ts +36 -0
- package/src/test/resizing.test.ts +250 -0
- package/src/test/right-click-context-menu.test.ts +90 -0
- package/src/test/rightClickPanning.test.ts +11 -0
- package/src/test/selection-omnibus.test.ts +15 -2
- package/src/test/spatialIndex.test.ts +132 -0
- package/src/test/translating.test.ts +0 -6
- package/src/test/ui/ContextMenu.test.tsx +146 -3
- package/src/test/ui/Dialogs.test.tsx +256 -0
- package/src/test/ui/copyHoveredStyles.test.tsx +154 -0
- package/src/test/ui/keyboardShortcuts.test.tsx +266 -0
- package/tldraw.css +35 -12
- package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js +0 -100
- package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js.map +0 -7
- package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs +0 -80
- package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs.map +0 -7
- package/src/lib/shapes/shared/freehand/setStrokePointRadii.ts +0 -127
|
@@ -21,7 +21,6 @@ __export(defaultOverlayUtils_exports, {
|
|
|
21
21
|
defaultOverlayUtils: () => defaultOverlayUtils
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(defaultOverlayUtils_exports);
|
|
24
|
-
var import_editor = require("@tldraw/editor");
|
|
25
24
|
var import_ArrowBindingHintOverlayUtil = require("./overlays/ArrowBindingHintOverlayUtil");
|
|
26
25
|
var import_ArrowHintOverlayUtil = require("./overlays/ArrowHintOverlayUtil");
|
|
27
26
|
var import_BrushOverlayUtil = require("./overlays/BrushOverlayUtil");
|
|
@@ -33,22 +32,23 @@ var import_CollaboratorShapeIndicatorOverlayUtil = require("./overlays/Collabora
|
|
|
33
32
|
var import_ScribbleOverlayUtil = require("./overlays/ScribbleOverlayUtil");
|
|
34
33
|
var import_SelectionForegroundOverlayUtil = require("./overlays/SelectionForegroundOverlayUtil");
|
|
35
34
|
var import_ShapeHandleOverlayUtil = require("./overlays/ShapeHandleOverlayUtil");
|
|
35
|
+
var import_ShapeIndicatorOverlayUtil = require("./overlays/ShapeIndicatorOverlayUtil");
|
|
36
36
|
var import_SnapIndicatorOverlayUtil = require("./overlays/SnapIndicatorOverlayUtil");
|
|
37
37
|
var import_ZoomBrushOverlayUtil = require("./overlays/ZoomBrushOverlayUtil");
|
|
38
38
|
const defaultOverlayUtils = [
|
|
39
|
+
import_ArrowBindingHintOverlayUtil.ArrowBindingHintOverlayUtil,
|
|
40
|
+
import_ArrowHintOverlayUtil.ArrowHintOverlayUtil,
|
|
41
|
+
import_BrushOverlayUtil.BrushOverlayUtil,
|
|
42
|
+
import_CollaboratorBrushOverlayUtil.CollaboratorBrushOverlayUtil,
|
|
43
|
+
import_CollaboratorCursorOverlayUtil.CollaboratorCursorOverlayUtil,
|
|
44
|
+
import_CollaboratorHintOverlayUtil.CollaboratorHintOverlayUtil,
|
|
45
|
+
import_CollaboratorScribbleOverlayUtil.CollaboratorScribbleOverlayUtil,
|
|
39
46
|
import_CollaboratorShapeIndicatorOverlayUtil.CollaboratorShapeIndicatorOverlayUtil,
|
|
40
|
-
|
|
47
|
+
import_ScribbleOverlayUtil.ScribbleOverlayUtil,
|
|
41
48
|
import_SelectionForegroundOverlayUtil.SelectionForegroundOverlayUtil,
|
|
42
49
|
import_ShapeHandleOverlayUtil.ShapeHandleOverlayUtil,
|
|
43
|
-
|
|
44
|
-
import_ZoomBrushOverlayUtil.ZoomBrushOverlayUtil,
|
|
50
|
+
import_ShapeIndicatorOverlayUtil.ShapeIndicatorOverlayUtil,
|
|
45
51
|
import_SnapIndicatorOverlayUtil.SnapIndicatorOverlayUtil,
|
|
46
|
-
|
|
47
|
-
import_CollaboratorBrushOverlayUtil.CollaboratorBrushOverlayUtil,
|
|
48
|
-
import_CollaboratorScribbleOverlayUtil.CollaboratorScribbleOverlayUtil,
|
|
49
|
-
import_CollaboratorHintOverlayUtil.CollaboratorHintOverlayUtil,
|
|
50
|
-
import_ArrowHintOverlayUtil.ArrowHintOverlayUtil,
|
|
51
|
-
import_ArrowBindingHintOverlayUtil.ArrowBindingHintOverlayUtil,
|
|
52
|
-
import_CollaboratorCursorOverlayUtil.CollaboratorCursorOverlayUtil
|
|
52
|
+
import_ZoomBrushOverlayUtil.ZoomBrushOverlayUtil
|
|
53
53
|
];
|
|
54
54
|
//# sourceMappingURL=defaultOverlayUtils.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/defaultOverlayUtils.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import { ArrowBindingHintOverlayUtil } from './overlays/ArrowBindingHintOverlayUtil'\nimport { ArrowHintOverlayUtil } from './overlays/ArrowHintOverlayUtil'\nimport { BrushOverlayUtil } from './overlays/BrushOverlayUtil'\nimport { CollaboratorBrushOverlayUtil } from './overlays/CollaboratorBrushOverlayUtil'\nimport { CollaboratorCursorOverlayUtil } from './overlays/CollaboratorCursorOverlayUtil'\nimport { CollaboratorHintOverlayUtil } from './overlays/CollaboratorHintOverlayUtil'\nimport { CollaboratorScribbleOverlayUtil } from './overlays/CollaboratorScribbleOverlayUtil'\nimport { CollaboratorShapeIndicatorOverlayUtil } from './overlays/CollaboratorShapeIndicatorOverlayUtil'\nimport { ScribbleOverlayUtil } from './overlays/ScribbleOverlayUtil'\nimport { SelectionForegroundOverlayUtil } from './overlays/SelectionForegroundOverlayUtil'\nimport { ShapeHandleOverlayUtil } from './overlays/ShapeHandleOverlayUtil'\nimport { ShapeIndicatorOverlayUtil } from './overlays/ShapeIndicatorOverlayUtil'\nimport { SnapIndicatorOverlayUtil } from './overlays/SnapIndicatorOverlayUtil'\nimport { ZoomBrushOverlayUtil } from './overlays/ZoomBrushOverlayUtil'\n\n/** @public */\nexport const defaultOverlayUtils = [\n\tArrowBindingHintOverlayUtil,\n\tArrowHintOverlayUtil,\n\tBrushOverlayUtil,\n\tCollaboratorBrushOverlayUtil,\n\tCollaboratorCursorOverlayUtil,\n\tCollaboratorHintOverlayUtil,\n\tCollaboratorScribbleOverlayUtil,\n\tCollaboratorShapeIndicatorOverlayUtil,\n\tScribbleOverlayUtil,\n\tSelectionForegroundOverlayUtil,\n\tShapeHandleOverlayUtil,\n\tShapeIndicatorOverlayUtil,\n\tSnapIndicatorOverlayUtil,\n\tZoomBrushOverlayUtil,\n] as const\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCAA4C;AAC5C,kCAAqC;AACrC,8BAAiC;AACjC,0CAA6C;AAC7C,2CAA8C;AAC9C,yCAA4C;AAC5C,6CAAgD;AAChD,mDAAsD;AACtD,iCAAoC;AACpC,4CAA+C;AAC/C,oCAAuC;AACvC,uCAA0C;AAC1C,sCAAyC;AACzC,kCAAqC;AAG9B,MAAM,sBAAsB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -52,6 +52,7 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
52
52
|
"select.pointing_selection",
|
|
53
53
|
"select.pointing_shape",
|
|
54
54
|
"select.pointing_resize_handle",
|
|
55
|
+
"select.pointing_rotate_handle",
|
|
55
56
|
"select.resizing",
|
|
56
57
|
"select.crop.idle",
|
|
57
58
|
"select.crop.pointing_crop",
|
|
@@ -73,7 +74,7 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
73
74
|
const transform = import_editor.Mat.Compose(
|
|
74
75
|
import_editor.Mat.Translate(state.bounds.x, state.bounds.y),
|
|
75
76
|
import_editor.Mat.Rotate(state.rotation),
|
|
76
|
-
import_editor.Mat.Translate(state.
|
|
77
|
+
import_editor.Mat.Translate(state.expandOffsetX, state.expandOffsetY)
|
|
77
78
|
);
|
|
78
79
|
const { overlayType, handle } = overlay.props;
|
|
79
80
|
switch (overlayType) {
|
|
@@ -93,7 +94,7 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
93
94
|
ctx.save();
|
|
94
95
|
ctx.translate(state.bounds.x, state.bounds.y);
|
|
95
96
|
ctx.rotate(state.rotation);
|
|
96
|
-
ctx.translate(state.
|
|
97
|
+
ctx.translate(state.expandOffsetX, state.expandOffsetY);
|
|
97
98
|
const colors = this._getThemeColors();
|
|
98
99
|
this._renderSelectionBox(ctx, state, colors);
|
|
99
100
|
this._renderResizeCorners(ctx, state, colors);
|
|
@@ -171,23 +172,31 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
171
172
|
isFilled: true
|
|
172
173
|
});
|
|
173
174
|
}
|
|
174
|
-
const
|
|
175
|
-
|
|
175
|
+
const cornerPoint = this._getCornerLocalPoint(
|
|
176
|
+
handle,
|
|
177
|
+
state.width,
|
|
178
|
+
state.height
|
|
179
|
+
);
|
|
180
|
+
const cornerHitHalfSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.5;
|
|
176
181
|
return new import_editor.Polygon2d({
|
|
177
|
-
points: this._localRectToPoints(
|
|
178
|
-
|
|
179
|
-
|
|
182
|
+
points: this._localRectToPoints(
|
|
183
|
+
cornerPoint.x - cornerHitHalfSize,
|
|
184
|
+
cornerPoint.y - cornerHitHalfSize,
|
|
185
|
+
cornerHitHalfSize * 2,
|
|
186
|
+
cornerHitHalfSize * 2
|
|
187
|
+
).map((p) => import_editor.Mat.applyToPoint(transform, p)),
|
|
180
188
|
isFilled: true
|
|
181
189
|
});
|
|
182
190
|
}
|
|
183
191
|
_getRotateHandleGeometry(handle, state, transform) {
|
|
184
|
-
const cornerSize = Math.max(state.
|
|
192
|
+
const cornerSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.62;
|
|
185
193
|
const center = this._getRotateHandleLocalCenter(handle, state.width, state.height, cornerSize);
|
|
186
194
|
const radius = cornerSize;
|
|
187
|
-
return new import_editor.
|
|
195
|
+
return new import_editor.Rectangle2d({
|
|
188
196
|
x: center.x - radius,
|
|
189
197
|
y: center.y - radius,
|
|
190
|
-
radius,
|
|
198
|
+
width: radius * 2,
|
|
199
|
+
height: radius * 2,
|
|
191
200
|
isFilled: true
|
|
192
201
|
}).transform(transform);
|
|
193
202
|
}
|
|
@@ -210,14 +219,14 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
210
219
|
}
|
|
211
220
|
_renderResizeCorners(ctx, state, colors) {
|
|
212
221
|
if (!state.showResizeHandles) return;
|
|
213
|
-
const {
|
|
222
|
+
const { handleSize, width, height, hideAlternateCornerHandles, showOnlyOneHandle, zoom } = state;
|
|
214
223
|
ctx.fillStyle = colors.bgColor;
|
|
215
224
|
ctx.strokeStyle = colors.strokeColor;
|
|
216
225
|
ctx.lineWidth = this.options.lineWidth / zoom;
|
|
217
226
|
const drawCorner = (x, y, hidden) => {
|
|
218
227
|
if (hidden) return;
|
|
219
|
-
ctx.fillRect(x -
|
|
220
|
-
ctx.strokeRect(x -
|
|
228
|
+
ctx.fillRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize);
|
|
229
|
+
ctx.strokeRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize);
|
|
221
230
|
};
|
|
222
231
|
drawCorner(0, 0, false);
|
|
223
232
|
drawCorner(width, 0, hideAlternateCornerHandles);
|
|
@@ -226,42 +235,42 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
226
235
|
}
|
|
227
236
|
_renderCropHandles(ctx, state, colors) {
|
|
228
237
|
if (!state.showCropHandles) return;
|
|
229
|
-
const {
|
|
230
|
-
const cropStrokeWidth =
|
|
238
|
+
const { handleSize, width, height, hideAlternateCropHandles } = state;
|
|
239
|
+
const cropStrokeWidth = handleSize / 3;
|
|
231
240
|
const offset = cropStrokeWidth / 2;
|
|
232
241
|
ctx.beginPath();
|
|
233
242
|
ctx.strokeStyle = colors.strokeColor;
|
|
234
243
|
ctx.lineWidth = cropStrokeWidth;
|
|
235
244
|
ctx.lineCap = "butt";
|
|
236
245
|
ctx.lineJoin = "miter";
|
|
237
|
-
ctx.moveTo(-offset,
|
|
246
|
+
ctx.moveTo(-offset, handleSize);
|
|
238
247
|
ctx.lineTo(-offset, -offset);
|
|
239
|
-
ctx.lineTo(
|
|
240
|
-
ctx.moveTo(width + offset, height -
|
|
248
|
+
ctx.lineTo(handleSize, -offset);
|
|
249
|
+
ctx.moveTo(width + offset, height - handleSize);
|
|
241
250
|
ctx.lineTo(width + offset, height + offset);
|
|
242
|
-
ctx.lineTo(width -
|
|
251
|
+
ctx.lineTo(width - handleSize, height + offset);
|
|
243
252
|
if (!hideAlternateCropHandles) {
|
|
244
|
-
ctx.moveTo(width -
|
|
253
|
+
ctx.moveTo(width - handleSize, -offset);
|
|
245
254
|
ctx.lineTo(width + offset, -offset);
|
|
246
|
-
ctx.lineTo(width + offset,
|
|
247
|
-
ctx.moveTo(
|
|
255
|
+
ctx.lineTo(width + offset, handleSize);
|
|
256
|
+
ctx.moveTo(handleSize, height + offset);
|
|
248
257
|
ctx.lineTo(-offset, height + offset);
|
|
249
|
-
ctx.lineTo(-offset, height -
|
|
250
|
-
ctx.moveTo(width / 2 -
|
|
251
|
-
ctx.lineTo(width / 2 +
|
|
252
|
-
ctx.moveTo(width + offset, height / 2 -
|
|
253
|
-
ctx.lineTo(width + offset, height / 2 +
|
|
254
|
-
ctx.moveTo(width / 2 -
|
|
255
|
-
ctx.lineTo(width / 2 +
|
|
256
|
-
ctx.moveTo(-offset, height / 2 -
|
|
257
|
-
ctx.lineTo(-offset, height / 2 +
|
|
258
|
+
ctx.lineTo(-offset, height - handleSize);
|
|
259
|
+
ctx.moveTo(width / 2 - handleSize, -offset);
|
|
260
|
+
ctx.lineTo(width / 2 + handleSize, -offset);
|
|
261
|
+
ctx.moveTo(width + offset, height / 2 - handleSize);
|
|
262
|
+
ctx.lineTo(width + offset, height / 2 + handleSize);
|
|
263
|
+
ctx.moveTo(width / 2 - handleSize, height + offset);
|
|
264
|
+
ctx.lineTo(width / 2 + handleSize, height + offset);
|
|
265
|
+
ctx.moveTo(-offset, height / 2 - handleSize);
|
|
266
|
+
ctx.lineTo(-offset, height / 2 + handleSize);
|
|
258
267
|
}
|
|
259
268
|
ctx.stroke();
|
|
260
269
|
}
|
|
261
270
|
_renderMobileRotateHandle(ctx, state, colors) {
|
|
262
271
|
if (!state.showMobileRotateHandle) return;
|
|
263
272
|
const { cx, cy } = this._getMobileRotateCenter(state);
|
|
264
|
-
const fgRadius = state.
|
|
273
|
+
const fgRadius = state.handleSize / SQUARE_ROOT_PI;
|
|
265
274
|
ctx.fillStyle = colors.bgColor;
|
|
266
275
|
ctx.strokeStyle = colors.strokeColor;
|
|
267
276
|
ctx.lineWidth = this.options.lineWidth / state.zoom;
|
|
@@ -278,16 +287,16 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
278
287
|
zoom,
|
|
279
288
|
width,
|
|
280
289
|
height,
|
|
281
|
-
|
|
282
|
-
|
|
290
|
+
handleSize,
|
|
291
|
+
hitTargetSizeY
|
|
283
292
|
} = state;
|
|
284
293
|
if (!shouldDisplayControls || !isCoarsePointer || !onlyShape || onlyShape.type !== "text") {
|
|
285
294
|
return;
|
|
286
295
|
}
|
|
287
|
-
const textHandleHeight = Math.min(24 / zoom, height -
|
|
296
|
+
const textHandleHeight = Math.min(24 / zoom, height - hitTargetSizeY * 3);
|
|
288
297
|
if (textHandleHeight * zoom < 4) return;
|
|
289
|
-
const hw =
|
|
290
|
-
const r =
|
|
298
|
+
const hw = handleSize / 2;
|
|
299
|
+
const r = handleSize / 4;
|
|
291
300
|
ctx.fillStyle = colors.strokeColor;
|
|
292
301
|
ctx.beginPath();
|
|
293
302
|
ctx.roundRect(0 - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r);
|
|
@@ -321,23 +330,25 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
321
330
|
const rotation = editor.getSelectionRotation();
|
|
322
331
|
const width = expandedBounds.width;
|
|
323
332
|
const height = expandedBounds.height;
|
|
324
|
-
const
|
|
325
|
-
const isTinyX = width <
|
|
326
|
-
const isTinyY = height <
|
|
327
|
-
const isSmallX = width <
|
|
328
|
-
const isSmallY = height <
|
|
329
|
-
const isSmallCropX = width <
|
|
330
|
-
const isSmallCropY = height <
|
|
333
|
+
const handleSize = 8 / zoom;
|
|
334
|
+
const isTinyX = width < handleSize * 2;
|
|
335
|
+
const isTinyY = height < handleSize * 2;
|
|
336
|
+
const isSmallX = width < handleSize * 4;
|
|
337
|
+
const isSmallY = height < handleSize * 4;
|
|
338
|
+
const isSmallCropX = width < handleSize * 5;
|
|
339
|
+
const isSmallCropY = height < handleSize * 5;
|
|
331
340
|
const mobileHandleMultiplier = isCoarsePointer ? 1.75 : 1;
|
|
332
|
-
const
|
|
333
|
-
const
|
|
334
|
-
const
|
|
335
|
-
const
|
|
336
|
-
const
|
|
341
|
+
const hitTargetSize = 6 / zoom * mobileHandleMultiplier;
|
|
342
|
+
const hitTargetSizeX = (isSmallX ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75);
|
|
343
|
+
const hitTargetSizeY = (isSmallY ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75);
|
|
344
|
+
const expandOffsetX = expandedBounds.x - bounds.x;
|
|
345
|
+
const expandOffsetY = expandedBounds.y - bounds.y;
|
|
337
346
|
const shouldDisplayControls = editor.isInAny(
|
|
338
347
|
"select.idle",
|
|
339
348
|
"select.pointing_selection",
|
|
340
349
|
"select.pointing_shape",
|
|
350
|
+
"select.pointing_resize_handle",
|
|
351
|
+
"select.pointing_rotate_handle",
|
|
341
352
|
"select.crop.idle"
|
|
342
353
|
) && !isChangingStyle && !isReadonly;
|
|
343
354
|
const showCropHandles = editor.isInAny(
|
|
@@ -366,7 +377,8 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
366
377
|
"select.crop.idle",
|
|
367
378
|
"select.crop.pointing_crop",
|
|
368
379
|
"select.crop.pointing_crop_handle",
|
|
369
|
-
"select.pointing_resize_handle"
|
|
380
|
+
"select.pointing_resize_handle",
|
|
381
|
+
"select.pointing_rotate_handle"
|
|
370
382
|
) || showSelectionBounds && editor.isIn("select.resizing") && !!(onlyShape && editor.isShapeOfType(onlyShape, "text"));
|
|
371
383
|
return {
|
|
372
384
|
bounds,
|
|
@@ -376,12 +388,12 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
376
388
|
rotation,
|
|
377
389
|
width,
|
|
378
390
|
height,
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
391
|
+
handleSize,
|
|
392
|
+
hitTargetSize,
|
|
393
|
+
hitTargetSizeX,
|
|
394
|
+
hitTargetSizeY,
|
|
395
|
+
expandOffsetX,
|
|
396
|
+
expandOffsetY,
|
|
385
397
|
isSmallX,
|
|
386
398
|
shouldDisplayControls,
|
|
387
399
|
shouldDisplayBox,
|
|
@@ -396,12 +408,12 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
396
408
|
};
|
|
397
409
|
}
|
|
398
410
|
_getMobileRotateCenter(state) {
|
|
399
|
-
const { width, height,
|
|
411
|
+
const { width, height, hitTargetSize, isSmallX, onlyShape, rotation } = state;
|
|
400
412
|
const editor = this.editor;
|
|
401
413
|
const isMediaShape = !!onlyShape && (editor.isShapeOfType(onlyShape, "image") || editor.isShapeOfType(onlyShape, "video"));
|
|
402
414
|
const isShapeTooCloseToContextualToolbar = rotation / import_editor.HALF_PI > 1.6 && rotation / import_editor.HALF_PI < 2.4;
|
|
403
|
-
const cx = isSmallX ? -
|
|
404
|
-
const cy = isSmallX ? height / 2 : isMediaShape && !isShapeTooCloseToContextualToolbar ? height +
|
|
415
|
+
const cx = isSmallX ? -hitTargetSize * 1.5 : width / 2;
|
|
416
|
+
const cy = isSmallX ? height / 2 : isMediaShape && !isShapeTooCloseToContextualToolbar ? height + hitTargetSize * 1.5 : -hitTargetSize * 1.5;
|
|
405
417
|
return { cx, cy };
|
|
406
418
|
}
|
|
407
419
|
_getThemeColors() {
|
|
@@ -420,16 +432,16 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
|
|
|
420
432
|
};
|
|
421
433
|
}
|
|
422
434
|
_getEdgeLocalRect(edge, state) {
|
|
423
|
-
const { width, height,
|
|
435
|
+
const { width, height, hitTargetSizeX, hitTargetSizeY } = state;
|
|
424
436
|
switch (edge) {
|
|
425
437
|
case "top":
|
|
426
|
-
return { x: 0, y: -
|
|
438
|
+
return { x: 0, y: -hitTargetSizeY, w: width, h: hitTargetSizeY * 2 };
|
|
427
439
|
case "right":
|
|
428
|
-
return { x: width -
|
|
440
|
+
return { x: width - hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height };
|
|
429
441
|
case "bottom":
|
|
430
|
-
return { x: 0, y: height -
|
|
442
|
+
return { x: 0, y: height - hitTargetSizeY, w: width, h: hitTargetSizeY * 2 };
|
|
431
443
|
case "left":
|
|
432
|
-
return { x: -
|
|
444
|
+
return { x: -hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height };
|
|
433
445
|
}
|
|
434
446
|
}
|
|
435
447
|
_getRotateHandleLocalCenter(corner, width, height, cornerSize) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/overlays/SelectionForegroundOverlayUtil.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tGeometry2d,\n\tHALF_PI,\n\tMat,\n\tOverlayUtil,\n\tPolygon2d,\n\tRotateCorner,\n\tSelectionCorner,\n\tSelectionEdge,\n\tTLCursorType,\n\tTLOverlay,\n\tTLSelectionHandle,\n\tTLShape,\n\tVec,\n} from '@tldraw/editor'\n\nconst SQUARE_ROOT_PI = Math.sqrt(Math.PI)\n\nconst ROTATE_CURSORS: Partial<Record<RotateCorner, TLCursorType>> = {\n\ttop_left_rotate: 'nwse-rotate',\n\ttop_right_rotate: 'nesw-rotate',\n\tbottom_left_rotate: 'swne-rotate',\n\tbottom_right_rotate: 'senw-rotate',\n}\n\nconst RESIZE_CURSORS: Partial<Record<TLSelectionHandle, TLCursorType>> = {\n\ttop_left: 'nwse-resize',\n\ttop_right: 'nesw-resize',\n\tbottom_right: 'nwse-resize',\n\tbottom_left: 'nesw-resize',\n\ttop: 'ns-resize',\n\tbottom: 'ns-resize',\n\tleft: 'ew-resize',\n\tright: 'ew-resize',\n}\n\n/** @public */\nexport interface TLSelectionForegroundOverlay extends TLOverlay {\n\tprops: {\n\t\toverlayType: 'resize_handle' | 'rotate_handle' | 'mobile_rotate'\n\t\thandle: TLSelectionHandle | RotateCorner\n\t}\n}\n\ninterface SelectionState {\n\tbounds: Box\n\tonlyShape: TLShape | null\n\tisCoarsePointer: boolean\n\tzoom: number\n\trotation: number\n\twidth: number\n\theight: number\n\tsize: number\n\ttargetSize: number\n\ttargetSizeX: number\n\ttargetSizeY: number\n\texpandDx: number\n\texpandDy: number\n\tisSmallX: boolean\n\tshouldDisplayControls: boolean\n\tshouldDisplayBox: boolean\n\tshowCropHandles: boolean\n\tshowResizeHandles: boolean\n\tshowCornerRotateHandles: boolean\n\tshowMobileRotateHandle: boolean\n\tshowHandles: boolean\n\thideAlternateCornerHandles: boolean\n\thideAlternateCropHandles: boolean\n\tshowOnlyOneHandle: boolean\n}\n\ninterface SelectionForegroundColors {\n\tstrokeColor: string\n\tbgColor: string\n}\n\n/**\n * Overlay util for selection foreground handles (resize corners/edges, rotate corners, mobile rotate).\n * Each interactive element of the selection foreground becomes its own overlay instance.\n *\n * @public\n */\nexport class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForegroundOverlay> {\n\tstatic override type = 'selection_foreground'\n\toverride options = { zIndex: 100, lineWidth: 1.5 }\n\n\toverride isActive(): boolean {\n\t\tif (!this.editor.getSelectionRotatedPageBounds()) return false\n\n\t\treturn this.editor.isInAny(\n\t\t\t'select.idle',\n\t\t\t'select.brushing',\n\t\t\t'select.scribble_brushing',\n\t\t\t'select.pointing_canvas',\n\t\t\t'select.pointing_selection',\n\t\t\t'select.pointing_shape',\n\t\t\t'select.pointing_resize_handle',\n\t\t\t'select.resizing',\n\t\t\t'select.crop.idle',\n\t\t\t'select.crop.pointing_crop',\n\t\t\t'select.crop.pointing_crop_handle'\n\t\t)\n\t}\n\n\toverride getOverlays(): TLSelectionForegroundOverlay[] {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return []\n\n\t\tconst overlays: TLSelectionForegroundOverlay[] = []\n\t\tthis._collectResizeCornerOverlays(state, overlays)\n\t\tthis._collectResizeEdgeOverlays(state, overlays)\n\t\tthis._collectRotateOverlays(state, overlays)\n\t\treturn overlays\n\t}\n\n\toverride getGeometry(overlay: TLSelectionForegroundOverlay): Geometry2d | null {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return null\n\n\t\tconst transform = Mat.Compose(\n\t\t\tMat.Translate(state.bounds.x, state.bounds.y),\n\t\t\tMat.Rotate(state.rotation),\n\t\t\tMat.Translate(state.expandDx, state.expandDy)\n\t\t)\n\n\t\tconst { overlayType, handle } = overlay.props\n\n\t\tswitch (overlayType) {\n\t\t\tcase 'resize_handle':\n\t\t\t\treturn this._getResizeHandleGeometry(handle as TLSelectionHandle, state, transform)\n\t\t\tcase 'rotate_handle':\n\t\t\t\treturn this._getRotateHandleGeometry(handle as RotateCorner, state, transform)\n\t\t\tcase 'mobile_rotate':\n\t\t\t\treturn this._getMobileRotateGeometry(state, transform)\n\t\t\tdefault:\n\t\t\t\treturn null\n\t\t}\n\t}\n\n\toverride render(ctx: CanvasRenderingContext2D, _overlays: TLSelectionForegroundOverlay[]): void {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return\n\n\t\t// Transform to local selection space; each render helper assumes this is active.\n\t\tctx.save()\n\t\tctx.translate(state.bounds.x, state.bounds.y)\n\t\tctx.rotate(state.rotation)\n\t\tctx.translate(state.expandDx, state.expandDy)\n\n\t\tconst colors = this._getThemeColors()\n\t\tthis._renderSelectionBox(ctx, state, colors)\n\t\tthis._renderResizeCorners(ctx, state, colors)\n\t\tthis._renderCropHandles(ctx, state, colors)\n\t\tthis._renderMobileRotateHandle(ctx, state, colors)\n\t\tthis._renderTextResizeHandles(ctx, state, colors)\n\n\t\tctx.restore()\n\t}\n\n\toverride getCursor(overlay: TLSelectionForegroundOverlay): TLCursorType | undefined {\n\t\tconst { overlayType, handle } = overlay.props\n\t\tswitch (overlayType) {\n\t\t\tcase 'rotate_handle':\n\t\t\t\treturn ROTATE_CURSORS[handle as RotateCorner]\n\t\t\tcase 'mobile_rotate':\n\t\t\t\treturn 'grab'\n\t\t\tcase 'resize_handle':\n\t\t\t\treturn RESIZE_CURSORS[handle as TLSelectionHandle]\n\t\t\tdefault:\n\t\t\t\treturn undefined\n\t\t}\n\t}\n\n\t// --- Overlay collection ---\n\n\tprivate _collectResizeCornerOverlays(\n\t\tstate: SelectionState,\n\t\toverlays: TLSelectionForegroundOverlay[]\n\t) {\n\t\tif (!state.showHandles) return\n\n\t\toverlays.push(this._makeOverlay('resize_handle', 'top_left'))\n\t\tif (!state.hideAlternateCornerHandles) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'top_right'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom_left'))\n\t\t}\n\t\tif (!state.showOnlyOneHandle || state.showCropHandles) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom_right'))\n\t\t}\n\t}\n\n\tprivate _collectResizeEdgeOverlays(\n\t\tstate: SelectionState,\n\t\toverlays: TLSelectionForegroundOverlay[]\n\t) {\n\t\tif (!state.showHandles) return\n\n\t\tconst {\n\t\t\tshowCropHandles,\n\t\t\thideAlternateCropHandles,\n\t\t\thideAlternateCornerHandles,\n\t\t\tshowOnlyOneHandle,\n\t\t\tisCoarsePointer,\n\t\t\tonlyShape,\n\t\t} = state\n\n\t\tconst hideVerticalEdgeTargets = showCropHandles\n\t\t\t? hideAlternateCropHandles\n\t\t\t: hideAlternateCornerHandles || showOnlyOneHandle || isCoarsePointer\n\t\tconst isMobileAndTextShape = isCoarsePointer && !!onlyShape && onlyShape.type === 'text'\n\t\tconst hideHorizontalEdgeTargets = showCropHandles\n\t\t\t? hideAlternateCropHandles\n\t\t\t: hideVerticalEdgeTargets && !isMobileAndTextShape\n\n\t\tif (!hideVerticalEdgeTargets) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'top'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom'))\n\t\t}\n\t\tif (!hideHorizontalEdgeTargets) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'right'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'left'))\n\t\t}\n\t}\n\n\tprivate _collectRotateOverlays(state: SelectionState, overlays: TLSelectionForegroundOverlay[]) {\n\t\tif (state.showCornerRotateHandles) {\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'top_left_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'top_right_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'bottom_left_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'bottom_right_rotate'))\n\t\t}\n\t\tif (state.showMobileRotateHandle) {\n\t\t\toverlays.push(this._makeOverlay('mobile_rotate', 'mobile_rotate'))\n\t\t}\n\t}\n\n\t// --- Geometry builders ---\n\n\tprivate _getResizeHandleGeometry(\n\t\thandle: TLSelectionHandle,\n\t\tstate: SelectionState,\n\t\ttransform: Mat\n\t): Geometry2d {\n\t\tif (handle === 'top' || handle === 'bottom' || handle === 'left' || handle === 'right') {\n\t\t\tconst rect = this._getEdgeLocalRect(handle, state)\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: this._localRectToPoints(rect.x, rect.y, rect.w, rect.h).map((p) =>\n\t\t\t\t\tMat.applyToPoint(transform, p)\n\t\t\t\t),\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst cp = this._getCornerLocalPoint(handle as SelectionCorner, state.width, state.height)\n\t\tconst s = Math.max(state.targetSizeX, state.targetSizeY) * 1.5\n\t\treturn new Polygon2d({\n\t\t\tpoints: this._localRectToPoints(cp.x - s, cp.y - s, s * 2, s * 2).map((p) =>\n\t\t\t\tMat.applyToPoint(transform, p)\n\t\t\t),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tprivate _getRotateHandleGeometry(\n\t\thandle: RotateCorner,\n\t\tstate: SelectionState,\n\t\ttransform: Mat\n\t): Geometry2d {\n\t\tconst cornerSize = Math.max(state.targetSizeX, state.targetSizeY) * 1.5\n\t\tconst center = this._getRotateHandleLocalCenter(handle, state.width, state.height, cornerSize)\n\t\tconst radius = cornerSize\n\t\treturn new Circle2d({\n\t\t\tx: center.x - radius,\n\t\t\ty: center.y - radius,\n\t\t\tradius,\n\t\t\tisFilled: true,\n\t\t}).transform(transform)\n\t}\n\n\tprivate _getMobileRotateGeometry(state: SelectionState, transform: Mat): Geometry2d {\n\t\tconst bgRadius = Math.max(14 * (1 / state.zoom), 20 / Math.max(1, state.zoom))\n\t\tconst { cx, cy } = this._getMobileRotateCenter(state)\n\t\treturn new Polygon2d({\n\t\t\tpoints: this._localRectToPoints(cx - bgRadius, cy - bgRadius, bgRadius * 2, bgRadius * 2).map(\n\t\t\t\t(p) => Mat.applyToPoint(transform, p)\n\t\t\t),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\t// --- Rendering (all helpers assume ctx is in local selection space) ---\n\n\tprivate _renderSelectionBox(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.shouldDisplayBox) return\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / state.zoom\n\t\tctx.strokeRect(0, 0, state.width, state.height)\n\t}\n\n\tprivate _renderResizeCorners(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showResizeHandles) return\n\n\t\tconst { size, width, height, hideAlternateCornerHandles, showOnlyOneHandle, zoom } = state\n\n\t\tctx.fillStyle = colors.bgColor\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / zoom\n\n\t\tconst drawCorner = (x: number, y: number, hidden: boolean) => {\n\t\t\tif (hidden) return\n\t\t\tctx.fillRect(x - size / 2, y - size / 2, size, size)\n\t\t\tctx.strokeRect(x - size / 2, y - size / 2, size, size)\n\t\t}\n\n\t\tdrawCorner(0, 0, false) // top-left always shown\n\t\tdrawCorner(width, 0, hideAlternateCornerHandles) // top-right\n\t\tdrawCorner(width, height, showOnlyOneHandle) // bottom-right\n\t\tdrawCorner(0, height, hideAlternateCornerHandles) // bottom-left\n\t}\n\n\tprivate _renderCropHandles(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showCropHandles) return\n\n\t\tconst { size, width, height, hideAlternateCropHandles } = state\n\t\tconst cropStrokeWidth = size / 3\n\t\tconst offset = cropStrokeWidth / 2\n\n\t\tctx.beginPath()\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = cropStrokeWidth\n\t\tctx.lineCap = 'butt'\n\t\tctx.lineJoin = 'miter'\n\n\t\t// top_left corner (always shown)\n\t\tctx.moveTo(-offset, size)\n\t\tctx.lineTo(-offset, -offset)\n\t\tctx.lineTo(size, -offset)\n\n\t\t// bottom_right corner (always shown)\n\t\tctx.moveTo(width + offset, height - size)\n\t\tctx.lineTo(width + offset, height + offset)\n\t\tctx.lineTo(width - size, height + offset)\n\n\t\tif (!hideAlternateCropHandles) {\n\t\t\t// top_right corner\n\t\t\tctx.moveTo(width - size, -offset)\n\t\t\tctx.lineTo(width + offset, -offset)\n\t\t\tctx.lineTo(width + offset, size)\n\n\t\t\t// bottom_left corner\n\t\t\tctx.moveTo(size, height + offset)\n\t\t\tctx.lineTo(-offset, height + offset)\n\t\t\tctx.lineTo(-offset, height - size)\n\n\t\t\t// top edge\n\t\t\tctx.moveTo(width / 2 - size, -offset)\n\t\t\tctx.lineTo(width / 2 + size, -offset)\n\n\t\t\t// right edge\n\t\t\tctx.moveTo(width + offset, height / 2 - size)\n\t\t\tctx.lineTo(width + offset, height / 2 + size)\n\n\t\t\t// bottom edge\n\t\t\tctx.moveTo(width / 2 - size, height + offset)\n\t\t\tctx.lineTo(width / 2 + size, height + offset)\n\n\t\t\t// left edge\n\t\t\tctx.moveTo(-offset, height / 2 - size)\n\t\t\tctx.lineTo(-offset, height / 2 + size)\n\t\t}\n\n\t\tctx.stroke()\n\t}\n\n\tprivate _renderMobileRotateHandle(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showMobileRotateHandle) return\n\n\t\tconst { cx, cy } = this._getMobileRotateCenter(state)\n\t\tconst fgRadius = state.size / SQUARE_ROOT_PI\n\n\t\tctx.fillStyle = colors.bgColor\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / state.zoom\n\t\tctx.beginPath()\n\t\tctx.arc(cx, cy, fgRadius, 0, Math.PI * 2)\n\t\tctx.fill()\n\t\tctx.stroke()\n\t}\n\n\tprivate _renderTextResizeHandles(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tconst {\n\t\t\tshouldDisplayControls,\n\t\t\tisCoarsePointer,\n\t\t\tonlyShape,\n\t\t\tzoom,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tsize,\n\t\t\ttargetSizeY,\n\t\t} = state\n\t\tif (!shouldDisplayControls || !isCoarsePointer || !onlyShape || onlyShape.type !== 'text') {\n\t\t\treturn\n\t\t}\n\n\t\tconst textHandleHeight = Math.min(24 / zoom, height - targetSizeY * 3)\n\t\tif (textHandleHeight * zoom < 4) return\n\n\t\tconst hw = size / 2\n\t\tconst r = size / 4\n\n\t\tctx.fillStyle = colors.strokeColor\n\t\tctx.beginPath()\n\t\tctx.roundRect(0 - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r)\n\t\tctx.fill()\n\t\tctx.beginPath()\n\t\tctx.roundRect(width - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r)\n\t\tctx.fill()\n\t}\n\n\t// --- Shared helpers ---\n\n\t/**\n\t * Single source of truth for the derived state the selection foreground needs.\n\t * Called from `getOverlays()`, `getGeometry()`, and `render()` so their visibility\n\t * predicates can't drift. Returns `null` when no selection UI should appear at all\n\t * (nothing selected, or the only selected shape is hidden).\n\t */\n\tprivate _computeSelectionState(): SelectionState | null {\n\t\tconst editor = this.editor\n\t\tconst bounds = editor.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return null\n\n\t\tconst onlyShape = editor.getOnlySelectedShape()\n\t\tif (onlyShape && editor.isShapeHidden(onlyShape)) return null\n\n\t\tconst onlyShapeUtil = onlyShape ? editor.getShapeUtil(onlyShape) : null\n\t\tconst isLockedShape = !!(onlyShape && editor.isShapeOrAncestorLocked(onlyShape))\n\n\t\tconst expandOutlineBy =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.expandSelectionOutlinePx(onlyShape) : 0\n\t\tconst expandedBounds =\n\t\t\texpandOutlineBy instanceof Box\n\t\t\t\t? bounds.clone().expand(expandOutlineBy).zeroFix()\n\t\t\t\t: bounds.clone().expandBy(expandOutlineBy).zeroFix()\n\n\t\tconst instanceState = editor.getInstanceState()\n\t\tconst isCoarsePointer = instanceState.isCoarsePointer\n\t\tconst isChangingStyle = instanceState.isChangingStyle\n\t\tconst isReadonly = editor.getIsReadonly()\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst rotation = editor.getSelectionRotation()\n\n\t\tconst width = expandedBounds.width\n\t\tconst height = expandedBounds.height\n\t\tconst size = 8 / zoom\n\t\tconst isTinyX = width < size * 2\n\t\tconst isTinyY = height < size * 2\n\t\tconst isSmallX = width < size * 4\n\t\tconst isSmallY = height < size * 4\n\t\tconst isSmallCropX = width < size * 5\n\t\tconst isSmallCropY = height < size * 5\n\n\t\tconst mobileHandleMultiplier = isCoarsePointer ? 1.75 : 1\n\t\tconst targetSize = (6 / zoom) * mobileHandleMultiplier\n\t\tconst targetSizeX = (isSmallX ? targetSize / 2 : targetSize) * (mobileHandleMultiplier * 0.75)\n\t\tconst targetSizeY = (isSmallY ? targetSize / 2 : targetSize) * (mobileHandleMultiplier * 0.75)\n\n\t\tconst expandDx = expandedBounds.x - bounds.x\n\t\tconst expandDy = expandedBounds.y - bounds.y\n\n\t\tconst shouldDisplayControls =\n\t\t\teditor.isInAny(\n\t\t\t\t'select.idle',\n\t\t\t\t'select.pointing_selection',\n\t\t\t\t'select.pointing_shape',\n\t\t\t\t'select.crop.idle'\n\t\t\t) &&\n\t\t\t!isChangingStyle &&\n\t\t\t!isReadonly\n\n\t\tconst showCropHandles =\n\t\t\teditor.isInAny(\n\t\t\t\t'select.crop.idle',\n\t\t\t\t'select.crop.pointing_crop',\n\t\t\t\t'select.crop.pointing_crop_handle'\n\t\t\t) && !isReadonly\n\n\t\tconst canOnlyShapeResize =\n\t\t\tonlyShape && onlyShapeUtil\n\t\t\t\t? onlyShapeUtil.canResize(onlyShape) && !onlyShapeUtil.hideResizeHandles(onlyShape)\n\t\t\t\t: true\n\t\tconst hideOnlyShapeRotateHandle =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.hideRotateHandle(onlyShape) : false\n\t\tconst hideOnlyShapeSelectionBounds =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.hideSelectionBoundsFg(onlyShape) : false\n\n\t\tconst showResizeHandles =\n\t\t\tshouldDisplayControls && !isLockedShape && !showCropHandles && canOnlyShapeResize\n\n\t\tconst showCornerRotateHandles =\n\t\t\tshouldDisplayControls &&\n\t\t\t!isLockedShape &&\n\t\t\t!isCoarsePointer &&\n\t\t\t!(isTinyX || isTinyY) &&\n\t\t\t!hideOnlyShapeRotateHandle\n\n\t\tconst showMobileRotateHandle =\n\t\t\tshouldDisplayControls &&\n\t\t\t!isLockedShape &&\n\t\t\tisCoarsePointer &&\n\t\t\t(!isSmallX || !isSmallY) &&\n\t\t\t!hideOnlyShapeRotateHandle\n\n\t\tconst hideAlternateCornerHandles = isTinyX || isTinyY\n\t\tconst hideAlternateCropHandles = isSmallCropX || isSmallCropY\n\t\tconst showOnlyOneHandle = isTinyX && isTinyY\n\t\tconst showHandles = showResizeHandles || showCropHandles\n\n\t\tconst showSelectionBounds = !hideOnlyShapeSelectionBounds && !isChangingStyle\n\n\t\tconst shouldDisplayBox =\n\t\t\t(showSelectionBounds &&\n\t\t\t\teditor.isInAny(\n\t\t\t\t\t'select.idle',\n\t\t\t\t\t'select.brushing',\n\t\t\t\t\t'select.scribble_brushing',\n\t\t\t\t\t'select.pointing_canvas',\n\t\t\t\t\t'select.pointing_selection',\n\t\t\t\t\t'select.pointing_shape',\n\t\t\t\t\t'select.crop.idle',\n\t\t\t\t\t'select.crop.pointing_crop',\n\t\t\t\t\t'select.crop.pointing_crop_handle',\n\t\t\t\t\t'select.pointing_resize_handle'\n\t\t\t\t)) ||\n\t\t\t(showSelectionBounds &&\n\t\t\t\teditor.isIn('select.resizing') &&\n\t\t\t\t!!(onlyShape && editor.isShapeOfType(onlyShape, 'text')))\n\n\t\treturn {\n\t\t\tbounds,\n\t\t\tonlyShape,\n\t\t\tisCoarsePointer,\n\t\t\tzoom,\n\t\t\trotation,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tsize,\n\t\t\ttargetSize,\n\t\t\ttargetSizeX,\n\t\t\ttargetSizeY,\n\t\t\texpandDx,\n\t\t\texpandDy,\n\t\t\tisSmallX,\n\t\t\tshouldDisplayControls,\n\t\t\tshouldDisplayBox,\n\t\t\tshowCropHandles,\n\t\t\tshowResizeHandles,\n\t\t\tshowCornerRotateHandles,\n\t\t\tshowMobileRotateHandle,\n\t\t\tshowHandles,\n\t\t\thideAlternateCornerHandles,\n\t\t\thideAlternateCropHandles,\n\t\t\tshowOnlyOneHandle,\n\t\t}\n\t}\n\n\tprivate _getMobileRotateCenter(state: SelectionState): { cx: number; cy: number } {\n\t\tconst { width, height, targetSize, isSmallX, onlyShape, rotation } = state\n\t\tconst editor = this.editor\n\t\tconst isMediaShape =\n\t\t\t!!onlyShape &&\n\t\t\t(editor.isShapeOfType(onlyShape, 'image') || editor.isShapeOfType(onlyShape, 'video'))\n\t\tconst isShapeTooCloseToContextualToolbar = rotation / HALF_PI > 1.6 && rotation / HALF_PI < 2.4\n\n\t\tconst cx = isSmallX ? -targetSize * 1.5 : width / 2\n\t\tconst cy = isSmallX\n\t\t\t? height / 2\n\t\t\t: isMediaShape && !isShapeTooCloseToContextualToolbar\n\t\t\t\t? height + targetSize * 1.5\n\t\t\t\t: -targetSize * 1.5\n\t\treturn { cx, cy }\n\t}\n\n\tprivate _getThemeColors(): SelectionForegroundColors {\n\t\tconst editor = this.editor\n\t\tconst themeColors = editor.getCurrentTheme().colors[editor.getColorMode()]\n\t\treturn {\n\t\t\tstrokeColor: themeColors.selectionStroke,\n\t\t\tbgColor: themeColors.background,\n\t\t}\n\t}\n\n\tprivate _makeOverlay(\n\t\toverlayType: TLSelectionForegroundOverlay['props']['overlayType'],\n\t\thandle: TLSelectionHandle | RotateCorner\n\t): TLSelectionForegroundOverlay {\n\t\treturn {\n\t\t\tid: `selection_fg:${handle}`,\n\t\t\ttype: 'selection_foreground',\n\t\t\tprops: { overlayType, handle },\n\t\t}\n\t}\n\n\tprivate _getEdgeLocalRect(\n\t\tedge: SelectionEdge,\n\t\tstate: SelectionState\n\t): { x: number; y: number; w: number; h: number } {\n\t\tconst { width, height, targetSizeX, targetSizeY } = state\n\t\tswitch (edge) {\n\t\t\tcase 'top':\n\t\t\t\treturn { x: 0, y: -targetSizeY, w: width, h: targetSizeY * 2 }\n\t\t\tcase 'right':\n\t\t\t\treturn { x: width - targetSizeX, y: 0, w: targetSizeX * 2, h: height }\n\t\t\tcase 'bottom':\n\t\t\t\treturn { x: 0, y: height - targetSizeY, w: width, h: targetSizeY * 2 }\n\t\t\tcase 'left':\n\t\t\t\treturn { x: -targetSizeX, y: 0, w: targetSizeX * 2, h: height }\n\t\t}\n\t}\n\n\tprivate _getRotateHandleLocalCenter(\n\t\tcorner: RotateCorner,\n\t\twidth: number,\n\t\theight: number,\n\t\tcornerSize: number\n\t): Vec {\n\t\t// Centered on the outside corner of the resize handle square\n\t\t// (the corner furthest from the selection interior)\n\t\tswitch (corner) {\n\t\t\tcase 'top_left_rotate':\n\t\t\t\treturn new Vec(-cornerSize, -cornerSize)\n\t\t\tcase 'top_right_rotate':\n\t\t\t\treturn new Vec(width + cornerSize, -cornerSize)\n\t\t\tcase 'bottom_left_rotate':\n\t\t\t\treturn new Vec(-cornerSize, height + cornerSize)\n\t\t\tcase 'bottom_right_rotate':\n\t\t\t\treturn new Vec(width + cornerSize, height + cornerSize)\n\t\t\tdefault:\n\t\t\t\treturn new Vec(0, 0)\n\t\t}\n\t}\n\n\tprivate _getCornerLocalPoint(corner: SelectionCorner, width: number, height: number): Vec {\n\t\tswitch (corner) {\n\t\t\tcase 'top_left':\n\t\t\t\treturn new Vec(0, 0)\n\t\t\tcase 'top_right':\n\t\t\t\treturn new Vec(width, 0)\n\t\t\tcase 'bottom_right':\n\t\t\t\treturn new Vec(width, height)\n\t\t\tcase 'bottom_left':\n\t\t\t\treturn new Vec(0, height)\n\t\t}\n\t}\n\n\tprivate _localRectToPoints(x: number, y: number, w: number, h: number): Vec[] {\n\t\treturn [new Vec(x, y), new Vec(x + w, y), new Vec(x + w, y + h), new Vec(x, y + h)]\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n\tBox,\n\tGeometry2d,\n\tHALF_PI,\n\tMat,\n\tOverlayUtil,\n\tPolygon2d,\n\tRectangle2d,\n\tRotateCorner,\n\tSelectionCorner,\n\tSelectionEdge,\n\tTLCursorType,\n\tTLOverlay,\n\tTLSelectionHandle,\n\tTLShape,\n\tVec,\n} from '@tldraw/editor'\n\nconst SQUARE_ROOT_PI = Math.sqrt(Math.PI)\n\nconst ROTATE_CURSORS: Partial<Record<RotateCorner, TLCursorType>> = {\n\ttop_left_rotate: 'nwse-rotate',\n\ttop_right_rotate: 'nesw-rotate',\n\tbottom_left_rotate: 'swne-rotate',\n\tbottom_right_rotate: 'senw-rotate',\n}\n\nconst RESIZE_CURSORS: Partial<Record<TLSelectionHandle, TLCursorType>> = {\n\ttop_left: 'nwse-resize',\n\ttop_right: 'nesw-resize',\n\tbottom_right: 'nwse-resize',\n\tbottom_left: 'nesw-resize',\n\ttop: 'ns-resize',\n\tbottom: 'ns-resize',\n\tleft: 'ew-resize',\n\tright: 'ew-resize',\n}\n\n/** @public */\nexport interface TLSelectionForegroundOverlay extends TLOverlay {\n\tprops: {\n\t\toverlayType: 'resize_handle' | 'rotate_handle' | 'mobile_rotate'\n\t\thandle: TLSelectionHandle | RotateCorner\n\t}\n}\n\ninterface SelectionState {\n\tbounds: Box\n\tonlyShape: TLShape | null\n\tisCoarsePointer: boolean\n\tzoom: number\n\trotation: number\n\twidth: number\n\theight: number\n\t/** Visual side length of the rendered resize-handle squares. */\n\thandleSize: number\n\t/** Base half-extent of the interactive hit target for handles. */\n\thitTargetSize: number\n\t/** Hit target half-extent along the x axis (narrower for small selections). */\n\thitTargetSizeX: number\n\t/** Hit target half-extent along the y axis (narrower for small selections). */\n\thitTargetSizeY: number\n\t/** Offset from the unexpanded bounds to the expanded selection outline. */\n\texpandOffsetX: number\n\texpandOffsetY: number\n\tisSmallX: boolean\n\tshouldDisplayControls: boolean\n\tshouldDisplayBox: boolean\n\tshowCropHandles: boolean\n\tshowResizeHandles: boolean\n\tshowCornerRotateHandles: boolean\n\tshowMobileRotateHandle: boolean\n\tshowHandles: boolean\n\thideAlternateCornerHandles: boolean\n\thideAlternateCropHandles: boolean\n\tshowOnlyOneHandle: boolean\n}\n\ninterface SelectionForegroundColors {\n\tstrokeColor: string\n\tbgColor: string\n}\n\n/**\n * Overlay util for selection foreground handles (resize corners/edges, rotate corners, mobile rotate).\n * Each interactive element of the selection foreground becomes its own overlay instance.\n *\n * @public\n */\nexport class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForegroundOverlay> {\n\tstatic override type = 'selection_foreground'\n\toverride options = { zIndex: 100, lineWidth: 1.5 }\n\n\toverride isActive(): boolean {\n\t\tif (!this.editor.getSelectionRotatedPageBounds()) return false\n\n\t\treturn this.editor.isInAny(\n\t\t\t'select.idle',\n\t\t\t'select.brushing',\n\t\t\t'select.scribble_brushing',\n\t\t\t'select.pointing_canvas',\n\t\t\t'select.pointing_selection',\n\t\t\t'select.pointing_shape',\n\t\t\t'select.pointing_resize_handle',\n\t\t\t'select.pointing_rotate_handle',\n\t\t\t'select.resizing',\n\t\t\t'select.crop.idle',\n\t\t\t'select.crop.pointing_crop',\n\t\t\t'select.crop.pointing_crop_handle'\n\t\t)\n\t}\n\n\toverride getOverlays(): TLSelectionForegroundOverlay[] {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return []\n\n\t\tconst overlays: TLSelectionForegroundOverlay[] = []\n\t\tthis._collectResizeCornerOverlays(state, overlays)\n\t\tthis._collectResizeEdgeOverlays(state, overlays)\n\t\tthis._collectRotateOverlays(state, overlays)\n\t\treturn overlays\n\t}\n\n\toverride getGeometry(overlay: TLSelectionForegroundOverlay): Geometry2d | null {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return null\n\n\t\tconst transform = Mat.Compose(\n\t\t\tMat.Translate(state.bounds.x, state.bounds.y),\n\t\t\tMat.Rotate(state.rotation),\n\t\t\tMat.Translate(state.expandOffsetX, state.expandOffsetY)\n\t\t)\n\n\t\tconst { overlayType, handle } = overlay.props\n\n\t\tswitch (overlayType) {\n\t\t\tcase 'resize_handle':\n\t\t\t\treturn this._getResizeHandleGeometry(handle as TLSelectionHandle, state, transform)\n\t\t\tcase 'rotate_handle':\n\t\t\t\treturn this._getRotateHandleGeometry(handle as RotateCorner, state, transform)\n\t\t\tcase 'mobile_rotate':\n\t\t\t\treturn this._getMobileRotateGeometry(state, transform)\n\t\t\tdefault:\n\t\t\t\treturn null\n\t\t}\n\t}\n\n\toverride render(ctx: CanvasRenderingContext2D, _overlays: TLSelectionForegroundOverlay[]): void {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return\n\n\t\t// Transform to local selection space; each render helper assumes this is active.\n\t\tctx.save()\n\t\tctx.translate(state.bounds.x, state.bounds.y)\n\t\tctx.rotate(state.rotation)\n\t\tctx.translate(state.expandOffsetX, state.expandOffsetY)\n\n\t\tconst colors = this._getThemeColors()\n\t\tthis._renderSelectionBox(ctx, state, colors)\n\t\tthis._renderResizeCorners(ctx, state, colors)\n\t\tthis._renderCropHandles(ctx, state, colors)\n\t\tthis._renderMobileRotateHandle(ctx, state, colors)\n\t\tthis._renderTextResizeHandles(ctx, state, colors)\n\n\t\tctx.restore()\n\t}\n\n\toverride getCursor(overlay: TLSelectionForegroundOverlay): TLCursorType | undefined {\n\t\tconst { overlayType, handle } = overlay.props\n\t\tswitch (overlayType) {\n\t\t\tcase 'rotate_handle':\n\t\t\t\treturn ROTATE_CURSORS[handle as RotateCorner]\n\t\t\tcase 'mobile_rotate':\n\t\t\t\treturn 'grab'\n\t\t\tcase 'resize_handle':\n\t\t\t\treturn RESIZE_CURSORS[handle as TLSelectionHandle]\n\t\t\tdefault:\n\t\t\t\treturn undefined\n\t\t}\n\t}\n\n\t// --- Overlay collection ---\n\n\tprivate _collectResizeCornerOverlays(\n\t\tstate: SelectionState,\n\t\toverlays: TLSelectionForegroundOverlay[]\n\t) {\n\t\tif (!state.showHandles) return\n\n\t\toverlays.push(this._makeOverlay('resize_handle', 'top_left'))\n\t\tif (!state.hideAlternateCornerHandles) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'top_right'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom_left'))\n\t\t}\n\t\tif (!state.showOnlyOneHandle || state.showCropHandles) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom_right'))\n\t\t}\n\t}\n\n\tprivate _collectResizeEdgeOverlays(\n\t\tstate: SelectionState,\n\t\toverlays: TLSelectionForegroundOverlay[]\n\t) {\n\t\tif (!state.showHandles) return\n\n\t\tconst {\n\t\t\tshowCropHandles,\n\t\t\thideAlternateCropHandles,\n\t\t\thideAlternateCornerHandles,\n\t\t\tshowOnlyOneHandle,\n\t\t\tisCoarsePointer,\n\t\t\tonlyShape,\n\t\t} = state\n\n\t\tconst hideVerticalEdgeTargets = showCropHandles\n\t\t\t? hideAlternateCropHandles\n\t\t\t: hideAlternateCornerHandles || showOnlyOneHandle || isCoarsePointer\n\t\tconst isMobileAndTextShape = isCoarsePointer && !!onlyShape && onlyShape.type === 'text'\n\t\tconst hideHorizontalEdgeTargets = showCropHandles\n\t\t\t? hideAlternateCropHandles\n\t\t\t: hideVerticalEdgeTargets && !isMobileAndTextShape\n\n\t\tif (!hideVerticalEdgeTargets) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'top'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom'))\n\t\t}\n\t\tif (!hideHorizontalEdgeTargets) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'right'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'left'))\n\t\t}\n\t}\n\n\tprivate _collectRotateOverlays(state: SelectionState, overlays: TLSelectionForegroundOverlay[]) {\n\t\tif (state.showCornerRotateHandles) {\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'top_left_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'top_right_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'bottom_left_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'bottom_right_rotate'))\n\t\t}\n\t\tif (state.showMobileRotateHandle) {\n\t\t\toverlays.push(this._makeOverlay('mobile_rotate', 'mobile_rotate'))\n\t\t}\n\t}\n\n\t// --- Geometry builders ---\n\n\tprivate _getResizeHandleGeometry(\n\t\thandle: TLSelectionHandle,\n\t\tstate: SelectionState,\n\t\ttransform: Mat\n\t): Geometry2d {\n\t\tif (handle === 'top' || handle === 'bottom' || handle === 'left' || handle === 'right') {\n\t\t\tconst rect = this._getEdgeLocalRect(handle, state)\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: this._localRectToPoints(rect.x, rect.y, rect.w, rect.h).map((p) =>\n\t\t\t\t\tMat.applyToPoint(transform, p)\n\t\t\t\t),\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst cornerPoint = this._getCornerLocalPoint(\n\t\t\thandle as SelectionCorner,\n\t\t\tstate.width,\n\t\t\tstate.height\n\t\t)\n\t\tconst cornerHitHalfSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.5\n\t\treturn new Polygon2d({\n\t\t\tpoints: this._localRectToPoints(\n\t\t\t\tcornerPoint.x - cornerHitHalfSize,\n\t\t\t\tcornerPoint.y - cornerHitHalfSize,\n\t\t\t\tcornerHitHalfSize * 2,\n\t\t\t\tcornerHitHalfSize * 2\n\t\t\t).map((p) => Mat.applyToPoint(transform, p)),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tprivate _getRotateHandleGeometry(\n\t\thandle: RotateCorner,\n\t\tstate: SelectionState,\n\t\ttransform: Mat\n\t): Geometry2d {\n\t\tconst cornerSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.62\n\t\tconst center = this._getRotateHandleLocalCenter(handle, state.width, state.height, cornerSize)\n\t\tconst radius = cornerSize\n\t\treturn new Rectangle2d({\n\t\t\tx: center.x - radius,\n\t\t\ty: center.y - radius,\n\t\t\twidth: radius * 2,\n\t\t\theight: radius * 2,\n\t\t\tisFilled: true,\n\t\t}).transform(transform)\n\t}\n\n\tprivate _getMobileRotateGeometry(state: SelectionState, transform: Mat): Geometry2d {\n\t\tconst bgRadius = Math.max(14 * (1 / state.zoom), 20 / Math.max(1, state.zoom))\n\t\tconst { cx, cy } = this._getMobileRotateCenter(state)\n\t\treturn new Polygon2d({\n\t\t\tpoints: this._localRectToPoints(cx - bgRadius, cy - bgRadius, bgRadius * 2, bgRadius * 2).map(\n\t\t\t\t(p) => Mat.applyToPoint(transform, p)\n\t\t\t),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\t// --- Rendering (all helpers assume ctx is in local selection space) ---\n\n\tprivate _renderSelectionBox(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.shouldDisplayBox) return\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / state.zoom\n\t\tctx.strokeRect(0, 0, state.width, state.height)\n\t}\n\n\tprivate _renderResizeCorners(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showResizeHandles) return\n\n\t\tconst { handleSize, width, height, hideAlternateCornerHandles, showOnlyOneHandle, zoom } = state\n\n\t\tctx.fillStyle = colors.bgColor\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / zoom\n\n\t\tconst drawCorner = (x: number, y: number, hidden: boolean) => {\n\t\t\tif (hidden) return\n\t\t\tctx.fillRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize)\n\t\t\tctx.strokeRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize)\n\t\t}\n\n\t\tdrawCorner(0, 0, false) // top-left always shown\n\t\tdrawCorner(width, 0, hideAlternateCornerHandles) // top-right\n\t\tdrawCorner(width, height, showOnlyOneHandle) // bottom-right\n\t\tdrawCorner(0, height, hideAlternateCornerHandles) // bottom-left\n\t}\n\n\tprivate _renderCropHandles(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showCropHandles) return\n\n\t\tconst { handleSize, width, height, hideAlternateCropHandles } = state\n\t\tconst cropStrokeWidth = handleSize / 3\n\t\tconst offset = cropStrokeWidth / 2\n\n\t\tctx.beginPath()\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = cropStrokeWidth\n\t\tctx.lineCap = 'butt'\n\t\tctx.lineJoin = 'miter'\n\n\t\t// top_left corner (always shown)\n\t\tctx.moveTo(-offset, handleSize)\n\t\tctx.lineTo(-offset, -offset)\n\t\tctx.lineTo(handleSize, -offset)\n\n\t\t// bottom_right corner (always shown)\n\t\tctx.moveTo(width + offset, height - handleSize)\n\t\tctx.lineTo(width + offset, height + offset)\n\t\tctx.lineTo(width - handleSize, height + offset)\n\n\t\tif (!hideAlternateCropHandles) {\n\t\t\t// top_right corner\n\t\t\tctx.moveTo(width - handleSize, -offset)\n\t\t\tctx.lineTo(width + offset, -offset)\n\t\t\tctx.lineTo(width + offset, handleSize)\n\n\t\t\t// bottom_left corner\n\t\t\tctx.moveTo(handleSize, height + offset)\n\t\t\tctx.lineTo(-offset, height + offset)\n\t\t\tctx.lineTo(-offset, height - handleSize)\n\n\t\t\t// top edge\n\t\t\tctx.moveTo(width / 2 - handleSize, -offset)\n\t\t\tctx.lineTo(width / 2 + handleSize, -offset)\n\n\t\t\t// right edge\n\t\t\tctx.moveTo(width + offset, height / 2 - handleSize)\n\t\t\tctx.lineTo(width + offset, height / 2 + handleSize)\n\n\t\t\t// bottom edge\n\t\t\tctx.moveTo(width / 2 - handleSize, height + offset)\n\t\t\tctx.lineTo(width / 2 + handleSize, height + offset)\n\n\t\t\t// left edge\n\t\t\tctx.moveTo(-offset, height / 2 - handleSize)\n\t\t\tctx.lineTo(-offset, height / 2 + handleSize)\n\t\t}\n\n\t\tctx.stroke()\n\t}\n\n\tprivate _renderMobileRotateHandle(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showMobileRotateHandle) return\n\n\t\tconst { cx, cy } = this._getMobileRotateCenter(state)\n\t\tconst fgRadius = state.handleSize / SQUARE_ROOT_PI\n\n\t\tctx.fillStyle = colors.bgColor\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / state.zoom\n\t\tctx.beginPath()\n\t\tctx.arc(cx, cy, fgRadius, 0, Math.PI * 2)\n\t\tctx.fill()\n\t\tctx.stroke()\n\t}\n\n\tprivate _renderTextResizeHandles(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tconst {\n\t\t\tshouldDisplayControls,\n\t\t\tisCoarsePointer,\n\t\t\tonlyShape,\n\t\t\tzoom,\n\t\t\twidth,\n\t\t\theight,\n\t\t\thandleSize,\n\t\t\thitTargetSizeY,\n\t\t} = state\n\t\tif (!shouldDisplayControls || !isCoarsePointer || !onlyShape || onlyShape.type !== 'text') {\n\t\t\treturn\n\t\t}\n\n\t\tconst textHandleHeight = Math.min(24 / zoom, height - hitTargetSizeY * 3)\n\t\tif (textHandleHeight * zoom < 4) return\n\n\t\tconst hw = handleSize / 2\n\t\tconst r = handleSize / 4\n\n\t\tctx.fillStyle = colors.strokeColor\n\t\tctx.beginPath()\n\t\tctx.roundRect(0 - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r)\n\t\tctx.fill()\n\t\tctx.beginPath()\n\t\tctx.roundRect(width - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r)\n\t\tctx.fill()\n\t}\n\n\t// --- Shared helpers ---\n\n\t/**\n\t * Single source of truth for the derived state the selection foreground needs.\n\t * Called from `getOverlays()`, `getGeometry()`, and `render()` so their visibility\n\t * predicates can't drift. Returns `null` when no selection UI should appear at all\n\t * (nothing selected, or the only selected shape is hidden).\n\t */\n\tprivate _computeSelectionState(): SelectionState | null {\n\t\tconst editor = this.editor\n\t\tconst bounds = editor.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return null\n\n\t\tconst onlyShape = editor.getOnlySelectedShape()\n\t\tif (onlyShape && editor.isShapeHidden(onlyShape)) return null\n\n\t\tconst onlyShapeUtil = onlyShape ? editor.getShapeUtil(onlyShape) : null\n\t\tconst isLockedShape = !!(onlyShape && editor.isShapeOrAncestorLocked(onlyShape))\n\n\t\tconst expandOutlineBy =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.expandSelectionOutlinePx(onlyShape) : 0\n\t\tconst expandedBounds =\n\t\t\texpandOutlineBy instanceof Box\n\t\t\t\t? bounds.clone().expand(expandOutlineBy).zeroFix()\n\t\t\t\t: bounds.clone().expandBy(expandOutlineBy).zeroFix()\n\n\t\tconst instanceState = editor.getInstanceState()\n\t\tconst isCoarsePointer = instanceState.isCoarsePointer\n\t\tconst isChangingStyle = instanceState.isChangingStyle\n\t\tconst isReadonly = editor.getIsReadonly()\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst rotation = editor.getSelectionRotation()\n\n\t\tconst width = expandedBounds.width\n\t\tconst height = expandedBounds.height\n\t\tconst handleSize = 8 / zoom\n\t\tconst isTinyX = width < handleSize * 2\n\t\tconst isTinyY = height < handleSize * 2\n\t\tconst isSmallX = width < handleSize * 4\n\t\tconst isSmallY = height < handleSize * 4\n\t\tconst isSmallCropX = width < handleSize * 5\n\t\tconst isSmallCropY = height < handleSize * 5\n\n\t\tconst mobileHandleMultiplier = isCoarsePointer ? 1.75 : 1\n\t\tconst hitTargetSize = (6 / zoom) * mobileHandleMultiplier\n\t\tconst hitTargetSizeX =\n\t\t\t(isSmallX ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75)\n\t\tconst hitTargetSizeY =\n\t\t\t(isSmallY ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75)\n\n\t\tconst expandOffsetX = expandedBounds.x - bounds.x\n\t\tconst expandOffsetY = expandedBounds.y - bounds.y\n\n\t\tconst shouldDisplayControls =\n\t\t\teditor.isInAny(\n\t\t\t\t'select.idle',\n\t\t\t\t'select.pointing_selection',\n\t\t\t\t'select.pointing_shape',\n\t\t\t\t'select.pointing_resize_handle',\n\t\t\t\t'select.pointing_rotate_handle',\n\t\t\t\t'select.crop.idle'\n\t\t\t) &&\n\t\t\t!isChangingStyle &&\n\t\t\t!isReadonly\n\n\t\tconst showCropHandles =\n\t\t\teditor.isInAny(\n\t\t\t\t'select.crop.idle',\n\t\t\t\t'select.crop.pointing_crop',\n\t\t\t\t'select.crop.pointing_crop_handle'\n\t\t\t) && !isReadonly\n\n\t\tconst canOnlyShapeResize =\n\t\t\tonlyShape && onlyShapeUtil\n\t\t\t\t? onlyShapeUtil.canResize(onlyShape) && !onlyShapeUtil.hideResizeHandles(onlyShape)\n\t\t\t\t: true\n\t\tconst hideOnlyShapeRotateHandle =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.hideRotateHandle(onlyShape) : false\n\t\tconst hideOnlyShapeSelectionBounds =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.hideSelectionBoundsFg(onlyShape) : false\n\n\t\tconst showResizeHandles =\n\t\t\tshouldDisplayControls && !isLockedShape && !showCropHandles && canOnlyShapeResize\n\n\t\tconst showCornerRotateHandles =\n\t\t\tshouldDisplayControls &&\n\t\t\t!isLockedShape &&\n\t\t\t!isCoarsePointer &&\n\t\t\t!(isTinyX || isTinyY) &&\n\t\t\t!hideOnlyShapeRotateHandle\n\n\t\tconst showMobileRotateHandle =\n\t\t\tshouldDisplayControls &&\n\t\t\t!isLockedShape &&\n\t\t\tisCoarsePointer &&\n\t\t\t(!isSmallX || !isSmallY) &&\n\t\t\t!hideOnlyShapeRotateHandle\n\n\t\tconst hideAlternateCornerHandles = isTinyX || isTinyY\n\t\tconst hideAlternateCropHandles = isSmallCropX || isSmallCropY\n\t\tconst showOnlyOneHandle = isTinyX && isTinyY\n\t\tconst showHandles = showResizeHandles || showCropHandles\n\n\t\tconst showSelectionBounds = !hideOnlyShapeSelectionBounds && !isChangingStyle\n\n\t\tconst shouldDisplayBox =\n\t\t\t(showSelectionBounds &&\n\t\t\t\teditor.isInAny(\n\t\t\t\t\t'select.idle',\n\t\t\t\t\t'select.brushing',\n\t\t\t\t\t'select.scribble_brushing',\n\t\t\t\t\t'select.pointing_canvas',\n\t\t\t\t\t'select.pointing_selection',\n\t\t\t\t\t'select.pointing_shape',\n\t\t\t\t\t'select.crop.idle',\n\t\t\t\t\t'select.crop.pointing_crop',\n\t\t\t\t\t'select.crop.pointing_crop_handle',\n\t\t\t\t\t'select.pointing_resize_handle',\n\t\t\t\t\t'select.pointing_rotate_handle'\n\t\t\t\t)) ||\n\t\t\t(showSelectionBounds &&\n\t\t\t\teditor.isIn('select.resizing') &&\n\t\t\t\t!!(onlyShape && editor.isShapeOfType(onlyShape, 'text')))\n\n\t\treturn {\n\t\t\tbounds,\n\t\t\tonlyShape,\n\t\t\tisCoarsePointer,\n\t\t\tzoom,\n\t\t\trotation,\n\t\t\twidth,\n\t\t\theight,\n\t\t\thandleSize,\n\t\t\thitTargetSize,\n\t\t\thitTargetSizeX,\n\t\t\thitTargetSizeY,\n\t\t\texpandOffsetX,\n\t\t\texpandOffsetY,\n\t\t\tisSmallX,\n\t\t\tshouldDisplayControls,\n\t\t\tshouldDisplayBox,\n\t\t\tshowCropHandles,\n\t\t\tshowResizeHandles,\n\t\t\tshowCornerRotateHandles,\n\t\t\tshowMobileRotateHandle,\n\t\t\tshowHandles,\n\t\t\thideAlternateCornerHandles,\n\t\t\thideAlternateCropHandles,\n\t\t\tshowOnlyOneHandle,\n\t\t}\n\t}\n\n\tprivate _getMobileRotateCenter(state: SelectionState): { cx: number; cy: number } {\n\t\tconst { width, height, hitTargetSize, isSmallX, onlyShape, rotation } = state\n\t\tconst editor = this.editor\n\t\tconst isMediaShape =\n\t\t\t!!onlyShape &&\n\t\t\t(editor.isShapeOfType(onlyShape, 'image') || editor.isShapeOfType(onlyShape, 'video'))\n\t\tconst isShapeTooCloseToContextualToolbar = rotation / HALF_PI > 1.6 && rotation / HALF_PI < 2.4\n\n\t\tconst cx = isSmallX ? -hitTargetSize * 1.5 : width / 2\n\t\tconst cy = isSmallX\n\t\t\t? height / 2\n\t\t\t: isMediaShape && !isShapeTooCloseToContextualToolbar\n\t\t\t\t? height + hitTargetSize * 1.5\n\t\t\t\t: -hitTargetSize * 1.5\n\t\treturn { cx, cy }\n\t}\n\n\tprivate _getThemeColors(): SelectionForegroundColors {\n\t\tconst editor = this.editor\n\t\tconst themeColors = editor.getCurrentTheme().colors[editor.getColorMode()]\n\t\treturn {\n\t\t\tstrokeColor: themeColors.selectionStroke,\n\t\t\tbgColor: themeColors.background,\n\t\t}\n\t}\n\n\tprivate _makeOverlay(\n\t\toverlayType: TLSelectionForegroundOverlay['props']['overlayType'],\n\t\thandle: TLSelectionHandle | RotateCorner\n\t): TLSelectionForegroundOverlay {\n\t\treturn {\n\t\t\tid: `selection_fg:${handle}`,\n\t\t\ttype: 'selection_foreground',\n\t\t\tprops: { overlayType, handle },\n\t\t}\n\t}\n\n\tprivate _getEdgeLocalRect(\n\t\tedge: SelectionEdge,\n\t\tstate: SelectionState\n\t): { x: number; y: number; w: number; h: number } {\n\t\tconst { width, height, hitTargetSizeX, hitTargetSizeY } = state\n\t\tswitch (edge) {\n\t\t\tcase 'top':\n\t\t\t\treturn { x: 0, y: -hitTargetSizeY, w: width, h: hitTargetSizeY * 2 }\n\t\t\tcase 'right':\n\t\t\t\treturn { x: width - hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height }\n\t\t\tcase 'bottom':\n\t\t\t\treturn { x: 0, y: height - hitTargetSizeY, w: width, h: hitTargetSizeY * 2 }\n\t\t\tcase 'left':\n\t\t\t\treturn { x: -hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height }\n\t\t}\n\t}\n\n\tprivate _getRotateHandleLocalCenter(\n\t\tcorner: RotateCorner,\n\t\twidth: number,\n\t\theight: number,\n\t\tcornerSize: number\n\t): Vec {\n\t\t// Centered on the outside corner of the resize handle square\n\t\t// (the corner furthest from the selection interior)\n\t\tswitch (corner) {\n\t\t\tcase 'top_left_rotate':\n\t\t\t\treturn new Vec(-cornerSize, -cornerSize)\n\t\t\tcase 'top_right_rotate':\n\t\t\t\treturn new Vec(width + cornerSize, -cornerSize)\n\t\t\tcase 'bottom_left_rotate':\n\t\t\t\treturn new Vec(-cornerSize, height + cornerSize)\n\t\t\tcase 'bottom_right_rotate':\n\t\t\t\treturn new Vec(width + cornerSize, height + cornerSize)\n\t\t\tdefault:\n\t\t\t\treturn new Vec(0, 0)\n\t\t}\n\t}\n\n\tprivate _getCornerLocalPoint(corner: SelectionCorner, width: number, height: number): Vec {\n\t\tswitch (corner) {\n\t\t\tcase 'top_left':\n\t\t\t\treturn new Vec(0, 0)\n\t\t\tcase 'top_right':\n\t\t\t\treturn new Vec(width, 0)\n\t\t\tcase 'bottom_right':\n\t\t\t\treturn new Vec(width, height)\n\t\t\tcase 'bottom_left':\n\t\t\t\treturn new Vec(0, height)\n\t\t}\n\t}\n\n\tprivate _localRectToPoints(x: number, y: number, w: number, h: number): Vec[] {\n\t\treturn [new Vec(x, y), new Vec(x + w, y), new Vec(x + w, y + h), new Vec(x, y + h)]\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -32,7 +32,7 @@ class ShapeHandleOverlayUtil extends import_editor.OverlayUtil {
|
|
|
32
32
|
if (!onlySelectedShape) return false;
|
|
33
33
|
const handles = editor.getShapeHandles(onlySelectedShape);
|
|
34
34
|
if (!handles) return false;
|
|
35
|
-
if (editor.isInAny("select.idle", "select.pointing_handle"
|
|
35
|
+
if (editor.isInAny("select.idle", "select.pointing_handle")) {
|
|
36
36
|
return true;
|
|
37
37
|
}
|
|
38
38
|
if (editor.isIn("select.editing_shape")) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/overlays/ShapeHandleOverlayUtil.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tCircle2d,\n\tGeometry2d,\n\tMat,\n\tOverlayUtil,\n\tSIDES,\n\tTLCursorType,\n\tTLHandle,\n\tTLOverlay,\n\tTLShapeId,\n\tVec,\n} from '@tldraw/editor'\n\n/** @public */\nexport interface TLShapeHandleOverlay extends TLOverlay {\n\tprops: {\n\t\tshapeId: TLShapeId\n\t\thandle: TLHandle\n\t}\n}\n\n/**\n * Overlay util for shape handles (arrow endpoints, line vertices, etc.).\n *\n * @public\n */\nexport class ShapeHandleOverlayUtil extends OverlayUtil<TLShapeHandleOverlay> {\n\tstatic override type = 'shape_handle'\n\toverride options = { zIndex: 200, lineWidth: 1.5 }\n\n\toverride isActive(): boolean {\n\t\tconst editor = this.editor\n\t\tif (editor.getIsReadonly() || editor.getInstanceState().isChangingStyle) return false\n\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return false\n\n\t\tconst handles = editor.getShapeHandles(onlySelectedShape)\n\t\tif (!handles) return false\n\n\t\tif (editor.isInAny('select.idle', 'select.pointing_handle'
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAWO;AAeA,MAAM,+BAA+B,0BAAkC;AAAA,EAC7E,OAAgB,OAAO;AAAA,EACd,UAAU,EAAE,QAAQ,KAAK,WAAW,IAAI;AAAA,EAExC,WAAoB;AAC5B,UAAM,SAAS,KAAK;AACpB,QAAI,OAAO,cAAc,KAAK,OAAO,iBAAiB,EAAE,gBAAiB,QAAO;AAEhF,UAAM,oBAAoB,OAAO,qBAAqB;AACtD,QAAI,CAAC,kBAAmB,QAAO;AAE/B,UAAM,UAAU,OAAO,gBAAgB,iBAAiB;AACxD,QAAI,CAAC,QAAS,QAAO;
|
|
4
|
+
"sourcesContent": ["import {\n\tCircle2d,\n\tGeometry2d,\n\tMat,\n\tOverlayUtil,\n\tSIDES,\n\tTLCursorType,\n\tTLHandle,\n\tTLOverlay,\n\tTLShapeId,\n\tVec,\n} from '@tldraw/editor'\n\n/** @public */\nexport interface TLShapeHandleOverlay extends TLOverlay {\n\tprops: {\n\t\tshapeId: TLShapeId\n\t\thandle: TLHandle\n\t}\n}\n\n/**\n * Overlay util for shape handles (arrow endpoints, line vertices, etc.).\n *\n * @public\n */\nexport class ShapeHandleOverlayUtil extends OverlayUtil<TLShapeHandleOverlay> {\n\tstatic override type = 'shape_handle'\n\toverride options = { zIndex: 200, lineWidth: 1.5 }\n\n\toverride isActive(): boolean {\n\t\tconst editor = this.editor\n\t\tif (editor.getIsReadonly() || editor.getInstanceState().isChangingStyle) return false\n\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return false\n\n\t\tconst handles = editor.getShapeHandles(onlySelectedShape)\n\t\tif (!handles) return false\n\n\t\t// Not shown in select.pointing_shape: hiding handles on pointer down\n\t\t// matches the arrow binding hint, which also waits for pointer up.\n\t\tif (editor.isInAny('select.idle', 'select.pointing_handle')) {\n\t\t\treturn true\n\t\t}\n\n\t\tif (editor.isIn('select.editing_shape')) {\n\t\t\treturn editor.isShapeOfType(onlySelectedShape, 'note')\n\t\t}\n\n\t\treturn false\n\t}\n\n\toverride getOverlays(): TLShapeHandleOverlay[] {\n\t\tconst editor = this.editor\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return []\n\n\t\tconst handles = editor.getShapeHandles(onlySelectedShape)\n\t\tif (!handles) return []\n\n\t\tif (editor.isShapeHidden(onlySelectedShape)) return []\n\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst isCoarse = editor.getInstanceState().isCoarsePointer\n\t\tconst minDist =\n\t\t\t((isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom) * 2\n\n\t\tconst vertexHandles = handles.filter((handle) => handle.type === 'vertex')\n\t\tconst vertexHandlesForHitTest: TLHandle[] = []\n\t\tconst otherHandlesForHitTest: TLHandle[] = []\n\n\t\t// Vertex handles come first so they win hit-testing against overlapping\n\t\t// virtual/create handles (e.g., a line's midpoint create handle that\n\t\t// coincides with its endpoint vertices when a segment is very short).\n\t\t// `render` iterates this array in reverse so the painted order puts\n\t\t// vertex handles on top visually, matching the main branch's paint\n\t\t// order where vertex handles were sorted last.\n\t\tfor (const handle of handles) {\n\t\t\tif (\n\t\t\t\thandle.type === 'virtual' &&\n\t\t\t\tvertexHandles.some((vertexHandle) => Vec.Dist(handle, vertexHandle) < minDist)\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (handle.type === 'vertex') {\n\t\t\t\tvertexHandlesForHitTest.push(handle)\n\t\t\t} else {\n\t\t\t\totherHandlesForHitTest.push(handle)\n\t\t\t}\n\t\t}\n\n\t\treturn vertexHandlesForHitTest.concat(otherHandlesForHitTest).map((handle) => ({\n\t\t\tid: `handle:${onlySelectedShape.id}:${handle.id}`,\n\t\t\ttype: 'shape_handle',\n\t\t\tprops: {\n\t\t\t\tshapeId: onlySelectedShape.id,\n\t\t\t\thandle,\n\t\t\t},\n\t\t}))\n\t}\n\n\toverride getGeometry(overlay: TLShapeHandleOverlay): Geometry2d | null {\n\t\tconst editor = this.editor\n\t\tconst { shapeId, handle } = overlay.props\n\t\tconst transform = editor.getShapePageTransform(shapeId)\n\t\tif (!transform) return null\n\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst isCoarse = editor.getInstanceState().isCoarsePointer\n\t\tconst radius =\n\t\t\t(isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom\n\n\t\t// Transform handle position to page space\n\t\tconst pagePoint = Mat.applyToPoint(transform, { x: handle.x, y: handle.y })\n\n\t\treturn new Circle2d({\n\t\t\tx: pagePoint.x - radius,\n\t\t\ty: pagePoint.y - radius,\n\t\t\tradius,\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\toverride getCursor(_overlay: TLShapeHandleOverlay): TLCursorType | undefined {\n\t\treturn 'grab' as TLCursorType\n\t}\n\n\toverride render(ctx: CanvasRenderingContext2D, overlays: TLShapeHandleOverlay[]): void {\n\t\tif (overlays.length === 0) return\n\n\t\tconst editor = this.editor\n\t\tconst shapeId = overlays[0].props.shapeId\n\t\tconst transform = editor.getShapePageTransform(shapeId)\n\t\tif (!transform) return\n\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst isCoarse = editor.getInstanceState().isCoarsePointer\n\t\tconst themeColors = editor.getCurrentTheme().colors[editor.getColorMode()]\n\t\tconst fgColor = themeColors.selectedContrast\n\t\tconst strokeColor = themeColors.selectionStroke\n\t\tconst bgFill = themeColors.selectionFill\n\t\tconst hoveredOverlayId = editor.overlays.getHoveredOverlayId()\n\t\tconst bgRadius =\n\t\t\t(isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom\n\n\t\tctx.save()\n\t\tctx.transform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f)\n\n\t\tctx.strokeStyle = strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / zoom\n\n\t\t// Iterate in reverse: vertex handles come first in the array (for hit-\n\t\t// test priority) but should paint last so they visually sit on top of\n\t\t// overlapping virtual/create handles.\n\t\tfor (let i = overlays.length - 1; i >= 0; i--) {\n\t\t\tconst overlay = overlays[i]\n\t\t\tconst { handle } = overlay.props\n\t\t\tconst isHovered = overlay.id === hoveredOverlayId\n\n\t\t\t// 'create' handles are invisible on fine pointers and revealed on\n\t\t\t// hover (matches the old .tl-handle__create opacity rules).\n\t\t\tif (handle.type === 'create' && !isCoarse && !isHovered) continue\n\n\t\t\t// Hover halo \u2014 matches the old .tl-handle__bg:hover fill rule.\n\t\t\tif (isHovered) {\n\t\t\t\tctx.fillStyle = bgFill\n\t\t\t\tctx.beginPath()\n\t\t\t\tctx.arc(handle.x, handle.y, bgRadius, 0, Math.PI * 2)\n\t\t\t\tctx.fill()\n\t\t\t}\n\n\t\t\tif (handle.type === 'clone') {\n\t\t\t\t// Note clone handles render as a side-facing half circle.\n\t\t\t\tconst fr = 3 / zoom\n\t\t\t\tconst sideIndex = SIDES.indexOf(handle.id as (typeof SIDES)[number])\n\t\t\t\tconst rotation = (-Math.PI / 2) * (1 - sideIndex)\n\n\t\t\t\tctx.save()\n\t\t\t\tctx.translate(handle.x, handle.y)\n\t\t\t\tctx.rotate(rotation)\n\t\t\t\tctx.fillStyle = strokeColor\n\t\t\t\tctx.beginPath()\n\t\t\t\tctx.moveTo(0, -fr)\n\t\t\t\tctx.arc(0, 0, fr, -Math.PI / 2, Math.PI / 2)\n\t\t\t\tctx.closePath()\n\t\t\t\tctx.fill()\n\t\t\t\tctx.restore()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Match the old DefaultHandle sizing: create handles on coarse\n\t\t\t// pointers are slightly smaller (3px) since they're always visible;\n\t\t\t// on fine pointers they render at 4px when revealed by hover so\n\t\t\t// they match the vertex handles. Clamp the zoom divisor at 0.25 so\n\t\t\t// the visible circle stops growing past 25% zoom and visually\n\t\t\t// shrinks as the user zooms further out \u2014 the hit-area halo above\n\t\t\t// still tracks the full zoom so handles remain grabbable.\n\t\t\tconst fr = (handle.type === 'create' && isCoarse ? 3 : 4) / Math.max(zoom, 0.25)\n\n\t\t\tctx.fillStyle = fgColor\n\t\t\tctx.beginPath()\n\t\t\tctx.arc(handle.x, handle.y, fr, 0, Math.PI * 2)\n\t\t\tctx.fill()\n\t\t\tctx.stroke()\n\t\t}\n\n\t\tctx.restore()\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["fr"]
|
|
7
7
|
}
|