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
|
@@ -33,6 +33,10 @@ class Drawing extends import_editor.StateNode {
|
|
|
33
33
|
util = this.editor.getShapeUtil(this.shapeType);
|
|
34
34
|
isPen = false;
|
|
35
35
|
isPenOrStylus = false;
|
|
36
|
+
// Encoding dimension for segments created during this stroke. `2` drops the
|
|
37
|
+
// constant pressure value (non-pressure devices), `undefined` keeps full 3D.
|
|
38
|
+
// Decided once in startShape from the input device — see the note there.
|
|
39
|
+
segmentDim = void 0;
|
|
36
40
|
segmentMode = "free";
|
|
37
41
|
didJustShiftClickToExtendPreviousShapeLine = false;
|
|
38
42
|
pagePointWhereCurrentSegmentChanged = {};
|
|
@@ -120,9 +124,9 @@ class Drawing extends import_editor.StateNode {
|
|
|
120
124
|
const theme = this.editor.getCurrentTheme();
|
|
121
125
|
strokeWidth = theme.strokeWidth * import_default_shape_constants.STROKE_SIZES[size];
|
|
122
126
|
}
|
|
123
|
-
const firstPoint = import_editor.b64Vecs.decodeFirstPoint(segments[0].path);
|
|
127
|
+
const firstPoint = import_editor.b64Vecs.decodeFirstPoint(segments[0].path, segments[0].dim);
|
|
124
128
|
const lastSegment = segments[segments.length - 1];
|
|
125
|
-
const lastPoint = import_editor.b64Vecs.decodeLastPoint(lastSegment.path);
|
|
129
|
+
const lastPoint = import_editor.b64Vecs.decodeLastPoint(lastSegment.path, lastSegment.dim);
|
|
126
130
|
const isDynamicResizingEnabled = this.editor.user.getIsDynamicResizeMode();
|
|
127
131
|
const threshold = isDynamicResizingEnabled ? (strokeWidth + 2) * scale : (
|
|
128
132
|
// 6 is a base floor, 2 is stroke influence, 0.8 tempers width growth
|
|
@@ -131,6 +135,15 @@ class Drawing extends import_editor.StateNode {
|
|
|
131
135
|
);
|
|
132
136
|
return firstPoint !== null && lastPoint !== null && firstPoint !== lastPoint && this.currentLineLength > strokeWidth * 4 * scale && import_editor.Vec.DistMin(firstPoint, lastPoint, threshold);
|
|
133
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Build a segment from points, encoding `path` at this stroke's `segmentDim` and
|
|
140
|
+
* attaching `dim: 2` only when z was dropped. 3D segments omit `dim` so they
|
|
141
|
+
* serialize byte-identically to pre-#8879 data.
|
|
142
|
+
*/
|
|
143
|
+
makeSegment(type, points) {
|
|
144
|
+
const path = import_editor.b64Vecs.encodePoints(points, this.segmentDim);
|
|
145
|
+
return this.segmentDim === import_editor.DIM_2D ? { type, path, dim: import_editor.DIM_2D } : { type, path };
|
|
146
|
+
}
|
|
134
147
|
startShape() {
|
|
135
148
|
const inputs = this.editor.inputs;
|
|
136
149
|
const originPagePoint = inputs.getOriginPagePoint();
|
|
@@ -139,6 +152,7 @@ class Drawing extends import_editor.StateNode {
|
|
|
139
152
|
const { z = 0.5 } = this.info.point;
|
|
140
153
|
this.isPen = isPen;
|
|
141
154
|
this.isPenOrStylus = isPen && z !== 0 || z > 0 && z < 0.5 || z > 0.5 && z < 1;
|
|
155
|
+
this.segmentDim = this.isPenOrStylus ? void 0 : import_editor.DIM_2D;
|
|
142
156
|
const pressure = this.isPenOrStylus ? z * 1.25 : 0.5;
|
|
143
157
|
this.segmentMode = this.editor.inputs.getShiftKey() ? "straight" : "free";
|
|
144
158
|
this.didJustShiftClickToExtendPreviousShapeLine = false;
|
|
@@ -149,16 +163,13 @@ class Drawing extends import_editor.StateNode {
|
|
|
149
163
|
this.didJustShiftClickToExtendPreviousShapeLine = true;
|
|
150
164
|
const prevSegment = (0, import_editor.last)(shape2.props.segments);
|
|
151
165
|
if (!prevSegment) throw Error("Expected a previous segment!");
|
|
152
|
-
const prevPoint = import_editor.b64Vecs.decodeLastPoint(prevSegment.path);
|
|
166
|
+
const prevPoint = import_editor.b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim);
|
|
153
167
|
if (!prevPoint) throw Error("Expected a previous point!");
|
|
154
168
|
const { x, y } = this.editor.getPointInShapeSpace(shape2, originPagePoint).toFixed();
|
|
155
|
-
const newSegment =
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
{ x, y, z: +pressure.toFixed(2) }
|
|
160
|
-
])
|
|
161
|
-
};
|
|
169
|
+
const newSegment = this.makeSegment(this.segmentMode, [
|
|
170
|
+
{ x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },
|
|
171
|
+
{ x, y, z: +pressure.toFixed(2) }
|
|
172
|
+
]);
|
|
162
173
|
const prevPointPageSpace = import_editor.Mat.applyToPoint(
|
|
163
174
|
this.editor.getShapePageTransform(shape2.id),
|
|
164
175
|
prevPoint
|
|
@@ -201,12 +212,7 @@ class Drawing extends import_editor.StateNode {
|
|
|
201
212
|
props: {
|
|
202
213
|
isPen: this.isPenOrStylus,
|
|
203
214
|
scale: this.editor.getResizeScaleFactor(),
|
|
204
|
-
segments: [
|
|
205
|
-
{
|
|
206
|
-
type: this.segmentMode,
|
|
207
|
-
path: import_editor.b64Vecs.encodePoints([initialPoint])
|
|
208
|
-
}
|
|
209
|
-
]
|
|
215
|
+
segments: [this.makeSegment(this.segmentMode, [initialPoint])]
|
|
210
216
|
}
|
|
211
217
|
});
|
|
212
218
|
const shape = this.editor.getShape(id);
|
|
@@ -245,23 +251,17 @@ class Drawing extends import_editor.StateNode {
|
|
|
245
251
|
this.segmentMode = "straight";
|
|
246
252
|
const prevSegment = (0, import_editor.last)(segments);
|
|
247
253
|
if (!prevSegment) throw Error("Expected a previous segment!");
|
|
248
|
-
const prevLastPoint = import_editor.b64Vecs.decodeLastPoint(prevSegment.path);
|
|
254
|
+
const prevLastPoint = import_editor.b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim);
|
|
249
255
|
if (!prevLastPoint) throw Error("Expected a previous last point!");
|
|
250
256
|
let newSegment;
|
|
251
257
|
const newLastPoint = this.editor.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged).toFixed().toJson();
|
|
252
258
|
if (prevSegment.type === "straight") {
|
|
253
259
|
this.currentLineLength += import_editor.Vec.Dist(prevLastPoint, newLastPoint);
|
|
254
|
-
newSegment =
|
|
255
|
-
type: "straight",
|
|
256
|
-
path: import_editor.b64Vecs.encodePoints([prevLastPoint, newLastPoint])
|
|
257
|
-
};
|
|
260
|
+
newSegment = this.makeSegment("straight", [prevLastPoint, newLastPoint]);
|
|
258
261
|
const transform = this.editor.getShapePageTransform(shape);
|
|
259
262
|
this.pagePointWhereCurrentSegmentChanged = import_editor.Mat.applyToPoint(transform, prevLastPoint);
|
|
260
263
|
} else {
|
|
261
|
-
newSegment =
|
|
262
|
-
type: "straight",
|
|
263
|
-
path: import_editor.b64Vecs.encodePoints([newLastPoint, newPoint])
|
|
264
|
-
};
|
|
264
|
+
newSegment = this.makeSegment("straight", [newLastPoint, newPoint]);
|
|
265
265
|
}
|
|
266
266
|
const shapePartial = {
|
|
267
267
|
id,
|
|
@@ -294,7 +294,10 @@ class Drawing extends import_editor.StateNode {
|
|
|
294
294
|
this.segmentMode = "free";
|
|
295
295
|
const newSegments = segments.slice();
|
|
296
296
|
const prevStraightSegment = newSegments[newSegments.length - 1];
|
|
297
|
-
const prevPoint = import_editor.b64Vecs.decodeLastPoint(
|
|
297
|
+
const prevPoint = import_editor.b64Vecs.decodeLastPoint(
|
|
298
|
+
prevStraightSegment.path,
|
|
299
|
+
prevStraightSegment.dim
|
|
300
|
+
);
|
|
298
301
|
if (!prevPoint) {
|
|
299
302
|
throw Error("No previous point!");
|
|
300
303
|
}
|
|
@@ -302,10 +305,7 @@ class Drawing extends import_editor.StateNode {
|
|
|
302
305
|
(p) => new import_editor.Vec((0, import_editor.toFixed)(p.x), (0, import_editor.toFixed)(p.y), (0, import_editor.toFixed)(p.z))
|
|
303
306
|
);
|
|
304
307
|
this.currentSegmentPoints = interpolatedPoints;
|
|
305
|
-
const newFreeSegment =
|
|
306
|
-
type: "free",
|
|
307
|
-
path: import_editor.b64Vecs.encodePoints(interpolatedPoints)
|
|
308
|
-
};
|
|
308
|
+
const newFreeSegment = this.makeSegment("free", interpolatedPoints);
|
|
309
309
|
const finalSegments = [...newSegments, newFreeSegment];
|
|
310
310
|
const dvStrokeWidth = (0, import_getDisplayValues.getDisplayValues)(this.util, shape).strokeWidth;
|
|
311
311
|
if (this.currentLineLength < dvStrokeWidth * 4) {
|
|
@@ -362,8 +362,8 @@ class Drawing extends import_editor.StateNode {
|
|
|
362
362
|
const segment = segments[i];
|
|
363
363
|
if (!segment) break;
|
|
364
364
|
if (segment.type === "free") continue;
|
|
365
|
-
const first = import_editor.b64Vecs.decodeFirstPoint(segment.path);
|
|
366
|
-
const lastPoint = import_editor.b64Vecs.decodeLastPoint(segment.path);
|
|
365
|
+
const first = import_editor.b64Vecs.decodeFirstPoint(segment.path, segment.dim);
|
|
366
|
+
const lastPoint = import_editor.b64Vecs.decodeLastPoint(segment.path, segment.dim);
|
|
367
367
|
if (!(first && lastPoint)) continue;
|
|
368
368
|
const nearestPointOnSegment = import_editor.Vec.NearestPointOnLineSegment(
|
|
369
369
|
first,
|
|
@@ -385,8 +385,8 @@ class Drawing extends import_editor.StateNode {
|
|
|
385
385
|
}
|
|
386
386
|
if (didSnap && snapSegment) {
|
|
387
387
|
const transform = this.editor.getShapePageTransform(shape);
|
|
388
|
-
const first = import_editor.b64Vecs.decodeFirstPoint(snapSegment.path);
|
|
389
|
-
const lastPoint = import_editor.b64Vecs.decodeLastPoint(snapSegment.path);
|
|
388
|
+
const first = import_editor.b64Vecs.decodeFirstPoint(snapSegment.path, snapSegment.dim);
|
|
389
|
+
const lastPoint = import_editor.b64Vecs.decodeLastPoint(snapSegment.path, snapSegment.dim);
|
|
390
390
|
if (!first || !lastPoint) throw Error("Expected a last point!");
|
|
391
391
|
const A = import_editor.Mat.applyToPoint(transform, first);
|
|
392
392
|
const B = import_editor.Mat.applyToPoint(transform, lastPoint);
|
|
@@ -414,14 +414,17 @@ class Drawing extends import_editor.StateNode {
|
|
|
414
414
|
}
|
|
415
415
|
newPoint2 = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson();
|
|
416
416
|
}
|
|
417
|
-
this.currentLineLength += newSegments.length && import_editor.b64Vecs.decodeFirstPoint(newSegment.path) ? import_editor.Vec.Dist(
|
|
417
|
+
this.currentLineLength += newSegments.length && import_editor.b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim) ? import_editor.Vec.Dist(
|
|
418
|
+
import_editor.b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim),
|
|
419
|
+
import_editor.Vec.From(newPoint2)
|
|
420
|
+
) : 0;
|
|
418
421
|
newSegments[newSegments.length - 1] = {
|
|
419
422
|
...newSegment,
|
|
420
423
|
type: "straight",
|
|
421
|
-
path: import_editor.b64Vecs.encodePoints(
|
|
422
|
-
import_editor.b64Vecs.decodeFirstPoint(newSegment.path),
|
|
423
|
-
|
|
424
|
-
|
|
424
|
+
path: import_editor.b64Vecs.encodePoints(
|
|
425
|
+
[import_editor.b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim), import_editor.Vec.From(newPoint2)],
|
|
426
|
+
newSegment.dim
|
|
427
|
+
)
|
|
425
428
|
};
|
|
426
429
|
const shapePartial = {
|
|
427
430
|
id,
|
|
@@ -456,7 +459,7 @@ class Drawing extends import_editor.StateNode {
|
|
|
456
459
|
const newSegment = newSegments[newSegments.length - 1];
|
|
457
460
|
newSegments[newSegments.length - 1] = {
|
|
458
461
|
...newSegment,
|
|
459
|
-
path: import_editor.b64Vecs.encodePoints(cachedPoints)
|
|
462
|
+
path: import_editor.b64Vecs.encodePoints(cachedPoints, newSegment.dim)
|
|
460
463
|
};
|
|
461
464
|
const dvStrokeWidth = (0, import_getDisplayValues.getDisplayValues)(this.util, shape).strokeWidth;
|
|
462
465
|
if (this.currentLineLength < dvStrokeWidth * 4) {
|
|
@@ -494,12 +497,7 @@ class Drawing extends import_editor.StateNode {
|
|
|
494
497
|
props: {
|
|
495
498
|
isPen: this.isPenOrStylus,
|
|
496
499
|
scale: props.scale,
|
|
497
|
-
segments: [
|
|
498
|
-
{
|
|
499
|
-
type: "free",
|
|
500
|
-
path: import_editor.b64Vecs.encodePoints([initialPoint])
|
|
501
|
-
}
|
|
502
|
-
]
|
|
500
|
+
segments: [this.makeSegment("free", [initialPoint])]
|
|
503
501
|
}
|
|
504
502
|
});
|
|
505
503
|
const shape2 = this.editor.getShape(newShapeId);
|
|
@@ -518,7 +516,7 @@ class Drawing extends import_editor.StateNode {
|
|
|
518
516
|
getLineLength(segments) {
|
|
519
517
|
let length = 0;
|
|
520
518
|
for (let j = 0; j < segments.length; j++) {
|
|
521
|
-
const points = import_editor.b64Vecs.decodePoints(segments[j].path);
|
|
519
|
+
const points = import_editor.b64Vecs.decodePoints(segments[j].path, segments[j].dim);
|
|
522
520
|
for (let i = 0; i < points.length - 1; i++) {
|
|
523
521
|
length += import_editor.Vec.Dist2(points[i], points[i + 1]);
|
|
524
522
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/shapes/draw/toolStates/Drawing.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLDefaultSizeStyle,\n\tTLDrawShape,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tTLShapePartial,\n\tVec,\n\tVecModel,\n\tb64Vecs,\n\tcreateShapeId,\n\tlast,\n\tsnapAngle,\n\tstructuredClone,\n\ttoFixed,\n\tuniqueId,\n} from '@tldraw/editor'\nimport { HighlightShapeUtil } from '../../highlight/HighlightShapeUtil'\nimport { STROKE_SIZES } from '../../shared/default-shape-constants'\nimport { getDisplayValues } from '../../shared/getDisplayValues'\nimport { DrawShapeUtil } from '../DrawShapeUtil'\n\ntype DrawableShape = TLDrawShape | TLHighlightShape\n\nexport class Drawing extends StateNode {\n\tstatic override id = 'drawing'\n\tstatic override trackPerformance = true\n\n\tinfo = {} as TLPointerEventInfo\n\n\tinitialShape?: DrawableShape\n\n\toverride shapeType = this.parent.id === 'highlight' ? ('highlight' as const) : ('draw' as const)\n\n\tutil = this.editor.getShapeUtil(this.shapeType) as DrawShapeUtil | HighlightShapeUtil\n\n\tisPen = false\n\tisPenOrStylus = false\n\n\tsegmentMode = 'free' as 'free' | 'straight' | 'starting_straight' | 'starting_free'\n\n\tdidJustShiftClickToExtendPreviousShapeLine = false\n\n\tpagePointWhereCurrentSegmentChanged = {} as Vec\n\n\tpagePointWhereNextSegmentChanged = null as Vec | null\n\n\tlastRecordedPoint = {} as Vec\n\tmergeNextPoint = false\n\tcurrentLineLength = 0\n\tzoomOnEnter = 1\n\n\t// Cache for current segment's points to avoid repeated b64 decode/encode\n\tcurrentSegmentPoints: Vec[] = []\n\n\tmarkId = null as null | string\n\n\toverride onEnter(info: TLPointerEventInfo) {\n\t\tthis.markId = null\n\t\tthis.info = info\n\t\tthis.lastRecordedPoint = this.editor.inputs.getCurrentPagePoint().clone()\n\t\tthis.zoomOnEnter = this.editor.getZoomLevel()\n\t\tthis.startShape()\n\t}\n\n\toverride onPointerMove() {\n\t\tconst { inputs } = this.editor\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tif (this.isPen && !isPen) {\n\t\t\t// The user made a palm gesture before starting a pen gesture;\n\t\t\t// ideally we'd start the new shape here but we could also just bail\n\t\t\t// as the next interaction will work correctly\n\t\t\tif (this.markId) {\n\t\t\t\tthis.editor.bailToMark(this.markId)\n\t\t\t\tthis.startShape()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (this.isPenOrStylus) {\n\t\t\t// Don't update the shape if we haven't moved far enough from the last time we recorded a point\n\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\t\tif (Vec.Dist(currentPagePoint, this.lastRecordedPoint) >= 1 / this.zoomOnEnter) {\n\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\tthis.mergeNextPoint = false\n\t\t\t} else {\n\t\t\t\tthis.mergeNextPoint = true\n\t\t\t}\n\t\t} else {\n\t\t\tthis.mergeNextPoint = false\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyDown(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'free': {\n\t\t\t\t\t// We've just entered straight mode, go to straight mode\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_free': {\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'straight': {\n\t\t\t\t\t// We've just exited straight mode, go back to free mode\n\t\t\t\t\tthis.segmentMode = 'starting_free'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_straight': {\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\t\tthis.segmentMode = 'free'\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.snaps.clearIndicators()\n\t\tthis.pagePointWhereCurrentSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t}\n\n\tcanClose() {\n\t\treturn this.shapeType !== 'highlight'\n\t}\n\n\tgetIsClosed(\n\t\tsegments: TLDrawShapeSegment[],\n\t\tsize: TLDefaultSizeStyle,\n\t\tscale: number,\n\t\tstrokeWidth?: number\n\t) {\n\t\tif (!this.canClose()) return false\n\n\t\tif (strokeWidth === undefined) {\n\t\t\tconst theme = this.editor.getCurrentTheme()\n\t\t\tstrokeWidth = theme.strokeWidth * STROKE_SIZES[size]\n\t\t}\n\t\tconst firstPoint = b64Vecs.decodeFirstPoint(segments[0].path)\n\t\tconst lastSegment = segments[segments.length - 1]\n\t\tconst lastPoint = b64Vecs.decodeLastPoint(lastSegment.path)\n\n\t\tconst isDynamicResizingEnabled = this.editor.user.getIsDynamicResizeMode()\n\n\t\tconst threshold = isDynamicResizingEnabled // when dynamic resizing is enabled scale is 1/zoom, so the threshold should not scale directly with zoom at all\n\t\t\t? (strokeWidth + 2) * scale // +2 keeps tiny strokes from being too hard to close\n\t\t\t: // 6 is a base floor, 2 is stroke influence, 0.8 tempers width growth\n\t\t\t\t6 +\n\t\t\t\t2 * Math.sqrt(strokeWidth * 0.8) +\n\t\t\t\t// 100 is low-zoom boost, 0.18 is the zoom knee, 3 controls falloff steepness\n\t\t\t\t100 / (1 + Math.pow(this.zoomOnEnter / 0.18, 3))\n\n\t\treturn (\n\t\t\tfirstPoint !== null &&\n\t\t\tlastPoint !== null &&\n\t\t\tfirstPoint !== lastPoint &&\n\t\t\tthis.currentLineLength > strokeWidth * 4 * scale &&\n\t\t\tVec.DistMin(firstPoint, lastPoint, threshold)\n\t\t)\n\t}\n\n\tprivate startShape() {\n\t\tconst inputs = this.editor.inputs\n\t\tconst originPagePoint = inputs.getOriginPagePoint()\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('draw start')\n\n\t\t// If the pressure is weird, then it's probably a stylus reporting as a mouse\n\t\t// We treat pen/stylus inputs differently in the drawing tool, so we need to\n\t\t// have our own value for this. The inputs.isPen is only if the input is a regular\n\t\t// pen, like an iPad pen, which needs to trigger \"pen mode\" in order to avoid\n\t\t// accidental palm touches. We don't have to worry about that with styluses though.\n\t\tconst { z = 0.5 } = this.info.point\n\n\t\tthis.isPen = isPen\n\t\t// if z === 0 on the initial point, treat this pen as a mouse because it's likely a broken pen\n\t\t// or a broken OS.\n\t\tthis.isPenOrStylus = (isPen && z !== 0) || (z > 0 && z < 0.5) || (z > 0.5 && z < 1)\n\n\t\tconst pressure = this.isPenOrStylus ? z * 1.25 : 0.5\n\n\t\tthis.segmentMode = this.editor.inputs.getShiftKey() ? 'straight' : 'free'\n\n\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\n\t\tthis.lastRecordedPoint = originPagePoint.clone()\n\n\t\tif (this.initialShape) {\n\t\t\tconst shape = this.editor.getShape<DrawableShape>(this.initialShape.id)\n\n\t\t\tif (shape && this.segmentMode === 'straight') {\n\t\t\t\t// Connect dots\n\n\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = true\n\n\t\t\t\tconst prevSegment = last(shape.props.segments)\n\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevSegment.path)\n\t\t\t\tif (!prevPoint) throw Error('Expected a previous point!')\n\n\t\t\t\tconst { x, y } = this.editor.getPointInShapeSpace(shape, originPagePoint).toFixed()\n\n\t\t\t\tconst newSegment: TLDrawShapeSegment = {\n\t\t\t\t\ttype: this.segmentMode,\n\t\t\t\t\tpath: b64Vecs.encodePoints([\n\t\t\t\t\t\t{ x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },\n\t\t\t\t\t\t{ x, y, z: +pressure.toFixed(2) },\n\t\t\t\t\t]),\n\t\t\t\t}\n\n\t\t\t\t// Convert prevPoint to page space\n\t\t\t\tconst prevPointPageSpace = Mat.applyToPoint(\n\t\t\t\t\tthis.editor.getShapePageTransform(shape.id)!,\n\t\t\t\t\tprevPoint\n\t\t\t\t)\n\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = prevPointPageSpace\n\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\tconst segments = [...shape.props.segments, newSegment]\n\n\t\t\t\tconst dvStrokeWidth = (getDisplayValues(this.util as any, shape) as { strokeWidth: number })\n\t\t\t\t\t.strokeWidth\n\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(segments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tshape.props.size,\n\t\t\t\t\t\tshape.props.scale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Create a new shape\n\n\t\tthis.pagePointWhereCurrentSegmentChanged = originPagePoint.clone()\n\t\tconst id = createShapeId()\n\n\t\t// Initialize the segment points cache\n\t\tconst initialPoint = new Vec(0, 0, +pressure.toFixed(2))\n\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\tthis.editor.createShape({\n\t\t\tid,\n\t\t\ttype: this.shapeType,\n\t\t\tx: originPagePoint.x,\n\t\t\ty: originPagePoint.y,\n\t\t\tprops: {\n\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\tscale: this.editor.getResizeScaleFactor(),\n\t\t\t\tsegments: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: this.segmentMode,\n\t\t\t\t\t\tpath: b64Vecs.encodePoints([initialPoint]),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t})\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)\n\t\tif (!shape) {\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\t\tthis.currentLineLength = 0\n\t\tthis.initialShape = this.editor.getShape<DrawableShape>(id)\n\t}\n\n\tprivate updateDrawingShape() {\n\t\tconst { initialShape } = this\n\t\tconst { inputs } = this.editor\n\n\t\tif (!initialShape) return\n\n\t\tconst {\n\t\t\tid,\n\t\t\tprops: { size, scale },\n\t\t} = initialShape\n\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)!\n\n\t\tif (!shape) return\n\n\t\tconst { segments } = shape.props\n\n\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\tconst { x, y, z } = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed()\n\t\tconst pressure = this.isPenOrStylus ? +(currentPagePoint.z! * 1.25).toFixed(2) : 0.5\n\t\tconst newPoint = { x, y, z: pressure }\n\n\t\tswitch (this.segmentMode) {\n\t\t\tcase 'starting_straight': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'straight'\n\n\t\t\t\t\tconst prevSegment = last(segments)\n\t\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\n\t\t\t\t\tconst prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.path)\n\t\t\t\t\tif (!prevLastPoint) throw Error('Expected a previous last point!')\n\n\t\t\t\t\tlet newSegment: TLDrawShapeSegment\n\n\t\t\t\t\tconst newLastPoint = this.editor\n\t\t\t\t\t\t.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\t\t.toFixed()\n\t\t\t\t\t\t.toJson()\n\n\t\t\t\t\tif (prevSegment.type === 'straight') {\n\t\t\t\t\t\tthis.currentLineLength += Vec.Dist(prevLastPoint, newLastPoint)\n\n\t\t\t\t\t\tnewSegment = {\n\t\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\t\tpath: b64Vecs.encodePoints([prevLastPoint, newLastPoint]),\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\n\t\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = Mat.applyToPoint(transform, prevLastPoint)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewSegment = {\n\t\t\t\t\t\t\ttype: 'straight',\n\t\t\t\t\t\t\tpath: b64Vecs.encodePoints([newLastPoint, newPoint]),\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: [...segments, newSegment],\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tsegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'starting_free': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'free'\n\n\t\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\t\tconst prevStraightSegment = newSegments[newSegments.length - 1]\n\t\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevStraightSegment.path)\n\n\t\t\t\t\tif (!prevPoint) {\n\t\t\t\t\t\tthrow Error('No previous point!')\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create the new free segment and interpolate the points between where the last line\n\t\t\t\t\t// ended and where the pointer is now\n\t\t\t\t\tconst interpolatedPoints = Vec.PointsBetween(prevPoint, newPoint, 6).map(\n\t\t\t\t\t\t(p) => new Vec(toFixed(p.x), toFixed(p.y), toFixed(p.z))\n\t\t\t\t\t)\n\t\t\t\t\t// Initialize cache for the new free segment\n\t\t\t\t\tthis.currentSegmentPoints = interpolatedPoints\n\n\t\t\t\t\tconst newFreeSegment: TLDrawShapeSegment = {\n\t\t\t\t\t\ttype: 'free',\n\t\t\t\t\t\tpath: b64Vecs.encodePoints(interpolatedPoints),\n\t\t\t\t\t}\n\n\t\t\t\t\tconst finalSegments = [...newSegments, newFreeSegment]\n\n\t\t\t\t\tconst dvStrokeWidth = (\n\t\t\t\t\t\tgetDisplayValues(this.util as any, shape) as { strokeWidth: number }\n\t\t\t\t\t).strokeWidth\n\t\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\t\tthis.currentLineLength = this.getLineLength(finalSegments)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: finalSegments,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tfinalSegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'straight': {\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\n\t\t\t\tconst { pagePointWhereCurrentSegmentChanged } = this\n\t\t\t\tconst inputs = this.editor.inputs\n\t\t\t\tconst ctrlKey = inputs.getCtrlKey()\n\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\tif (!pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\n\t\t\t\tlet pagePoint: VecModel\n\t\t\t\tlet shouldSnapToAngle = false\n\n\t\t\t\tif (this.didJustShiftClickToExtendPreviousShapeLine) {\n\t\t\t\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\t\t\t\t// If we've just shift clicked to extend a line, only snap once we've started dragging\n\t\t\t\t\t\tshouldSnapToAngle = !ctrlKey\n\t\t\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If we're not shift clicking to extend a line, but we're holding shift, then we should snap\n\t\t\t\t\tshouldSnapToAngle = !ctrlKey // don't snap angle while snapping line\n\t\t\t\t}\n\n\t\t\t\tlet newPoint = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed().toJson()\n\t\t\t\tlet didSnap = false\n\t\t\t\tlet snapSegment: TLDrawShapeSegment | undefined = undefined\n\n\t\t\t\tconst shouldSnap = this.editor.user.getIsSnapMode() ? !ctrlKey : ctrlKey\n\n\t\t\t\tif (shouldSnap) {\n\t\t\t\t\tif (newSegments.length > 2) {\n\t\t\t\t\t\tlet nearestPoint: VecModel | undefined = undefined\n\t\t\t\t\t\tlet minDistance = 8 / this.zoomOnEnter\n\n\t\t\t\t\t\t// Don't try to snap to the last two segments\n\t\t\t\t\t\tfor (let i = 0, n = segments.length - 2; i < n; i++) {\n\t\t\t\t\t\t\tconst segment = segments[i]\n\t\t\t\t\t\t\tif (!segment) break\n\t\t\t\t\t\t\tif (segment.type === 'free') continue\n\n\t\t\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(segment.path)\n\t\t\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(segment.path)\n\t\t\t\t\t\t\tif (!(first && lastPoint)) continue\n\n\t\t\t\t\t\t\t// Snap to the nearest point on the segment, if it's closer than the previous snapped point\n\t\t\t\t\t\t\tconst nearestPointOnSegment = Vec.NearestPointOnLineSegment(\n\t\t\t\t\t\t\t\tfirst,\n\t\t\t\t\t\t\t\tlastPoint,\n\t\t\t\t\t\t\t\tnewPoint\n\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\tif (Vec.DistMin(nearestPointOnSegment, newPoint, minDistance)) {\n\t\t\t\t\t\t\t\tnearestPoint = nearestPointOnSegment.toFixed().toJson()\n\t\t\t\t\t\t\t\tminDistance = Vec.Dist(nearestPointOnSegment, newPoint)\n\t\t\t\t\t\t\t\tsnapSegment = segment\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (nearestPoint) {\n\t\t\t\t\t\t\tdidSnap = true\n\t\t\t\t\t\t\tnewPoint = nearestPoint\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (didSnap && snapSegment) {\n\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(snapSegment.path)\n\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(snapSegment.path)\n\t\t\t\t\tif (!first || !lastPoint) throw Error('Expected a last point!')\n\n\t\t\t\t\tconst A = Mat.applyToPoint(transform, first)\n\n\t\t\t\t\tconst B = Mat.applyToPoint(transform, lastPoint)\n\n\t\t\t\t\tconst snappedPoint = Mat.applyToPoint(transform, newPoint)\n\n\t\t\t\t\tthis.editor.snaps.setIndicators([\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttype: 'points',\n\t\t\t\t\t\t\tpoints: [A, snappedPoint, B],\n\t\t\t\t\t\t},\n\t\t\t\t\t])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\t\t\tif (shouldSnapToAngle) {\n\t\t\t\t\t\t// Snap line angle to nearest 15 degrees\n\t\t\t\t\t\tconst currentAngle = Vec.Angle(pagePointWhereCurrentSegmentChanged, currentPagePoint)\n\t\t\t\t\t\tconst snappedAngle = snapAngle(currentAngle, 24)\n\t\t\t\t\t\tconst angleDiff = snappedAngle - currentAngle\n\n\t\t\t\t\t\tpagePoint = Vec.RotWith(\n\t\t\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\t\t\tpagePointWhereCurrentSegmentChanged,\n\t\t\t\t\t\t\tangleDiff\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpagePoint = currentPagePoint.clone()\n\t\t\t\t\t}\n\n\t\t\t\t\tnewPoint = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson()\n\t\t\t\t}\n\n\t\t\t\t// If the previous segment is a one point free shape and is the first segment of the line,\n\t\t\t\t// then the user just did a click-and-immediately-press-shift to create a new straight line\n\t\t\t\t// without continuing the previous line. In this case, we want to remove the previous segment.\n\n\t\t\t\tthis.currentLineLength +=\n\t\t\t\t\tnewSegments.length && b64Vecs.decodeFirstPoint(newSegment.path)\n\t\t\t\t\t\t? Vec.Dist(b64Vecs.decodeFirstPoint(newSegment.path)!, Vec.From(newPoint))\n\t\t\t\t\t\t: 0\n\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\ttype: 'straight',\n\t\t\t\t\tpath: b64Vecs.encodePoints([\n\t\t\t\t\t\tb64Vecs.decodeFirstPoint(newSegment.path)!,\n\t\t\t\t\t\tVec.From(newPoint),\n\t\t\t\t\t]),\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'free': {\n\t\t\t\t// Use cached points instead of decoding from b64 on every update\n\t\t\t\tconst cachedPoints = this.currentSegmentPoints\n\n\t\t\t\tif (cachedPoints.length && this.mergeNextPoint) {\n\t\t\t\t\tconst lastPoint = cachedPoints[cachedPoints.length - 1]\n\t\t\t\t\tlastPoint.x = newPoint.x\n\t\t\t\t\tlastPoint.y = newPoint.y\n\t\t\t\t\tlastPoint.z = lastPoint.z ? Math.max(lastPoint.z, newPoint.z) : newPoint.z\n\t\t\t\t\t// Note: we could recompute the line length here, but it's not really necessary\n\t\t\t\t\t// this.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t} else {\n\t\t\t\t\tthis.currentLineLength += cachedPoints.length\n\t\t\t\t\t\t? Vec.Dist(cachedPoints[cachedPoints.length - 1], newPoint)\n\t\t\t\t\t\t: 0\n\t\t\t\t\tcachedPoints.push(new Vec(newPoint.x, newPoint.y, newPoint.z))\n\t\t\t\t}\n\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\tpath: b64Vecs.encodePoints(cachedPoints),\n\t\t\t\t}\n\n\t\t\t\tconst dvStrokeWidth = (getDisplayValues(this.util as any, shape) as { strokeWidth: number })\n\t\t\t\t\t.strokeWidth\n\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tnewSegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\t// Set a maximum length for the lines array; after 200 points, complete the line.\n\t\t\t\tif (cachedPoints.length > this.util.options.maxPointsPerShape) {\n\t\t\t\t\tthis.editor.updateShapes([{ id, type: this.shapeType, props: { isComplete: true } }])\n\n\t\t\t\t\tconst newShapeId = createShapeId()\n\n\t\t\t\t\tconst props = this.editor.getShape<DrawableShape>(id)!.props\n\n\t\t\t\t\tif (!this.editor.canCreateShapes([newShapeId])) return this.cancel()\n\t\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\t\t// Reset cache for the new shape's segment\n\t\t\t\t\tconst initialPoint = new Vec(0, 0, this.isPenOrStylus ? +(z! * 1.25).toFixed() : 0.5)\n\t\t\t\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t\t\t\tthis.editor.createShape({\n\t\t\t\t\t\tid: newShapeId,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tx: toFixed(currentPagePoint.x),\n\t\t\t\t\t\ty: toFixed(currentPagePoint.y),\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\t\t\t\tscale: props.scale,\n\t\t\t\t\t\t\tsegments: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: 'free',\n\t\t\t\t\t\t\t\t\tpath: b64Vecs.encodePoints([initialPoint]),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\tconst shape = this.editor.getShape<DrawableShape>(newShapeId)\n\n\t\t\t\t\tif (!shape) {\n\t\t\t\t\t\t// This would only happen if the page is full and no more shapes can be created. The bug would manifest as a crash when we try to clone the shape.\n\t\t\t\t\t\t// todo: handle this type of thing better\n\t\t\t\t\t\treturn this.cancel()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.initialShape = structuredClone(shape)\n\t\t\t\t\tthis.mergeNextPoint = false\n\t\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\t\tthis.currentLineLength = 0\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLineLength(segments: TLDrawShapeSegment[]) {\n\t\tlet length = 0\n\n\t\tfor (let j = 0; j < segments.length; j++) {\n\t\t\tconst points = b64Vecs.decodePoints(segments[j].path)\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tlength += Vec.Dist2(points[i], points[i + 1])\n\t\t\t}\n\t\t}\n\n\t\treturn Math.sqrt(length)\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onInterrupt() {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\treturn\n\t\t}\n\n\t\tif (this.markId) {\n\t\t\tthis.editor.bailToMark(this.markId)\n\t\t}\n\t\tthis.cancel()\n\t}\n\n\tcomplete() {\n\t\tconst { initialShape } = this\n\t\tif (!initialShape) return\n\t\tthis.editor.updateShapes([\n\t\t\t{ id: initialShape.id, type: initialShape.type, props: { isComplete: true } },\n\t\t])\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tcancel() {\n\t\tthis.parent.transition('idle', this.info)\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n\tMat,\n\tStateNode,\n\tTLDefaultSizeStyle,\n\tTLDrawShape,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLKeyboardEventInfo,\n\tTLPointerEventInfo,\n\tTLShapePartial,\n\tDIM_2D,\n\tVec,\n\tVecModel,\n\tb64Vecs,\n\tcreateShapeId,\n\tlast,\n\tsnapAngle,\n\tstructuredClone,\n\ttoFixed,\n\tuniqueId,\n} from '@tldraw/editor'\nimport { HighlightShapeUtil } from '../../highlight/HighlightShapeUtil'\nimport { STROKE_SIZES } from '../../shared/default-shape-constants'\nimport { getDisplayValues } from '../../shared/getDisplayValues'\nimport { DrawShapeUtil } from '../DrawShapeUtil'\n\ntype DrawableShape = TLDrawShape | TLHighlightShape\n\nexport class Drawing extends StateNode {\n\tstatic override id = 'drawing'\n\tstatic override trackPerformance = true\n\n\tinfo = {} as TLPointerEventInfo\n\n\tinitialShape?: DrawableShape\n\n\toverride shapeType = this.parent.id === 'highlight' ? ('highlight' as const) : ('draw' as const)\n\n\tutil = this.editor.getShapeUtil(this.shapeType) as DrawShapeUtil | HighlightShapeUtil\n\n\tisPen = false\n\tisPenOrStylus = false\n\n\t// Encoding dimension for segments created during this stroke. `2` drops the\n\t// constant pressure value (non-pressure devices), `undefined` keeps full 3D.\n\t// Decided once in startShape from the input device \u2014 see the note there.\n\tsegmentDim: 2 | undefined = undefined\n\n\tsegmentMode = 'free' as 'free' | 'straight' | 'starting_straight' | 'starting_free'\n\n\tdidJustShiftClickToExtendPreviousShapeLine = false\n\n\tpagePointWhereCurrentSegmentChanged = {} as Vec\n\n\tpagePointWhereNextSegmentChanged = null as Vec | null\n\n\tlastRecordedPoint = {} as Vec\n\tmergeNextPoint = false\n\tcurrentLineLength = 0\n\tzoomOnEnter = 1\n\n\t// Cache for current segment's points to avoid repeated b64 decode/encode\n\tcurrentSegmentPoints: Vec[] = []\n\n\tmarkId = null as null | string\n\n\toverride onEnter(info: TLPointerEventInfo) {\n\t\tthis.markId = null\n\t\tthis.info = info\n\t\tthis.lastRecordedPoint = this.editor.inputs.getCurrentPagePoint().clone()\n\t\tthis.zoomOnEnter = this.editor.getZoomLevel()\n\t\tthis.startShape()\n\t}\n\n\toverride onPointerMove() {\n\t\tconst { inputs } = this.editor\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tif (this.isPen && !isPen) {\n\t\t\t// The user made a palm gesture before starting a pen gesture;\n\t\t\t// ideally we'd start the new shape here but we could also just bail\n\t\t\t// as the next interaction will work correctly\n\t\t\tif (this.markId) {\n\t\t\t\tthis.editor.bailToMark(this.markId)\n\t\t\t\tthis.startShape()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (this.isPenOrStylus) {\n\t\t\t// Don't update the shape if we haven't moved far enough from the last time we recorded a point\n\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\t\tif (Vec.Dist(currentPagePoint, this.lastRecordedPoint) >= 1 / this.zoomOnEnter) {\n\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\tthis.mergeNextPoint = false\n\t\t\t} else {\n\t\t\t\tthis.mergeNextPoint = true\n\t\t\t}\n\t\t} else {\n\t\t\tthis.mergeNextPoint = false\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyDown(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'free': {\n\t\t\t\t\t// We've just entered straight mode, go to straight mode\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_free': {\n\t\t\t\t\tthis.segmentMode = 'starting_straight'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onKeyUp(info: TLKeyboardEventInfo) {\n\t\tif (info.key === 'Shift') {\n\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\tswitch (this.segmentMode) {\n\t\t\t\tcase 'straight': {\n\t\t\t\t\t// We've just exited straight mode, go back to free mode\n\t\t\t\t\tthis.segmentMode = 'starting_free'\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'starting_straight': {\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\t\tthis.segmentMode = 'free'\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.updateDrawingShape()\n\t}\n\n\toverride onExit() {\n\t\tthis.editor.snaps.clearIndicators()\n\t\tthis.pagePointWhereCurrentSegmentChanged = this.editor.inputs.getCurrentPagePoint().clone()\n\t}\n\n\tcanClose() {\n\t\treturn this.shapeType !== 'highlight'\n\t}\n\n\tgetIsClosed(\n\t\tsegments: TLDrawShapeSegment[],\n\t\tsize: TLDefaultSizeStyle,\n\t\tscale: number,\n\t\tstrokeWidth?: number\n\t) {\n\t\tif (!this.canClose()) return false\n\n\t\tif (strokeWidth === undefined) {\n\t\t\tconst theme = this.editor.getCurrentTheme()\n\t\t\tstrokeWidth = theme.strokeWidth * STROKE_SIZES[size]\n\t\t}\n\t\tconst firstPoint = b64Vecs.decodeFirstPoint(segments[0].path, segments[0].dim)\n\t\tconst lastSegment = segments[segments.length - 1]\n\t\tconst lastPoint = b64Vecs.decodeLastPoint(lastSegment.path, lastSegment.dim)\n\n\t\tconst isDynamicResizingEnabled = this.editor.user.getIsDynamicResizeMode()\n\n\t\tconst threshold = isDynamicResizingEnabled // when dynamic resizing is enabled scale is 1/zoom, so the threshold should not scale directly with zoom at all\n\t\t\t? (strokeWidth + 2) * scale // +2 keeps tiny strokes from being too hard to close\n\t\t\t: // 6 is a base floor, 2 is stroke influence, 0.8 tempers width growth\n\t\t\t\t6 +\n\t\t\t\t2 * Math.sqrt(strokeWidth * 0.8) +\n\t\t\t\t// 100 is low-zoom boost, 0.18 is the zoom knee, 3 controls falloff steepness\n\t\t\t\t100 / (1 + Math.pow(this.zoomOnEnter / 0.18, 3))\n\n\t\treturn (\n\t\t\tfirstPoint !== null &&\n\t\t\tlastPoint !== null &&\n\t\t\tfirstPoint !== lastPoint &&\n\t\t\tthis.currentLineLength > strokeWidth * 4 * scale &&\n\t\t\tVec.DistMin(firstPoint, lastPoint, threshold)\n\t\t)\n\t}\n\n\t/**\n\t * Build a segment from points, encoding `path` at this stroke's `segmentDim` and\n\t * attaching `dim: 2` only when z was dropped. 3D segments omit `dim` so they\n\t * serialize byte-identically to pre-#8879 data.\n\t */\n\tprivate makeSegment(type: TLDrawShapeSegment['type'], points: VecModel[]): TLDrawShapeSegment {\n\t\tconst path = b64Vecs.encodePoints(points, this.segmentDim)\n\t\treturn this.segmentDim === DIM_2D ? { type, path, dim: DIM_2D } : { type, path }\n\t}\n\n\tprivate startShape() {\n\t\tconst inputs = this.editor.inputs\n\t\tconst originPagePoint = inputs.getOriginPagePoint()\n\t\tconst isPen = inputs.getIsPen()\n\n\t\tthis.markId = this.editor.markHistoryStoppingPoint('draw start')\n\n\t\t// If the pressure is weird, then it's probably a stylus reporting as a mouse\n\t\t// We treat pen/stylus inputs differently in the drawing tool, so we need to\n\t\t// have our own value for this. The inputs.isPen is only if the input is a regular\n\t\t// pen, like an iPad pen, which needs to trigger \"pen mode\" in order to avoid\n\t\t// accidental palm touches. We don't have to worry about that with styluses though.\n\t\tconst { z = 0.5 } = this.info.point\n\n\t\tthis.isPen = isPen\n\t\t// if z === 0 on the initial point, treat this pen as a mouse because it's likely a broken pen\n\t\t// or a broken OS.\n\t\tthis.isPenOrStylus = (isPen && z !== 0) || (z > 0 && z < 0.5) || (z > 0.5 && z < 1)\n\n\t\t// Decide the encoding dimension once, here, from the input device \u2014 not by\n\t\t// scanning point data (content-driven). Device-driven keeps the encoded bytes\n\t\t// deterministic and is O(1) at stroke start. Non-pressure devices report a\n\t\t// constant z (0 / 0.5 / 1) that we normalize to 0.5 and omit entirely (2D);\n\t\t// pen/stylus input keeps the full 3D encoding.\n\t\tthis.segmentDim = this.isPenOrStylus ? undefined : DIM_2D\n\n\t\tconst pressure = this.isPenOrStylus ? z * 1.25 : 0.5\n\n\t\tthis.segmentMode = this.editor.inputs.getShiftKey() ? 'straight' : 'free'\n\n\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\n\t\tthis.lastRecordedPoint = originPagePoint.clone()\n\n\t\tif (this.initialShape) {\n\t\t\tconst shape = this.editor.getShape<DrawableShape>(this.initialShape.id)\n\n\t\t\tif (shape && this.segmentMode === 'straight') {\n\t\t\t\t// Connect dots\n\n\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = true\n\n\t\t\t\tconst prevSegment = last(shape.props.segments)\n\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim)\n\t\t\t\tif (!prevPoint) throw Error('Expected a previous point!')\n\n\t\t\t\tconst { x, y } = this.editor.getPointInShapeSpace(shape, originPagePoint).toFixed()\n\n\t\t\t\tconst newSegment = this.makeSegment(this.segmentMode, [\n\t\t\t\t\t{ x: prevPoint.x, y: prevPoint.y, z: +pressure.toFixed(2) },\n\t\t\t\t\t{ x, y, z: +pressure.toFixed(2) },\n\t\t\t\t])\n\n\t\t\t\t// Convert prevPoint to page space\n\t\t\t\tconst prevPointPageSpace = Mat.applyToPoint(\n\t\t\t\t\tthis.editor.getShapePageTransform(shape.id)!,\n\t\t\t\t\tprevPoint\n\t\t\t\t)\n\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = prevPointPageSpace\n\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\t\t\t\tconst segments = [...shape.props.segments, newSegment]\n\n\t\t\t\tconst dvStrokeWidth = (getDisplayValues(this.util as any, shape) as { strokeWidth: number })\n\t\t\t\t\t.strokeWidth\n\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(segments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid: shape.id,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tshape.props.size,\n\t\t\t\t\t\tshape.props.scale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Create a new shape\n\n\t\tthis.pagePointWhereCurrentSegmentChanged = originPagePoint.clone()\n\t\tconst id = createShapeId()\n\n\t\t// Initialize the segment points cache\n\t\tconst initialPoint = new Vec(0, 0, +pressure.toFixed(2))\n\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t// Allow this to trigger the max shapes reached alert\n\t\tthis.editor.createShape({\n\t\t\tid,\n\t\t\ttype: this.shapeType,\n\t\t\tx: originPagePoint.x,\n\t\t\ty: originPagePoint.y,\n\t\t\tprops: {\n\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\tscale: this.editor.getResizeScaleFactor(),\n\t\t\t\tsegments: [this.makeSegment(this.segmentMode, [initialPoint])],\n\t\t\t},\n\t\t})\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)\n\t\tif (!shape) {\n\t\t\tthis.cancel()\n\t\t\treturn\n\t\t}\n\t\tthis.currentLineLength = 0\n\t\tthis.initialShape = this.editor.getShape<DrawableShape>(id)\n\t}\n\n\tprivate updateDrawingShape() {\n\t\tconst { initialShape } = this\n\t\tconst { inputs } = this.editor\n\n\t\tif (!initialShape) return\n\n\t\tconst {\n\t\t\tid,\n\t\t\tprops: { size, scale },\n\t\t} = initialShape\n\n\t\tconst shape = this.editor.getShape<DrawableShape>(id)!\n\n\t\tif (!shape) return\n\n\t\tconst { segments } = shape.props\n\n\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\t\tconst { x, y, z } = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed()\n\t\tconst pressure = this.isPenOrStylus ? +(currentPagePoint.z! * 1.25).toFixed(2) : 0.5\n\t\tconst newPoint = { x, y, z: pressure }\n\n\t\tswitch (this.segmentMode) {\n\t\t\tcase 'starting_straight': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'straight'\n\n\t\t\t\t\tconst prevSegment = last(segments)\n\t\t\t\t\tif (!prevSegment) throw Error('Expected a previous segment!')\n\n\t\t\t\t\tconst prevLastPoint = b64Vecs.decodeLastPoint(prevSegment.path, prevSegment.dim)\n\t\t\t\t\tif (!prevLastPoint) throw Error('Expected a previous last point!')\n\n\t\t\t\t\tlet newSegment: TLDrawShapeSegment\n\n\t\t\t\t\tconst newLastPoint = this.editor\n\t\t\t\t\t\t.getPointInShapeSpace(shape, this.pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\t\t.toFixed()\n\t\t\t\t\t\t.toJson()\n\n\t\t\t\t\tif (prevSegment.type === 'straight') {\n\t\t\t\t\t\tthis.currentLineLength += Vec.Dist(prevLastPoint, newLastPoint)\n\n\t\t\t\t\t\tnewSegment = this.makeSegment('straight', [prevLastPoint, newLastPoint])\n\n\t\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\n\t\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = Mat.applyToPoint(transform, prevLastPoint)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnewSegment = this.makeSegment('straight', [newLastPoint, newPoint])\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: [...segments, newSegment],\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tsegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'starting_free': {\n\t\t\t\tconst { pagePointWhereNextSegmentChanged } = this\n\n\t\t\t\tif (pagePointWhereNextSegmentChanged === null) {\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\t\t\t\t}\n\n\t\t\t\tconst hasMovedFarEnough =\n\t\t\t\t\tVec.Dist2(pagePointWhereNextSegmentChanged, inputs.getCurrentPagePoint()) >\n\t\t\t\t\tthis.editor.options.dragDistanceSquared\n\n\t\t\t\t// Find the distance from where the pointer was when shift was released and\n\t\t\t\t// where it is now; if it's far enough away, then update the page point where\n\t\t\t\t// the current segment changed (to match the pagepoint where next segment changed)\n\t\t\t\t// and set the pagepoint where next segment changed to null.\n\t\t\t\tif (hasMovedFarEnough) {\n\t\t\t\t\tthis.pagePointWhereCurrentSegmentChanged = this.pagePointWhereNextSegmentChanged!.clone()\n\t\t\t\t\tthis.pagePointWhereNextSegmentChanged = null\n\n\t\t\t\t\t// Set the new mode\n\t\t\t\t\tthis.segmentMode = 'free'\n\n\t\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\t\tconst prevStraightSegment = newSegments[newSegments.length - 1]\n\t\t\t\t\tconst prevPoint = b64Vecs.decodeLastPoint(\n\t\t\t\t\t\tprevStraightSegment.path,\n\t\t\t\t\t\tprevStraightSegment.dim\n\t\t\t\t\t)\n\n\t\t\t\t\tif (!prevPoint) {\n\t\t\t\t\t\tthrow Error('No previous point!')\n\t\t\t\t\t}\n\n\t\t\t\t\t// Create the new free segment and interpolate the points between where the last line\n\t\t\t\t\t// ended and where the pointer is now\n\t\t\t\t\tconst interpolatedPoints = Vec.PointsBetween(prevPoint, newPoint, 6).map(\n\t\t\t\t\t\t(p) => new Vec(toFixed(p.x), toFixed(p.y), toFixed(p.z))\n\t\t\t\t\t)\n\t\t\t\t\t// Initialize cache for the new free segment\n\t\t\t\t\tthis.currentSegmentPoints = interpolatedPoints\n\n\t\t\t\t\tconst newFreeSegment = this.makeSegment('free', interpolatedPoints)\n\n\t\t\t\t\tconst finalSegments = [...newSegments, newFreeSegment]\n\n\t\t\t\t\tconst dvStrokeWidth = (\n\t\t\t\t\t\tgetDisplayValues(this.util as any, shape) as { strokeWidth: number }\n\t\t\t\t\t).strokeWidth\n\t\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\t\tthis.currentLineLength = this.getLineLength(finalSegments)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\t\tid,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tsegments: finalSegments,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\t\tfinalSegments,\n\t\t\t\t\t\t\tsize,\n\t\t\t\t\t\t\tscale\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.editor.updateShapes([shapePartial])\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'straight': {\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\n\t\t\t\tconst { pagePointWhereCurrentSegmentChanged } = this\n\t\t\t\tconst inputs = this.editor.inputs\n\t\t\t\tconst ctrlKey = inputs.getCtrlKey()\n\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\tif (!pagePointWhereCurrentSegmentChanged)\n\t\t\t\t\tthrow Error('We should have a point where the segment changed')\n\n\t\t\t\tlet pagePoint: VecModel\n\t\t\t\tlet shouldSnapToAngle = false\n\n\t\t\t\tif (this.didJustShiftClickToExtendPreviousShapeLine) {\n\t\t\t\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\t\t\t\t// If we've just shift clicked to extend a line, only snap once we've started dragging\n\t\t\t\t\t\tshouldSnapToAngle = !ctrlKey\n\t\t\t\t\t\tthis.didJustShiftClickToExtendPreviousShapeLine = false\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// noop\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If we're not shift clicking to extend a line, but we're holding shift, then we should snap\n\t\t\t\t\tshouldSnapToAngle = !ctrlKey // don't snap angle while snapping line\n\t\t\t\t}\n\n\t\t\t\tlet newPoint = this.editor.getPointInShapeSpace(shape, currentPagePoint).toFixed().toJson()\n\t\t\t\tlet didSnap = false\n\t\t\t\tlet snapSegment: TLDrawShapeSegment | undefined = undefined\n\n\t\t\t\tconst shouldSnap = this.editor.user.getIsSnapMode() ? !ctrlKey : ctrlKey\n\n\t\t\t\tif (shouldSnap) {\n\t\t\t\t\tif (newSegments.length > 2) {\n\t\t\t\t\t\tlet nearestPoint: VecModel | undefined = undefined\n\t\t\t\t\t\tlet minDistance = 8 / this.zoomOnEnter\n\n\t\t\t\t\t\t// Don't try to snap to the last two segments\n\t\t\t\t\t\tfor (let i = 0, n = segments.length - 2; i < n; i++) {\n\t\t\t\t\t\t\tconst segment = segments[i]\n\t\t\t\t\t\t\tif (!segment) break\n\t\t\t\t\t\t\tif (segment.type === 'free') continue\n\n\t\t\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(segment.path, segment.dim)\n\t\t\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(segment.path, segment.dim)\n\t\t\t\t\t\t\tif (!(first && lastPoint)) continue\n\n\t\t\t\t\t\t\t// Snap to the nearest point on the segment, if it's closer than the previous snapped point\n\t\t\t\t\t\t\tconst nearestPointOnSegment = Vec.NearestPointOnLineSegment(\n\t\t\t\t\t\t\t\tfirst,\n\t\t\t\t\t\t\t\tlastPoint,\n\t\t\t\t\t\t\t\tnewPoint\n\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\tif (Vec.DistMin(nearestPointOnSegment, newPoint, minDistance)) {\n\t\t\t\t\t\t\t\tnearestPoint = nearestPointOnSegment.toFixed().toJson()\n\t\t\t\t\t\t\t\tminDistance = Vec.Dist(nearestPointOnSegment, newPoint)\n\t\t\t\t\t\t\t\tsnapSegment = segment\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (nearestPoint) {\n\t\t\t\t\t\t\tdidSnap = true\n\t\t\t\t\t\t\tnewPoint = nearestPoint\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (didSnap && snapSegment) {\n\t\t\t\t\tconst transform = this.editor.getShapePageTransform(shape)!\n\t\t\t\t\tconst first = b64Vecs.decodeFirstPoint(snapSegment.path, snapSegment.dim)\n\t\t\t\t\tconst lastPoint = b64Vecs.decodeLastPoint(snapSegment.path, snapSegment.dim)\n\t\t\t\t\tif (!first || !lastPoint) throw Error('Expected a last point!')\n\n\t\t\t\t\tconst A = Mat.applyToPoint(transform, first)\n\n\t\t\t\t\tconst B = Mat.applyToPoint(transform, lastPoint)\n\n\t\t\t\t\tconst snappedPoint = Mat.applyToPoint(transform, newPoint)\n\n\t\t\t\t\tthis.editor.snaps.setIndicators([\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: uniqueId(),\n\t\t\t\t\t\t\ttype: 'points',\n\t\t\t\t\t\t\tpoints: [A, snappedPoint, B],\n\t\t\t\t\t\t},\n\t\t\t\t\t])\n\t\t\t\t} else {\n\t\t\t\t\tthis.editor.snaps.clearIndicators()\n\n\t\t\t\t\tif (shouldSnapToAngle) {\n\t\t\t\t\t\t// Snap line angle to nearest 15 degrees\n\t\t\t\t\t\tconst currentAngle = Vec.Angle(pagePointWhereCurrentSegmentChanged, currentPagePoint)\n\t\t\t\t\t\tconst snappedAngle = snapAngle(currentAngle, 24)\n\t\t\t\t\t\tconst angleDiff = snappedAngle - currentAngle\n\n\t\t\t\t\t\tpagePoint = Vec.RotWith(\n\t\t\t\t\t\t\tcurrentPagePoint,\n\t\t\t\t\t\t\tpagePointWhereCurrentSegmentChanged,\n\t\t\t\t\t\t\tangleDiff\n\t\t\t\t\t\t)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpagePoint = currentPagePoint.clone()\n\t\t\t\t\t}\n\n\t\t\t\t\tnewPoint = this.editor.getPointInShapeSpace(shape, pagePoint).toFixed().toJson()\n\t\t\t\t}\n\n\t\t\t\t// If the previous segment is a one point free shape and is the first segment of the line,\n\t\t\t\t// then the user just did a click-and-immediately-press-shift to create a new straight line\n\t\t\t\t// without continuing the previous line. In this case, we want to remove the previous segment.\n\n\t\t\t\tthis.currentLineLength +=\n\t\t\t\t\tnewSegments.length && b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim)\n\t\t\t\t\t\t? Vec.Dist(\n\t\t\t\t\t\t\t\tb64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim)!,\n\t\t\t\t\t\t\t\tVec.From(newPoint)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: 0\n\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\ttype: 'straight',\n\t\t\t\t\tpath: b64Vecs.encodePoints(\n\t\t\t\t\t\t[b64Vecs.decodeFirstPoint(newSegment.path, newSegment.dim)!, Vec.From(newPoint)],\n\t\t\t\t\t\tnewSegment.dim\n\t\t\t\t\t),\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tsegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'free': {\n\t\t\t\t// Use cached points instead of decoding from b64 on every update\n\t\t\t\tconst cachedPoints = this.currentSegmentPoints\n\n\t\t\t\tif (cachedPoints.length && this.mergeNextPoint) {\n\t\t\t\t\tconst lastPoint = cachedPoints[cachedPoints.length - 1]\n\t\t\t\t\tlastPoint.x = newPoint.x\n\t\t\t\t\tlastPoint.y = newPoint.y\n\t\t\t\t\tlastPoint.z = lastPoint.z ? Math.max(lastPoint.z, newPoint.z) : newPoint.z\n\t\t\t\t\t// Note: we could recompute the line length here, but it's not really necessary\n\t\t\t\t\t// this.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t} else {\n\t\t\t\t\tthis.currentLineLength += cachedPoints.length\n\t\t\t\t\t\t? Vec.Dist(cachedPoints[cachedPoints.length - 1], newPoint)\n\t\t\t\t\t\t: 0\n\t\t\t\t\tcachedPoints.push(new Vec(newPoint.x, newPoint.y, newPoint.z))\n\t\t\t\t}\n\n\t\t\t\tconst newSegments = segments.slice()\n\t\t\t\tconst newSegment = newSegments[newSegments.length - 1]\n\t\t\t\tnewSegments[newSegments.length - 1] = {\n\t\t\t\t\t...newSegment,\n\t\t\t\t\tpath: b64Vecs.encodePoints(cachedPoints, newSegment.dim),\n\t\t\t\t}\n\n\t\t\t\tconst dvStrokeWidth = (getDisplayValues(this.util as any, shape) as { strokeWidth: number })\n\t\t\t\t\t.strokeWidth\n\t\t\t\tif (this.currentLineLength < dvStrokeWidth * 4) {\n\t\t\t\t\tthis.currentLineLength = this.getLineLength(newSegments)\n\t\t\t\t}\n\n\t\t\t\tconst shapePartial: TLShapePartial<DrawableShape> = {\n\t\t\t\t\tid,\n\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\tsegments: newSegments,\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tif (this.canClose()) {\n\t\t\t\t\t;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(\n\t\t\t\t\t\tnewSegments,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\tscale\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\tthis.editor.updateShapes([shapePartial])\n\n\t\t\t\t// Set a maximum length for the lines array; after 200 points, complete the line.\n\t\t\t\tif (cachedPoints.length > this.util.options.maxPointsPerShape) {\n\t\t\t\t\tthis.editor.updateShapes([{ id, type: this.shapeType, props: { isComplete: true } }])\n\n\t\t\t\t\tconst newShapeId = createShapeId()\n\n\t\t\t\t\tconst props = this.editor.getShape<DrawableShape>(id)!.props\n\n\t\t\t\t\tif (!this.editor.canCreateShapes([newShapeId])) return this.cancel()\n\t\t\t\t\tconst currentPagePoint = inputs.getCurrentPagePoint()\n\n\t\t\t\t\t// Reset cache for the new shape's segment\n\t\t\t\t\tconst initialPoint = new Vec(0, 0, this.isPenOrStylus ? +(z! * 1.25).toFixed() : 0.5)\n\t\t\t\t\tthis.currentSegmentPoints = [initialPoint]\n\n\t\t\t\t\tthis.editor.createShape({\n\t\t\t\t\t\tid: newShapeId,\n\t\t\t\t\t\ttype: this.shapeType,\n\t\t\t\t\t\tx: toFixed(currentPagePoint.x),\n\t\t\t\t\t\ty: toFixed(currentPagePoint.y),\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tisPen: this.isPenOrStylus,\n\t\t\t\t\t\t\tscale: props.scale,\n\t\t\t\t\t\t\tsegments: [this.makeSegment('free', [initialPoint])],\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\tconst shape = this.editor.getShape<DrawableShape>(newShapeId)\n\n\t\t\t\t\tif (!shape) {\n\t\t\t\t\t\t// This would only happen if the page is full and no more shapes can be created. The bug would manifest as a crash when we try to clone the shape.\n\t\t\t\t\t\t// todo: handle this type of thing better\n\t\t\t\t\t\treturn this.cancel()\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.initialShape = structuredClone(shape)\n\t\t\t\t\tthis.mergeNextPoint = false\n\t\t\t\t\tthis.lastRecordedPoint = currentPagePoint.clone()\n\t\t\t\t\tthis.currentLineLength = 0\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getLineLength(segments: TLDrawShapeSegment[]) {\n\t\tlet length = 0\n\n\t\tfor (let j = 0; j < segments.length; j++) {\n\t\t\tconst points = b64Vecs.decodePoints(segments[j].path, segments[j].dim)\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tlength += Vec.Dist2(points[i], points[i + 1])\n\t\t\t}\n\t\t}\n\n\t\treturn Math.sqrt(length)\n\t}\n\n\toverride onPointerUp() {\n\t\tthis.complete()\n\t}\n\n\toverride onCancel() {\n\t\tthis.cancel()\n\t}\n\n\toverride onComplete() {\n\t\tthis.complete()\n\t}\n\n\toverride onInterrupt() {\n\t\tif (this.editor.inputs.getIsDragging()) {\n\t\t\treturn\n\t\t}\n\n\t\tif (this.markId) {\n\t\t\tthis.editor.bailToMark(this.markId)\n\t\t}\n\t\tthis.cancel()\n\t}\n\n\tcomplete() {\n\t\tconst { initialShape } = this\n\t\tif (!initialShape) return\n\t\tthis.editor.updateShapes([\n\t\t\t{ id: initialShape.id, type: initialShape.type, props: { isComplete: true } },\n\t\t])\n\n\t\tthis.parent.transition('idle')\n\t}\n\n\tcancel() {\n\t\tthis.parent.transition('idle', this.info)\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["shape", "inputs", "currentPagePoint", "newPoint"]
|
|
7
7
|
}
|
|
@@ -37,6 +37,7 @@ class EmbedShapeUtil extends import_editor.BaseBoxShapeUtil {
|
|
|
37
37
|
static migrations = import_editor.embedShapeMigrations;
|
|
38
38
|
options = {
|
|
39
39
|
embedDefinitions: import_defaultEmbedDefinitions.DEFAULT_EMBED_DEFINITIONS,
|
|
40
|
+
embedConfig: {},
|
|
40
41
|
getDefaultDisplayValues() {
|
|
41
42
|
return {
|
|
42
43
|
showShadow: true
|
|
@@ -63,7 +64,7 @@ class EmbedShapeUtil extends import_editor.BaseBoxShapeUtil {
|
|
|
63
64
|
return this.getEmbedDefs();
|
|
64
65
|
}
|
|
65
66
|
getEmbedDefinition(url) {
|
|
66
|
-
return (0, import_embeds.getEmbedInfo)(this.getEmbedDefs(), url);
|
|
67
|
+
return (0, import_embeds.getEmbedInfo)(this.getEmbedDefs(), url, this.options.embedConfig);
|
|
67
68
|
}
|
|
68
69
|
getText(shape) {
|
|
69
70
|
return shape.props.url;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/embed/EmbedShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseColorMode,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tEmbedDefinition,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n\tunknownEmbedShapePermissionOverrides,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { BookmarkShapeComponent } from '../bookmark/BookmarkShapeUtil'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\n/** @public */\nexport interface EmbedShapeUtilDisplayValues {\n\tshowShadow: boolean\n}\n\n/** @public */\nexport interface EmbedShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLEmbedShape,\n\tEmbedShapeUtilDisplayValues\n> {\n\t/** The embed definitions to use for this shape util. */\n\treadonly embedDefinitions: readonly TLEmbedDefinition[]\n}\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\n\toverride options: EmbedShapeOptions = {\n\t\tembedDefinitions: DEFAULT_EMBED_DEFINITIONS,\n\t\tgetDefaultDisplayValues(): EmbedShapeUtilDisplayValues {\n\t\t\treturn {\n\t\t\t\tshowShadow: true,\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<EmbedShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride canEditWhileLocked(shape: TLEmbedShape) {\n\t\tconst result = this.getEmbedDefinition(shape.props.url)\n\t\tif (!result) return true\n\t\treturn result.definition.canEditWhileLocked ?? true\n\t}\n\n\tprivate static legacyEmbedDefinitions: readonly EmbedDefinition[] | null = null\n\n\t/** @deprecated - Use `EmbedShapeUtil.configure({ embedDefinitions: [...] })` instead. */\n\tstatic setEmbedDefinitions(embedDefinitions: readonly EmbedDefinition[]) {\n\t\tEmbedShapeUtil.legacyEmbedDefinitions = embedDefinitions\n\t}\n\n\tprivate getEmbedDefs(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.legacyEmbedDefinitions ?? this.options.embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn this.getEmbedDefs()\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(this.getEmbedDefs(), url)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit(shape: TLEmbedShape) {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn this.getEmbedDefinition(shape.props.url)?.definition?.doesResize ?? true\n\t}\n\toverride canEditInReadonly(shape: TLEmbedShape) {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLEmbedShape) {\n\t\treturn super.getGeometry(shape)\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\t\tconst colorMode = useColorMode()\n\t\tconst dv = getDisplayValues(this, shape, colorMode)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: dv.showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo\n\t\t\t\t? (embedInfo.definition.overridePermissions ?? {})\n\t\t\t\t: unknownEmbedShapePermissionOverrides),\n\t\t})\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\t// Gist embeds use srcDoc, so we must disable allow-same-origin. Otherwise\n\t\t\t// the embedded script shares the parent's origin and can escape the sandbox.\n\t\t\tconst gistSandbox = getSandboxPermissions({\n\t\t\t\t...embedShapePermissionDefaults,\n\t\t\t\t...(embedInfo?.definition?.overridePermissions ?? {}),\n\t\t\t\t'allow-same-origin': false,\n\t\t\t})\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\tsandbox={gistSandbox}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t\tshowShadow={dv.showShadow}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst iframeSrc = embedInfo?.embedUrl ?? url\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{iframeSrc ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={iframeSrc}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tallowFullScreen\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: dv.showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition?.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition?.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<BookmarkShapeComponent\n\t\t\t\t\t\turl={url}\n\t\t\t\t\t\th={h}\n\t\t\t\t\t\trotation={pageRotation}\n\t\t\t\t\t\tassetId={null}\n\t\t\t\t\t\tshowImageContainer={false}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLEmbedShape): Path2D {\n\t\tconst path = new Path2D()\n\t\tpath.rect(0, 0, shape.props.w, shape.props.h)\n\t\treturn path\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tsandbox,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n\tshowShadow,\n}: {\n\tid: string\n\tsandbox: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tshowShadow: boolean\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tsandbox={sandbox}\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\n\nimport {\n\tBaseBoxShapeUtil,\n\tHTMLContainer,\n\tTLEmbedShape,\n\tTLEmbedShapeProps,\n\tTLResizeInfo,\n\tembedShapeMigrations,\n\tembedShapeProps,\n\tlerp,\n\tresizeBox,\n\ttoDomPrecision,\n\tuseColorMode,\n\tuseIsEditing,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\nimport {\n\tDEFAULT_EMBED_DEFINITIONS,\n\tDefaultEmbedConfig,\n\tTLEmbedDefinition,\n\tTLEmbedShapePermissions,\n\tembedShapePermissionDefaults,\n\tunknownEmbedShapePermissionOverrides,\n} from '../../defaultEmbedDefinitions'\nimport { TLEmbedResult, getEmbedInfo } from '../../utils/embeds/embeds'\nimport { BookmarkShapeComponent } from '../bookmark/BookmarkShapeUtil'\nimport { ShapeOptionsWithDisplayValues, getDisplayValues } from '../shared/getDisplayValues'\nimport { getRotatedBoxShadow } from '../shared/rotated-box-shadow'\n\n/** @public */\nexport interface EmbedShapeUtilDisplayValues {\n\tshowShadow: boolean\n}\n\n/** @public */\nexport interface EmbedShapeOptions extends ShapeOptionsWithDisplayValues<\n\tTLEmbedShape,\n\tEmbedShapeUtilDisplayValues\n> {\n\t/** The embed definitions to use for this shape util. */\n\treadonly embedDefinitions: readonly TLEmbedDefinition[]\n\t/**\n\t * Per-embed configuration, keyed by embed type. Passed to each definition's `toEmbedUrl` when\n\t * building its embed URL \u2014 for example, an API key for the default Google Maps embed:\n\t *\n\t * ```ts\n\t * EmbedShapeUtil.configure({ embedConfig: { google_maps: { apiKey: '...' } } })\n\t * ```\n\t */\n\treadonly embedConfig?: DefaultEmbedConfig & Record<string, unknown>\n}\n\nconst getSandboxPermissions = (permissions: TLEmbedShapePermissions) => {\n\treturn Object.entries(permissions)\n\t\t.filter(([_perm, isEnabled]) => isEnabled)\n\t\t.map(([perm]) => perm)\n\t\t.join(' ')\n}\n\n/** @public */\nexport class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {\n\tstatic override type = 'embed' as const\n\tstatic override props = embedShapeProps\n\tstatic override migrations = embedShapeMigrations\n\n\toverride options: EmbedShapeOptions = {\n\t\tembedDefinitions: DEFAULT_EMBED_DEFINITIONS,\n\t\tembedConfig: {},\n\t\tgetDefaultDisplayValues(): EmbedShapeUtilDisplayValues {\n\t\t\treturn {\n\t\t\t\tshowShadow: true,\n\t\t\t}\n\t\t},\n\t\tgetCustomDisplayValues(): Partial<EmbedShapeUtilDisplayValues> {\n\t\t\treturn {}\n\t\t},\n\t}\n\n\toverride canEditWhileLocked(shape: TLEmbedShape) {\n\t\tconst result = this.getEmbedDefinition(shape.props.url)\n\t\tif (!result) return true\n\t\treturn result.definition.canEditWhileLocked ?? true\n\t}\n\n\tprivate static legacyEmbedDefinitions: readonly TLEmbedDefinition[] | null = null\n\n\t/** @deprecated - Use `EmbedShapeUtil.configure({ embedDefinitions: [...] })` instead. */\n\tstatic setEmbedDefinitions(embedDefinitions: readonly TLEmbedDefinition[]) {\n\t\tEmbedShapeUtil.legacyEmbedDefinitions = embedDefinitions\n\t}\n\n\tprivate getEmbedDefs(): readonly TLEmbedDefinition[] {\n\t\treturn EmbedShapeUtil.legacyEmbedDefinitions ?? this.options.embedDefinitions\n\t}\n\n\tgetEmbedDefinitions(): readonly TLEmbedDefinition[] {\n\t\treturn this.getEmbedDefs()\n\t}\n\n\tgetEmbedDefinition(url: string): TLEmbedResult {\n\t\treturn getEmbedInfo(this.getEmbedDefs(), url, this.options.embedConfig)\n\t}\n\n\toverride getText(shape: TLEmbedShape) {\n\t\treturn shape.props.url\n\t}\n\n\toverride getAriaDescriptor(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.title\n\t}\n\n\toverride hideSelectionBoundsFg(shape: TLEmbedShape) {\n\t\treturn !this.canResize(shape)\n\t}\n\toverride canEdit(shape: TLEmbedShape) {\n\t\treturn true\n\t}\n\toverride canResize(shape: TLEmbedShape) {\n\t\treturn this.getEmbedDefinition(shape.props.url)?.definition?.doesResize ?? true\n\t}\n\toverride canEditInReadonly(shape: TLEmbedShape) {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLEmbedShape['props'] {\n\t\treturn {\n\t\t\tw: 300,\n\t\t\th: 300,\n\t\t\turl: '',\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLEmbedShape) {\n\t\treturn super.getGeometry(shape)\n\t}\n\n\toverride isAspectRatioLocked(shape: TLEmbedShape) {\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\treturn embedInfo?.definition.isAspectRatioLocked ?? false\n\t}\n\n\toverride onResize(shape: TLEmbedShape, info: TLResizeInfo<TLEmbedShape>) {\n\t\tconst isAspectRatioLocked = this.isAspectRatioLocked(shape)\n\t\tconst embedInfo = this.getEmbedDefinition(shape.props.url)\n\t\tlet minWidth = embedInfo?.definition.minWidth ?? 200\n\t\tlet minHeight = embedInfo?.definition.minHeight ?? 200\n\t\tif (isAspectRatioLocked) {\n\t\t\t// Enforce aspect ratio\n\t\t\t// Neither the width or height can be less than 200\n\t\t\tconst aspectRatio = shape.props.w / shape.props.h\n\t\t\tif (aspectRatio > 1) {\n\t\t\t\t// Landscape\n\t\t\t\tminWidth *= aspectRatio\n\t\t\t} else {\n\t\t\t\t// Portrait\n\t\t\t\tminHeight /= aspectRatio\n\t\t\t}\n\t\t}\n\n\t\treturn resizeBox(shape, info, { minWidth, minHeight })\n\t}\n\n\toverride component(shape: TLEmbedShape) {\n\t\tconst svgExport = useSvgExportContext()\n\t\tconst { w, h, url } = shape.props\n\t\tconst isEditing = useIsEditing(shape.id)\n\t\tconst colorMode = useColorMode()\n\t\tconst dv = getDisplayValues(this, shape, colorMode)\n\n\t\tconst embedInfo = this.getEmbedDefinition(url)\n\n\t\tconst isHoveringWhileEditingSameShape = useValue(\n\t\t\t'is hovering',\n\t\t\t() => {\n\t\t\t\tconst { editingShapeId, hoveredShapeId } = this.editor.getCurrentPageState()\n\n\t\t\t\tif (editingShapeId && hoveredShapeId !== editingShapeId) {\n\t\t\t\t\tconst editingShape = this.editor.getShape(editingShapeId)\n\t\t\t\t\tif (editingShape && this.editor.isShapeOfType(editingShape, 'embed')) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t},\n\t\t\t[]\n\t\t)\n\n\t\tconst pageRotation = this.editor.getShapePageTransform(shape)!.rotation()\n\n\t\tif (svgExport) {\n\t\t\t// for SVG exports, we show a blank embed\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tboxShadow: dv.showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',\n\t\t\t\t\t\t\twidth: w,\n\t\t\t\t\t\t\theight: h,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst isInteractive = isEditing || isHoveringWhileEditingSameShape\n\n\t\t// Prevent nested embedding of tldraw\n\t\tconst isIframe =\n\t\t\ttypeof window !== 'undefined' && (window !== window.top || window.self !== window.parent)\n\t\tif (isIframe && embedInfo?.definition.type === 'tldraw') return null\n\n\t\tconst sandbox = getSandboxPermissions({\n\t\t\t...embedShapePermissionDefaults,\n\t\t\t...(embedInfo\n\t\t\t\t? (embedInfo.definition.overridePermissions ?? {})\n\t\t\t\t: unknownEmbedShapePermissionOverrides),\n\t\t})\n\n\t\tif (embedInfo?.definition.type === 'github_gist') {\n\t\t\tconst idFromGistUrl = embedInfo.url.split('/').pop()\n\t\t\tif (!idFromGistUrl) throw Error('No gist id!')\n\n\t\t\t// Gist embeds use srcDoc, so we must disable allow-same-origin. Otherwise\n\t\t\t// the embedded script shares the parent's origin and can escape the sandbox.\n\t\t\tconst gistSandbox = getSandboxPermissions({\n\t\t\t\t...embedShapePermissionDefaults,\n\t\t\t\t...(embedInfo?.definition?.overridePermissions ?? {}),\n\t\t\t\t'allow-same-origin': false,\n\t\t\t})\n\n\t\t\treturn (\n\t\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t\t<Gist\n\t\t\t\t\t\tid={idFromGistUrl}\n\t\t\t\t\t\tsandbox={gistSandbox}\n\t\t\t\t\t\twidth={toDomPrecision(w)!}\n\t\t\t\t\t\theight={toDomPrecision(h)!}\n\t\t\t\t\t\tisInteractive={isInteractive}\n\t\t\t\t\t\tpageRotation={pageRotation}\n\t\t\t\t\t\tshowShadow={dv.showShadow}\n\t\t\t\t\t/>\n\t\t\t\t</HTMLContainer>\n\t\t\t)\n\t\t}\n\n\t\tconst iframeSrc = embedInfo?.embedUrl ?? url\n\n\t\treturn (\n\t\t\t<HTMLContainer className=\"tl-embed-container\" id={shape.id}>\n\t\t\t\t{iframeSrc ? (\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tclassName=\"tl-embed\"\n\t\t\t\t\t\tsandbox={sandbox}\n\t\t\t\t\t\tsrc={iframeSrc}\n\t\t\t\t\t\twidth={toDomPrecision(w)}\n\t\t\t\t\t\theight={toDomPrecision(h)}\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\t\t\t\tframeBorder=\"0\"\n\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\ttabIndex={isEditing ? 0 : -1}\n\t\t\t\t\t\tallowFullScreen\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpointerEvents: isInteractive ? 'auto' : 'none',\n\t\t\t\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\t\t\t\tboxShadow: dv.showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t\t\t\t\tborderRadius: embedInfo?.definition?.overrideOutlineRadius ?? 8,\n\t\t\t\t\t\t\tbackground: embedInfo?.definition?.backgroundColor,\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<BookmarkShapeComponent\n\t\t\t\t\t\turl={url}\n\t\t\t\t\t\th={h}\n\t\t\t\t\t\trotation={pageRotation}\n\t\t\t\t\t\tassetId={null}\n\t\t\t\t\t\tshowImageContainer={false}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\toverride getIndicatorPath(shape: TLEmbedShape): Path2D {\n\t\tconst path = new Path2D()\n\t\tpath.rect(0, 0, shape.props.w, shape.props.h)\n\t\treturn path\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLEmbedShape,\n\t\tendShape: TLEmbedShape,\n\t\tt: number\n\t): TLEmbedShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t}\n\t}\n}\n\nfunction Gist({\n\tid,\n\tsandbox,\n\tisInteractive,\n\twidth,\n\theight,\n\tstyle,\n\tpageRotation,\n\tshowShadow,\n}: {\n\tid: string\n\tsandbox: string\n\tisInteractive: boolean\n\twidth: number\n\theight: number\n\tpageRotation: number\n\tshowShadow: boolean\n\tstyle?: React.CSSProperties\n}) {\n\t// Security warning:\n\t// Gists allow adding .json extensions to the URL which return JSONP.\n\t// Furthermore, the JSONP can include callbacks that execute arbitrary JavaScript.\n\t// It _is_ sandboxed by the iframe but we still want to disable it nonetheless.\n\t// We restrict the id to only allow hexdecimal characters to prevent this.\n\t// Read more:\n\t// https://github.com/bhaveshk90/Content-Security-Policy-CSP-Bypass-Techniques\n\t// https://github.com/renniepak/CSPBypass\n\tif (!id.match(/^[0-9a-f]+$/)) throw Error('No gist id!')\n\n\treturn (\n\t\t<iframe\n\t\t\tclassName=\"tl-embed\"\n\t\t\tsandbox={sandbox}\n\t\t\tdraggable={false}\n\t\t\twidth={toDomPrecision(width)}\n\t\t\theight={toDomPrecision(height)}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tframeBorder=\"0\"\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tscrolling=\"no\"\n\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\ttabIndex={isInteractive ? 0 : -1}\n\t\t\tstyle={{\n\t\t\t\t...style,\n\t\t\t\tpointerEvents: isInteractive ? 'all' : 'none',\n\t\t\t\t// Fix for safari <https://stackoverflow.com/a/49150908>\n\t\t\t\tzIndex: isInteractive ? '' : '-1',\n\t\t\t\tboxShadow: showShadow ? getRotatedBoxShadow(pageRotation) : 'none',\n\t\t\t}}\n\t\t\tsrcDoc={`\n\t\t\t<html>\n\t\t\t\t<head>\n\t\t\t\t\t<base target=\"_blank\">\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<script src=${`https://gist.github.com/${id}.js`}></script>\n\t\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\t\t* { margin: 0px; }\n\t\t\t\t\t\ttable { height: 100%; background-color: red; }\n\t\t\t\t\t\t.gist { background-color: none; height: 100%; }\n\t\t\t\t\t\t.gist .gist-file { height: calc(100vh - 2px); padding: 0px; display: grid; grid-template-rows: 1fr auto; }\n\t\t\t\t\t</style>\n\t\t\t\t</body>\n\t\t\t</html>`}\n\t\t/>\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -18,7 +18,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var FrameShapeTool_exports = {};
|
|
20
20
|
__export(FrameShapeTool_exports, {
|
|
21
|
-
FrameShapeTool: () => FrameShapeTool
|
|
21
|
+
FrameShapeTool: () => FrameShapeTool,
|
|
22
|
+
getEnclosedShapeIds: () => getEnclosedShapeIds
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(FrameShapeTool_exports);
|
|
24
25
|
var import_editor = require("@tldraw/editor");
|
|
@@ -28,23 +29,7 @@ class FrameShapeTool extends import_editor.BaseBoxShapeTool {
|
|
|
28
29
|
shapeType = "frame";
|
|
29
30
|
onCreate(shape) {
|
|
30
31
|
if (!shape) return;
|
|
31
|
-
|
|
32
|
-
const shapesToAddToFrame = [];
|
|
33
|
-
const ancestorIds = this.editor.getShapeAncestors(shape).map((shape2) => shape2.id);
|
|
34
|
-
this.editor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => {
|
|
35
|
-
const siblingShape = this.editor.getShape(siblingShapeId);
|
|
36
|
-
if (!siblingShape) return;
|
|
37
|
-
if (siblingShape.id === shape.id) return;
|
|
38
|
-
if (siblingShape.isLocked) return;
|
|
39
|
-
const pageShapeBounds = this.editor.getShapePageBounds(siblingShape);
|
|
40
|
-
if (!pageShapeBounds) return;
|
|
41
|
-
if (bounds.contains(pageShapeBounds)) {
|
|
42
|
-
if (canEnclose(siblingShape, ancestorIds, shape)) {
|
|
43
|
-
shapesToAddToFrame.push(siblingShape.id);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
this.editor.reparentShapes(shapesToAddToFrame, shape.id);
|
|
32
|
+
this.editor.reparentShapes(getEnclosedShapeIds(this.editor, shape), shape.id);
|
|
48
33
|
if (this.editor.getInstanceState().isToolLocked) {
|
|
49
34
|
this.editor.setCurrentTool("frame");
|
|
50
35
|
} else {
|
|
@@ -52,6 +37,26 @@ class FrameShapeTool extends import_editor.BaseBoxShapeTool {
|
|
|
52
37
|
}
|
|
53
38
|
}
|
|
54
39
|
}
|
|
40
|
+
function getEnclosedShapeIds(editor, shape) {
|
|
41
|
+
const bounds = editor.getShapePageBounds(shape);
|
|
42
|
+
if (!bounds) return [];
|
|
43
|
+
const enclosedShapeIds = [];
|
|
44
|
+
const ancestorIds = editor.getShapeAncestors(shape).map((shape2) => shape2.id);
|
|
45
|
+
editor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => {
|
|
46
|
+
const siblingShape = editor.getShape(siblingShapeId);
|
|
47
|
+
if (!siblingShape) return;
|
|
48
|
+
if (siblingShape.id === shape.id) return;
|
|
49
|
+
if (siblingShape.isLocked) return;
|
|
50
|
+
const pageShapeBounds = editor.getShapePageBounds(siblingShape);
|
|
51
|
+
if (!pageShapeBounds) return;
|
|
52
|
+
if (bounds.contains(pageShapeBounds)) {
|
|
53
|
+
if (canEnclose(siblingShape, ancestorIds, shape)) {
|
|
54
|
+
enclosedShapeIds.push(siblingShape.id);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return enclosedShapeIds;
|
|
59
|
+
}
|
|
55
60
|
function canEnclose(shape, ancestorIds, frame) {
|
|
56
61
|
if (ancestorIds.includes(shape.id)) {
|
|
57
62
|
return false;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/frame/FrameShapeTool.ts"],
|
|
4
|
-
"sourcesContent": ["import { BaseBoxShapeTool, TLShape, TLShapeId } from '@tldraw/editor'\n\n/** @public */\nexport class FrameShapeTool extends BaseBoxShapeTool {\n\tstatic override id = 'frame'\n\tstatic override initial = 'idle'\n\toverride shapeType = 'frame' as const\n\n\toverride onCreate(shape: TLShape | null): void {\n\t\tif (!shape) return\n\n\t\tconst bounds =
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import { BaseBoxShapeTool, Editor, TLShape, TLShapeId } from '@tldraw/editor'\n\n/** @public */\nexport class FrameShapeTool extends BaseBoxShapeTool {\n\tstatic override id = 'frame'\n\tstatic override initial = 'idle'\n\toverride shapeType = 'frame' as const\n\n\toverride onCreate(shape: TLShape | null): void {\n\t\tif (!shape) return\n\n\t\tthis.editor.reparentShapes(getEnclosedShapeIds(this.editor, shape), shape.id)\n\n\t\tif (this.editor.getInstanceState().isToolLocked) {\n\t\t\tthis.editor.setCurrentTool('frame')\n\t\t} else {\n\t\t\tthis.editor.setCurrentTool('select.idle')\n\t\t}\n\t}\n}\n\n/**\n * Get the ids of the sibling shapes that a frame would enclose at its current page bounds.\n *\n * @internal\n */\nexport function getEnclosedShapeIds(editor: Editor, shape: TLShape): TLShapeId[] {\n\tconst bounds = editor.getShapePageBounds(shape)\n\tif (!bounds) return []\n\n\tconst enclosedShapeIds: TLShapeId[] = []\n\tconst ancestorIds = editor.getShapeAncestors(shape).map((shape) => shape.id)\n\n\teditor.getSortedChildIdsForParent(shape.parentId).map((siblingShapeId) => {\n\t\tconst siblingShape = editor.getShape(siblingShapeId)\n\t\tif (!siblingShape) return\n\t\t// We don't want to frame the frame itself\n\t\tif (siblingShape.id === shape.id) return\n\t\tif (siblingShape.isLocked) return\n\n\t\tconst pageShapeBounds = editor.getShapePageBounds(siblingShape)\n\t\tif (!pageShapeBounds) return\n\n\t\t// Frame shape encloses page shape\n\t\tif (bounds.contains(pageShapeBounds)) {\n\t\t\tif (canEnclose(siblingShape, ancestorIds, shape)) {\n\t\t\t\tenclosedShapeIds.push(siblingShape.id)\n\t\t\t}\n\t\t}\n\t})\n\n\treturn enclosedShapeIds\n}\n\n/** @internal */\nfunction canEnclose(shape: TLShape, ancestorIds: TLShapeId[], frame: TLShape): boolean {\n\t// We don't want to pull in shapes that are ancestors of the frame (can create a cycle)\n\tif (ancestorIds.includes(shape.id)) {\n\t\treturn false\n\t}\n\t// We only want to pull in shapes that are siblings of the frame\n\tif (shape.parentId === frame.parentId) {\n\t\treturn true\n\t}\n\treturn false\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA6D;AAGtD,MAAM,uBAAuB,+BAAiB;AAAA,EACpD,OAAgB,KAAK;AAAA,EACrB,OAAgB,UAAU;AAAA,EACjB,YAAY;AAAA,EAEZ,SAAS,OAA6B;AAC9C,QAAI,CAAC,MAAO;AAEZ,SAAK,OAAO,eAAe,oBAAoB,KAAK,QAAQ,KAAK,GAAG,MAAM,EAAE;AAE5E,QAAI,KAAK,OAAO,iBAAiB,EAAE,cAAc;AAChD,WAAK,OAAO,eAAe,OAAO;AAAA,IACnC,OAAO;AACN,WAAK,OAAO,eAAe,aAAa;AAAA,IACzC;AAAA,EACD;AACD;AAOO,SAAS,oBAAoB,QAAgB,OAA6B;AAChF,QAAM,SAAS,OAAO,mBAAmB,KAAK;AAC9C,MAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,QAAM,mBAAgC,CAAC;AACvC,QAAM,cAAc,OAAO,kBAAkB,KAAK,EAAE,IAAI,CAACA,WAAUA,OAAM,EAAE;AAE3E,SAAO,2BAA2B,MAAM,QAAQ,EAAE,IAAI,CAAC,mBAAmB;AACzE,UAAM,eAAe,OAAO,SAAS,cAAc;AACnD,QAAI,CAAC,aAAc;AAEnB,QAAI,aAAa,OAAO,MAAM,GAAI;AAClC,QAAI,aAAa,SAAU;AAE3B,UAAM,kBAAkB,OAAO,mBAAmB,YAAY;AAC9D,QAAI,CAAC,gBAAiB;AAGtB,QAAI,OAAO,SAAS,eAAe,GAAG;AACrC,UAAI,WAAW,cAAc,aAAa,KAAK,GAAG;AACjD,yBAAiB,KAAK,aAAa,EAAE;AAAA,MACtC;AAAA,IACD;AAAA,EACD,CAAC;AAED,SAAO;AACR;AAGA,SAAS,WAAW,OAAgB,aAA0B,OAAyB;AAEtF,MAAI,YAAY,SAAS,MAAM,EAAE,GAAG;AACnC,WAAO;AAAA,EACR;AAEA,MAAI,MAAM,aAAa,MAAM,UAAU;AACtC,WAAO;AAAA,EACR;AACA,SAAO;AACR;",
|
|
6
6
|
"names": ["shape"]
|
|
7
7
|
}
|
|
@@ -158,7 +158,7 @@ class GeoShapeUtil extends import_editor.BaseBoxShapeUtil {
|
|
|
158
158
|
const unscaledLabelSize = isEmptyLabel ? GEO_SHAPE_EMPTY_LABEL_SIZE : this.getUnscaledLabelSize(shape);
|
|
159
159
|
const unscaledMinWidth = Math.min(100, unscaledShapeW / 2);
|
|
160
160
|
const unscaledMinHeight = Math.min(
|
|
161
|
-
dv.labelFontSize
|
|
161
|
+
(0, import_editor.resolveLineHeightPx)(dv.labelFontSize, dv.labelLineHeight) + dv.labelPadding * 2,
|
|
162
162
|
unscaledShapeH / 2
|
|
163
163
|
);
|
|
164
164
|
const unscaledLabelW = Math.min(
|