tldraw 3.16.0-next.34fddf633325 → 3.16.0-next.4337ae1ab96d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +324 -105
- package/dist-cjs/index.js +40 -14
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/Tldraw.js +12 -2
- package/dist-cjs/lib/Tldraw.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
- package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -4
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
- package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
- package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +18 -12
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
- package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
- package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +6 -3
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
- package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +0 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
- package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
- package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
- package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
- package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
- package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
- package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
- package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +27 -12
- package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
- package/dist-cjs/lib/ui/assetUrls.js +13 -10
- package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +12 -3
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
- package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
- package/dist-cjs/lib/ui/components/DefaultMenuPanel.js +3 -2
- package/dist-cjs/lib/ui/components/DefaultMenuPanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +6 -6
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
- package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
- package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +1 -1
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +2 -1
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/{primitives/TldrawUiButtonPicker.js → StylePanel/StylePanelButtonPicker.js} +52 -56
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +26 -25
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +47 -43
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +39 -10
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
- package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +10 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +17 -4
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +21 -4
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +161 -159
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
- package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +154 -20
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +23 -10
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/components.js +2 -0
- package/dist-cjs/lib/ui/context/components.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
- package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
- 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/kbd-utils.js +9 -3
- package/dist-cjs/lib/ui/kbd-utils.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/export/copyAs.js +1 -2
- package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
- package/dist-cjs/lib/utils/export/export.js +0 -20
- package/dist-cjs/lib/utils/export/export.js.map +2 -2
- package/dist-cjs/lib/utils/export/exportAs.js +1 -2
- package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
- package/dist-esm/index.d.mts +324 -105
- package/dist-esm/index.mjs +75 -29
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/Tldraw.mjs +14 -4
- package/dist-esm/lib/Tldraw.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +4 -3
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
- package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
- package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +19 -12
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
- package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
- package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +6 -3
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +0 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
- package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
- package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
- package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
- package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
- package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/ui/TldrawUi.mjs +29 -14
- package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
- package/dist-esm/lib/ui/assetUrls.mjs +13 -10
- package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +12 -3
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
- package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
- package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs +3 -2
- package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +6 -6
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
- package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
- package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +1 -1
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -1
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs +3 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs +2 -2
- package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +126 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +23 -22
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +44 -40
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +39 -10
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -21
- package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
- package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +3 -3
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -81
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +2 -2
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +10 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +3 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +17 -4
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +21 -4
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +170 -161
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/layout.mjs +46 -0
- package/dist-esm/lib/ui/components/primitives/layout.mjs.map +7 -0
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +162 -22
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +23 -10
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/components.mjs +2 -0
- package/dist-esm/lib/ui/context/components.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
- package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
- 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/kbd-utils.mjs +9 -3
- package/dist-esm/lib/ui/kbd-utils.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/export/copyAs.mjs +1 -2
- package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
- package/dist-esm/lib/utils/export/export.mjs +0 -20
- package/dist-esm/lib/utils/export/export.mjs.map +2 -2
- package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
- package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
- package/package.json +11 -34
- package/src/index.ts +56 -22
- package/src/lib/Tldraw.tsx +15 -2
- package/src/lib/canvas/TldrawScribble.tsx +1 -1
- package/src/lib/defaultExternalContentHandlers.ts +12 -4
- package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
- package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +7 -6
- package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
- package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
- package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
- package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
- package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
- package/src/lib/shapes/frame/FrameShapeUtil.tsx +29 -14
- package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
- package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
- package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
- package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
- package/src/lib/shapes/image/ImageShapeUtil.tsx +6 -3
- package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
- package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
- package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
- package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
- package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
- package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
- package/src/lib/shapes/shared/freehand/svg.ts +2 -0
- package/src/lib/shapes/shared/useEditablePlainText.ts +0 -6
- package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
- package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
- package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
- package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
- package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
- package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
- package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -1
- package/src/lib/ui/TldrawUi.tsx +33 -12
- package/src/lib/ui/assetUrls.ts +13 -10
- package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
- package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
- package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
- package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
- package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
- package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +1 -1
- package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +3 -2
- package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
- package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
- package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
- package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -385
- package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +66 -50
- package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
- package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +31 -22
- package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
- package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
- package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +4 -3
- package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +33 -16
- package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
- package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
- package/src/lib/ui/components/Toolbar/LinkEditor.tsx +5 -5
- package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
- package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +2 -2
- package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +6 -1
- package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
- package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +50 -30
- package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +35 -9
- package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +203 -181
- package/src/lib/ui/components/primitives/layout.tsx +107 -0
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +221 -19
- package/src/lib/ui/context/actions.tsx +23 -10
- package/src/lib/ui/context/components.tsx +3 -0
- package/src/lib/ui/context/events.tsx +2 -1
- package/src/lib/ui/hooks/useExportAs.ts +3 -2
- package/src/lib/ui/hooks/useTools.tsx +140 -10
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
- package/src/lib/ui/kbd-utils.ts +10 -3
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +381 -306
- package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
- package/src/lib/utils/export/copyAs.ts +1 -24
- package/src/lib/utils/export/export.ts +0 -36
- package/src/lib/utils/export/exportAs.ts +1 -32
- package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
- package/src/test/A11y.test.tsx +3 -2
- package/src/test/ClickManager.test.ts +7 -6
- package/src/test/Editor.test.tsx +20 -19
- package/src/test/EraserTool.test.ts +184 -13
- package/src/test/HandTool.test.ts +10 -9
- package/src/test/HighlightShape.test.ts +2 -1
- package/src/test/SelectTool.test.ts +3 -2
- package/src/test/TLUserPreferences.test.ts +4 -3
- package/src/test/TestEditor.ts +13 -15
- package/src/test/TldrawEditor.test.tsx +11 -10
- package/src/test/ZoomTool.test.ts +7 -6
- package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
- package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
- package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
- package/src/test/arrows-megabus.test.tsx +5 -4
- package/src/test/bindings.test.tsx +24 -37
- package/src/test/bookmark-shapes.test.ts +1 -8
- package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
- package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
- package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
- package/src/test/commands/alignShapes.test.tsx +25 -24
- package/src/test/commands/animationSpeed.test.ts +2 -1
- package/src/test/commands/centerOnPoint.test.ts +3 -2
- package/src/test/commands/clipboard.test.ts +3 -2
- package/src/test/commands/createShapes.test.ts +2 -1
- package/src/test/commands/deleteShapes.test.ts +2 -1
- package/src/test/commands/distributeShapes.test.tsx +11 -10
- package/src/test/commands/getSvgString.test.ts +2 -1
- package/src/test/commands/packShapes.test.ts +5 -4
- package/src/test/commands/resizeShape.test.ts +2 -1
- package/src/test/commands/rotateShapes.test.ts +7 -6
- package/src/test/commands/setCamera.test.ts +4 -3
- package/src/test/commands/setCurrentPage.test.ts +3 -2
- package/src/test/commands/stackShapes.test.ts +11 -10
- package/src/test/commands/stretch.test.tsx +13 -12
- package/src/test/createDeepLink.test.tsx +2 -1
- package/src/test/cropping.test.ts +3 -2
- package/src/test/custom-clipping.test.ts +436 -0
- package/src/test/drawing.test.ts +2 -1
- package/src/test/flipShapes.test.ts +4 -3
- package/src/test/frames.test.ts +25 -24
- package/src/test/getCulledShapes.test.tsx +3 -2
- package/src/test/groups.test.tsx +1 -1
- package/src/test/handleDeepLink.test.tsx +2 -1
- package/src/test/maxShapes.test.ts +3 -2
- package/src/test/modifiers.test.ts +5 -4
- package/src/test/navigation.test.ts +12 -11
- package/src/test/panning.test.ts +2 -1
- package/src/test/perf/perf.test.ts +2 -1
- package/src/test/registerDeepLinkListener.test.tsx +10 -9
- package/src/test/resizing.test.ts +39 -38
- package/src/test/select.test.tsx +4 -3
- package/src/test/selection-omnibus.test.ts +11 -10
- package/src/test/shapeutils.test.ts +4 -3
- package/src/test/translating.test.ts +9 -8
- package/tldraw.css +682 -596
- package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
- package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
- package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
- package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
- package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
- package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +0 -115
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
- package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -109
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/geo/GeoShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBaseBoxShapeUtil,\n\tBox,\n\tEMPTY_ARRAY,\n\tEditor,\n\tGroup2d,\n\tHTMLContainer,\n\tHandleSnapGeometry,\n\tRectangle2d,\n\tSVGContainer,\n\tSvgExportContext,\n\tTLGeoShape,\n\tTLGeoShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVec,\n\texhaustiveSwitchError,\n\tgeoShapeMigrations,\n\tgeoShapeProps,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tisEqual,\n\tlerp,\n\ttoRichText,\n\tuseValue,\n} from '@tldraw/editor'\nimport {\n\tisEmptyRichText,\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport {\n\tFONT_FAMILIES,\n\tLABEL_FONT_SIZES,\n\tLABEL_PADDING,\n\tSTROKE_SIZES,\n\tTEXT_PROPS,\n} from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { useIsReadyForEditing } from '../shared/useEditablePlainText'\nimport { GeoShapeBody } from './components/GeoShapeBody'\nimport { getGeoShapePath } from './getGeoShapePath'\n\nconst MIN_SIZE_WITH_LABEL = 17 * 3\n\n/** @public */\nexport class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {\n\tstatic override type = 'geo' as const\n\tstatic override props = geoShapeProps\n\tstatic override migrations = geoShapeMigrations\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLGeoShape['props'] {\n\t\treturn {\n\t\t\tw: 100,\n\t\t\th: 100,\n\t\t\tgeo: 'rectangle',\n\t\t\tdash: 'draw',\n\t\t\tgrowY: 0,\n\t\t\turl: '',\n\t\t\tscale: 1,\n\n\t\t\t// Text properties\n\t\t\tcolor: 'black',\n\t\t\tlabelColor: 'black',\n\t\t\tfill: 'none',\n\t\t\tsize: 'm',\n\t\t\tfont: 'draw',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\trichText: toRichText(''),\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLGeoShape) {\n\t\tconst w = Math.max(1, shape.props.w)\n\t\tconst h = Math.max(1, shape.props.h + shape.props.growY)\n\n\t\tconst path = getGeoShapePath(shape)\n\t\tconst unscaledlabelSize = getUnscaledLabelSize(this.editor, shape)\n\t\t// unscaled w and h\n\t\tconst unscaledW = w / shape.props.scale\n\t\tconst unscaledH = h / shape.props.scale\n\t\tconst unscaledminWidth = Math.min(100, unscaledW / 2)\n\t\tconst unscaledMinHeight = Math.min(\n\t\t\tLABEL_FONT_SIZES[shape.props.size] * TEXT_PROPS.lineHeight + LABEL_PADDING * 2,\n\t\t\tunscaledH / 2\n\t\t)\n\n\t\tconst unscaledLabelWidth = Math.min(\n\t\t\tunscaledW,\n\t\t\tMath.max(unscaledlabelSize.w, Math.min(unscaledminWidth, Math.max(1, unscaledW - 8)))\n\t\t)\n\t\tconst unscaledLabelHeight = Math.min(\n\t\t\tunscaledH,\n\t\t\tMath.max(unscaledlabelSize.h, Math.min(unscaledMinHeight, Math.max(1, unscaledH - 8)))\n\t\t)\n\n\t\t// todo: use centroid for label position\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tpath.toGeometry(),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx:\n\t\t\t\t\t\tshape.props.align === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.align === 'end'\n\t\t\t\t\t\t\t\t? (unscaledW - unscaledLabelWidth) * shape.props.scale\n\t\t\t\t\t\t\t\t: ((unscaledW - unscaledLabelWidth) / 2) * shape.props.scale,\n\t\t\t\t\ty:\n\t\t\t\t\t\tshape.props.verticalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.verticalAlign === 'end'\n\t\t\t\t\t\t\t\t? (unscaledH - unscaledLabelHeight) * shape.props.scale\n\t\t\t\t\t\t\t\t: ((unscaledH - unscaledLabelHeight) / 2) * shape.props.scale,\n\t\t\t\t\twidth: unscaledLabelWidth * shape.props.scale,\n\t\t\t\t\theight: unscaledLabelHeight * shape.props.scale,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\tisEmptyLabel: isEmptyRichText(shape.props.richText),\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLGeoShape): HandleSnapGeometry {\n\t\tconst geometry = this.getGeometry(shape)\n\t\t// we only want to snap handles to the outline of the shape - not to its label etc.\n\t\tconst outline = geometry.children[0]\n\t\tswitch (shape.props.geo) {\n\t\t\tcase 'arrow-down':\n\t\t\tcase 'arrow-left':\n\t\t\tcase 'arrow-right':\n\t\t\tcase 'arrow-up':\n\t\t\tcase 'check-box':\n\t\t\tcase 'diamond':\n\t\t\tcase 'hexagon':\n\t\t\tcase 'octagon':\n\t\t\tcase 'pentagon':\n\t\t\tcase 'rectangle':\n\t\t\tcase 'rhombus':\n\t\t\tcase 'rhombus-2':\n\t\t\tcase 'star':\n\t\t\tcase 'trapezoid':\n\t\t\tcase 'triangle':\n\t\t\tcase 'x-box':\n\t\t\t\t// poly-line type shapes hand snap points for each vertex & the center\n\t\t\t\treturn { outline: outline, points: [...outline.vertices, geometry.bounds.center] }\n\t\t\tcase 'cloud':\n\t\t\tcase 'ellipse':\n\t\t\tcase 'heart':\n\t\t\tcase 'oval':\n\t\t\t\t// blobby shapes only have a snap point in their center\n\t\t\t\treturn { outline: outline, points: [geometry.bounds.center] }\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(shape.props.geo)\n\t\t}\n\t}\n\n\toverride getText(shape: TLGeoShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride getFontFaces(shape: TLGeoShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\treturn EMPTY_ARRAY\n\t\t}\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\tcomponent(shape: TLGeoShape) {\n\t\tconst { id, type, props } = shape\n\t\tconst { fill, font, align, verticalAlign, size, richText } = props\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst { editor } = this\n\t\tconst isOnlySelected = useValue(\n\t\t\t'isGeoOnlySelected',\n\t\t\t() => shape.id === editor.getOnlySelectedShapeId(),\n\t\t\t[editor]\n\t\t)\n\t\tconst isReadyForEditing = useIsReadyForEditing(editor, shape.id)\n\t\tconst isEmpty = isEmptyRichText(shape.props.richText)\n\t\tconst showHtmlContainer = isReadyForEditing || !isEmpty\n\t\tconst isForceSolid = useValue('force solid', () => editor.getZoomLevel() < 0.2, [editor])\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer>\n\t\t\t\t\t<GeoShapeBody shape={shape} shouldScale={true} forceSolid={isForceSolid} />\n\t\t\t\t</SVGContainer>\n\t\t\t\t{showHtmlContainer && (\n\t\t\t\t\t<HTMLContainer\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\t\t\theight: shape.props.h + props.growY,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\t\tshapeId={id}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t\tfont={font}\n\t\t\t\t\t\t\tfontSize={LABEL_FONT_SIZES[size] * shape.props.scale}\n\t\t\t\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\t\t\t\tpadding={LABEL_PADDING * shape.props.scale}\n\t\t\t\t\t\t\tfill={fill}\n\t\t\t\t\t\t\talign={align}\n\t\t\t\t\t\t\tverticalAlign={verticalAlign}\n\t\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\t\tisSelected={isOnlySelected}\n\t\t\t\t\t\t\tlabelColor={theme[props.labelColor].solid}\n\t\t\t\t\t\t\twrap\n\t\t\t\t\t\t/>\n\t\t\t\t\t</HTMLContainer>\n\t\t\t\t)}\n\t\t\t\t{shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLGeoShape) {\n\t\tconst isZoomedOut = useValue('isZoomedOut', () => this.editor.getZoomLevel() < 0.25, [\n\t\t\tthis.editor,\n\t\t])\n\n\t\tconst { size, dash, scale } = shape.props\n\t\tconst strokeWidth = STROKE_SIZES[size]\n\n\t\tconst path = getGeoShapePath(shape)\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2 * scale,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t\tforceSolid: isZoomedOut,\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLGeoShape, ctx: SvgExportContext) {\n\t\tconst scale = shape.props.scale\n\t\t// We need to scale the shape to 1x for export\n\t\tconst newShape = {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tw: shape.props.w / scale,\n\t\t\t\th: (shape.props.h + shape.props.growY) / scale,\n\t\t\t\tgrowY: 0, // growY throws off the path calculations, so we set it to 0\n\t\t\t},\n\t\t}\n\t\tconst props = newShape.props\n\t\tctx.addExportDef(getFillDefForExport(props.fill))\n\n\t\tlet textEl\n\t\tif (!isEmptyRichText(props.richText)) {\n\t\t\tconst theme = getDefaultColorTheme(ctx)\n\t\t\tconst bounds = new Box(0, 0, props.w, (shape.props.h + shape.props.growY) / scale)\n\t\t\ttextEl = (\n\t\t\t\t<RichTextSVG\n\t\t\t\t\tfontSize={LABEL_FONT_SIZES[props.size]}\n\t\t\t\t\tfont={props.font}\n\t\t\t\t\talign={props.align}\n\t\t\t\t\tverticalAlign={props.verticalAlign}\n\t\t\t\t\trichText={props.richText}\n\t\t\t\t\tlabelColor={theme[props.labelColor].solid}\n\t\t\t\t\tbounds={bounds}\n\t\t\t\t\tpadding={LABEL_PADDING}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<GeoShapeBody shouldScale={false} shape={newShape} forceSolid={false} />\n\t\t\t\t{textEl}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(\n\t\tshape: TLGeoShape,\n\t\t{ handle, newPoint, scaleX, scaleY, initialShape }: TLResizeInfo<TLGeoShape>\n\t) {\n\t\tconst unscaledInitialW = initialShape.props.w / initialShape.props.scale\n\t\tconst unscaledInitialH = initialShape.props.h / initialShape.props.scale\n\t\tconst unscaledGrowY = initialShape.props.growY / initialShape.props.scale\n\t\t// use the w/h from props here instead of the initialBounds here,\n\t\t// since cloud shapes calculated bounds can differ from the props w/h.\n\t\tlet unscaledW = unscaledInitialW * scaleX\n\t\tlet unscaledH = (unscaledInitialH + unscaledGrowY) * scaleY\n\t\tlet overShrinkX = 0\n\t\tlet overShrinkY = 0\n\n\t\tconst min = MIN_SIZE_WITH_LABEL\n\n\t\tif (!isEmptyRichText(shape.props.richText)) {\n\t\t\tlet newW = Math.max(Math.abs(unscaledW), min)\n\t\t\tlet newH = Math.max(Math.abs(unscaledH), min)\n\n\t\t\tif (newW < min && newH === min) newW = min\n\t\t\tif (newW === min && newH < min) newH = min\n\n\t\t\tconst unscaledLabelSize = getUnscaledLabelSize(this.editor, {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tw: newW * shape.props.scale,\n\t\t\t\t\th: newH * shape.props.scale,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tconst nextW = Math.max(Math.abs(unscaledW), unscaledLabelSize.w) * Math.sign(unscaledW)\n\t\t\tconst nextH = Math.max(Math.abs(unscaledH), unscaledLabelSize.h) * Math.sign(unscaledH)\n\t\t\toverShrinkX = Math.abs(nextW) - Math.abs(unscaledW)\n\t\t\toverShrinkY = Math.abs(nextH) - Math.abs(unscaledH)\n\n\t\t\tunscaledW = nextW\n\t\t\tunscaledH = nextH\n\t\t}\n\n\t\tconst scaledW = unscaledW * shape.props.scale\n\t\tconst scaledH = unscaledH * shape.props.scale\n\n\t\tconst offset = new Vec(0, 0)\n\n\t\t// x offsets\n\n\t\tif (scaleX < 0) {\n\t\t\toffset.x += scaledW\n\t\t}\n\n\t\tif (handle === 'left' || handle === 'top_left' || handle === 'bottom_left') {\n\t\t\toffset.x += scaleX < 0 ? overShrinkX : -overShrinkX\n\t\t}\n\n\t\t// y offsets\n\n\t\tif (scaleY < 0) {\n\t\t\toffset.y += scaledH\n\t\t}\n\n\t\tif (handle === 'top' || handle === 'top_left' || handle === 'top_right') {\n\t\t\toffset.y += scaleY < 0 ? overShrinkY : -overShrinkY\n\t\t}\n\n\t\tconst { x, y } = offset.rot(shape.rotation).add(newPoint)\n\n\t\treturn {\n\t\t\tx,\n\t\t\ty,\n\t\t\tprops: {\n\t\t\t\tw: Math.max(Math.abs(scaledW), 1),\n\t\t\t\th: Math.max(Math.abs(scaledH), 1),\n\t\t\t\tgrowY: 0,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(shape: TLGeoShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\tif (shape.props.growY) {\n\t\t\t\t// No text / some growY, set growY to 0\n\t\t\t\treturn {\n\t\t\t\t\t...shape,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\t...shape.props,\n\t\t\t\t\t\tgrowY: 0,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// No text / no growY, nothing to change\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tconst unscaledPrevHeight = shape.props.h / shape.props.scale\n\t\tconst unscaledNextHeight = getUnscaledLabelSize(this.editor, shape).h\n\n\t\tlet growY: number | null = null\n\n\t\tif (unscaledNextHeight > unscaledPrevHeight) {\n\t\t\tgrowY = unscaledNextHeight - unscaledPrevHeight\n\t\t} else {\n\t\t\tif (shape.props.growY) {\n\t\t\t\tgrowY = 0\n\t\t\t}\n\t\t}\n\n\t\tif (growY !== null) {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\t// scale the growY\n\t\t\t\t\tgrowY: growY * shape.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onBeforeUpdate(prev: TLGeoShape, next: TLGeoShape) {\n\t\t// No change to text, font, or size, no need to update update\n\t\tif (\n\t\t\tisEqual(prev.props.richText, next.props.richText) &&\n\t\t\tprev.props.font === next.props.font &&\n\t\t\tprev.props.size === next.props.size\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\t// If we got rid of the text, cancel out any growY from the prev text\n\t\tconst wasEmpty = isEmptyRichText(prev.props.richText)\n\t\tconst isEmpty = isEmptyRichText(next.props.richText)\n\t\tif (!wasEmpty && isEmpty) {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\tgrowY: 0,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\t// Get the prev width and height in unscaled values\n\t\tconst unscaledPrevWidth = prev.props.w / prev.props.scale\n\t\tconst unscaledPrevHeight = prev.props.h / prev.props.scale\n\t\tconst unscaledPrevGrowY = prev.props.growY / prev.props.scale\n\n\t\t// Get the next width and height in unscaled values\n\t\tconst unscaledNextLabelSize = getUnscaledLabelSize(this.editor, next)\n\n\t\t// When entering the first character in a label (not pasting in multiple characters...)\n\t\tif (wasEmpty && !isEmpty && renderPlaintextFromRichText(this.editor, next.props.richText)) {\n\t\t\tlet unscaledW = Math.max(unscaledPrevWidth, unscaledNextLabelSize.w)\n\t\t\tlet unscaledH = Math.max(unscaledPrevHeight, unscaledNextLabelSize.h)\n\n\t\t\tconst min = MIN_SIZE_WITH_LABEL\n\n\t\t\t// If both the width and height were less than the minimum size, make the shape square\n\t\t\tif (unscaledPrevWidth < min && unscaledPrevHeight < min) {\n\t\t\t\tunscaledW = Math.max(unscaledW, min)\n\t\t\t\tunscaledH = Math.max(unscaledH, min)\n\t\t\t\tunscaledW = Math.max(unscaledW, unscaledH)\n\t\t\t\tunscaledH = Math.max(unscaledW, unscaledH)\n\t\t\t}\n\n\t\t\t// Don't set a growY\u2014at least, not until we've implemented a growX property\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tw: unscaledW * next.props.scale,\n\t\t\t\t\th: unscaledH * next.props.scale,\n\t\t\t\t\tgrowY: 0,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\tlet growY: number | null = null\n\n\t\tif (unscaledNextLabelSize.h > unscaledPrevHeight) {\n\t\t\tgrowY = unscaledNextLabelSize.h - unscaledPrevHeight\n\t\t} else {\n\t\t\tif (unscaledPrevGrowY) {\n\t\t\t\tgrowY = 0\n\t\t\t}\n\t\t}\n\n\t\tif (growY !== null) {\n\t\t\tconst unscaledNextWidth = next.props.w / next.props.scale\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tgrowY: growY * next.props.scale,\n\t\t\t\t\tw: Math.max(unscaledNextWidth, unscaledNextLabelSize.w) * next.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\tif (unscaledNextLabelSize.w > unscaledPrevWidth) {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tw: unscaledNextLabelSize.w * next.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\t// otherwise, no update needed\n\t}\n\n\toverride onDoubleClick(shape: TLGeoShape) {\n\t\t// Little easter egg: double-clicking a rectangle / checkbox while\n\t\t// holding alt will toggle between check-box and rectangle\n\t\tif (this.editor.inputs.altKey) {\n\t\t\tswitch (shape.props.geo) {\n\t\t\t\tcase 'rectangle': {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tgeo: 'check-box' as const,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase 'check-box': {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tgeo: 'rectangle' as const,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLGeoShape,\n\t\tendShape: TLGeoShape,\n\t\tt: number\n\t): TLGeoShapeProps {\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\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\n// imperfect but good enough, should be the width of the W in the font / size combo\nconst minWidths = {\n\ts: 12,\n\tm: 14,\n\tl: 16,\n\txl: 20,\n}\n\nconst extraPaddings = {\n\ts: 2,\n\tm: 3.5,\n\tl: 5,\n\txl: 10,\n}\n\nfunction getUnscaledLabelSize(editor: Editor, shape: TLGeoShape) {\n\tconst { richText, font, size, w } = shape.props\n\n\tif (!richText || isEmptyRichText(richText)) {\n\t\treturn { w: 0, h: 0 }\n\t}\n\n\t// way too expensive to be recomputing on every update\n\tconst minWidth = minWidths[size]\n\n\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\tconst textSize = editor.textMeasure.measureHtml(html, {\n\t\t...TEXT_PROPS,\n\t\tfontFamily: FONT_FAMILIES[font],\n\t\tfontSize: LABEL_FONT_SIZES[size],\n\t\tminWidth: minWidth,\n\t\tmaxWidth: Math.max(\n\t\t\t// Guard because a DOM nodes can't be less 0\n\t\t\t0,\n\t\t\t// A 'w' width that we're setting as the min-width\n\t\t\tMath.ceil(minWidth + extraPaddings[size]),\n\t\t\t// The actual text size\n\t\t\tMath.ceil(w / shape.props.scale - LABEL_PADDING * 2)\n\t\t),\n\t})\n\n\treturn {\n\t\tw: textSize.w + LABEL_PADDING * 2,\n\t\th: textSize.h + LABEL_PADDING * 2,\n\t}\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBaseBoxShapeUtil,\n\tBox,\n\tEMPTY_ARRAY,\n\tEditor,\n\tGroup2d,\n\tHTMLContainer,\n\tHandleSnapGeometry,\n\tRectangle2d,\n\tSVGContainer,\n\tSvgExportContext,\n\tTLGeoShape,\n\tTLGeoShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVec,\n\texhaustiveSwitchError,\n\tgeoShapeMigrations,\n\tgeoShapeProps,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tisEqual,\n\tlerp,\n\ttoRichText,\n\tuseValue,\n} from '@tldraw/editor'\nimport {\n\tisEmptyRichText,\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport {\n\tFONT_FAMILIES,\n\tLABEL_FONT_SIZES,\n\tLABEL_PADDING,\n\tSTROKE_SIZES,\n\tTEXT_PROPS,\n} from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { useIsReadyForEditing } from '../shared/useEditablePlainText'\nimport { GeoShapeBody } from './components/GeoShapeBody'\nimport { getGeoShapePath } from './getGeoShapePath'\n\nconst MIN_SIZE_WITH_LABEL = 17 * 3\n\n/** @public */\nexport class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {\n\tstatic override type = 'geo' as const\n\tstatic override props = geoShapeProps\n\tstatic override migrations = geoShapeMigrations\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLGeoShape['props'] {\n\t\treturn {\n\t\t\tw: 100,\n\t\t\th: 100,\n\t\t\tgeo: 'rectangle',\n\t\t\tdash: 'draw',\n\t\t\tgrowY: 0,\n\t\t\turl: '',\n\t\t\tscale: 1,\n\n\t\t\t// Text properties\n\t\t\tcolor: 'black',\n\t\t\tlabelColor: 'black',\n\t\t\tfill: 'none',\n\t\t\tsize: 'm',\n\t\t\tfont: 'draw',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\trichText: toRichText(''),\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLGeoShape) {\n\t\tconst w = Math.max(1, shape.props.w)\n\t\tconst h = Math.max(1, shape.props.h + shape.props.growY)\n\n\t\tconst path = getGeoShapePath(shape)\n\t\tconst unscaledlabelSize = getUnscaledLabelSize(this.editor, shape)\n\t\t// unscaled w and h\n\t\tconst unscaledW = w / shape.props.scale\n\t\tconst unscaledH = h / shape.props.scale\n\t\tconst unscaledminWidth = Math.min(100, unscaledW / 2)\n\t\tconst unscaledMinHeight = Math.min(\n\t\t\tLABEL_FONT_SIZES[shape.props.size] * TEXT_PROPS.lineHeight + LABEL_PADDING * 2,\n\t\t\tunscaledH / 2\n\t\t)\n\n\t\tconst unscaledLabelWidth = Math.min(\n\t\t\tunscaledW,\n\t\t\tMath.max(unscaledlabelSize.w, Math.min(unscaledminWidth, Math.max(1, unscaledW - 8)))\n\t\t)\n\t\tconst unscaledLabelHeight = Math.min(\n\t\t\tunscaledH,\n\t\t\tMath.max(unscaledlabelSize.h, Math.min(unscaledMinHeight, Math.max(1, unscaledH - 8)))\n\t\t)\n\n\t\t// todo: use centroid for label position\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tpath.toGeometry(),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx:\n\t\t\t\t\t\tshape.props.align === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.align === 'end'\n\t\t\t\t\t\t\t\t? (unscaledW - unscaledLabelWidth) * shape.props.scale\n\t\t\t\t\t\t\t\t: ((unscaledW - unscaledLabelWidth) / 2) * shape.props.scale,\n\t\t\t\t\ty:\n\t\t\t\t\t\tshape.props.verticalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.verticalAlign === 'end'\n\t\t\t\t\t\t\t\t? (unscaledH - unscaledLabelHeight) * shape.props.scale\n\t\t\t\t\t\t\t\t: ((unscaledH - unscaledLabelHeight) / 2) * shape.props.scale,\n\t\t\t\t\twidth: unscaledLabelWidth * shape.props.scale,\n\t\t\t\t\theight: unscaledLabelHeight * shape.props.scale,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\tisEmptyLabel: isEmptyRichText(shape.props.richText),\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLGeoShape): HandleSnapGeometry {\n\t\tconst geometry = this.getGeometry(shape)\n\t\t// we only want to snap handles to the outline of the shape - not to its label etc.\n\t\tconst outline = geometry.children[0]\n\t\tswitch (shape.props.geo) {\n\t\t\tcase 'arrow-down':\n\t\t\tcase 'arrow-left':\n\t\t\tcase 'arrow-right':\n\t\t\tcase 'arrow-up':\n\t\t\tcase 'check-box':\n\t\t\tcase 'diamond':\n\t\t\tcase 'hexagon':\n\t\t\tcase 'octagon':\n\t\t\tcase 'pentagon':\n\t\t\tcase 'rectangle':\n\t\t\tcase 'rhombus':\n\t\t\tcase 'rhombus-2':\n\t\t\tcase 'star':\n\t\t\tcase 'trapezoid':\n\t\t\tcase 'triangle':\n\t\t\tcase 'x-box':\n\t\t\t\t// poly-line type shapes hand snap points for each vertex & the center\n\t\t\t\treturn { outline: outline, points: [...outline.vertices, geometry.bounds.center] }\n\t\t\tcase 'cloud':\n\t\t\tcase 'ellipse':\n\t\t\tcase 'heart':\n\t\t\tcase 'oval':\n\t\t\t\t// blobby shapes only have a snap point in their center\n\t\t\t\treturn { outline: outline, points: [geometry.bounds.center] }\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(shape.props.geo)\n\t\t}\n\t}\n\n\toverride getText(shape: TLGeoShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride getFontFaces(shape: TLGeoShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\treturn EMPTY_ARRAY\n\t\t}\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\tcomponent(shape: TLGeoShape) {\n\t\tconst { id, type, props } = shape\n\t\tconst { fill, font, align, verticalAlign, size, richText } = props\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst { editor } = this\n\t\tconst isOnlySelected = useValue(\n\t\t\t'isGeoOnlySelected',\n\t\t\t() => shape.id === editor.getOnlySelectedShapeId(),\n\t\t\t[editor]\n\t\t)\n\t\tconst isReadyForEditing = useIsReadyForEditing(editor, shape.id)\n\t\tconst isEmpty = isEmptyRichText(shape.props.richText)\n\t\tconst showHtmlContainer = isReadyForEditing || !isEmpty\n\t\tconst isForceSolid = useValue('force solid', () => editor.getZoomLevel() < 0.2, [editor])\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer>\n\t\t\t\t\t<GeoShapeBody shape={shape} shouldScale={true} forceSolid={isForceSolid} />\n\t\t\t\t</SVGContainer>\n\t\t\t\t{showHtmlContainer && (\n\t\t\t\t\t<HTMLContainer\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\t\t\theight: shape.props.h + props.growY,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\t\tshapeId={id}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t\tfont={font}\n\t\t\t\t\t\t\tfontSize={LABEL_FONT_SIZES[size] * shape.props.scale}\n\t\t\t\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\t\t\t\tpadding={LABEL_PADDING * shape.props.scale}\n\t\t\t\t\t\t\tfill={fill}\n\t\t\t\t\t\t\talign={align}\n\t\t\t\t\t\t\tverticalAlign={verticalAlign}\n\t\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\t\tisSelected={isOnlySelected}\n\t\t\t\t\t\t\tlabelColor={getColorValue(theme, props.labelColor, 'solid')}\n\t\t\t\t\t\t\twrap\n\t\t\t\t\t\t/>\n\t\t\t\t\t</HTMLContainer>\n\t\t\t\t)}\n\t\t\t\t{shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLGeoShape) {\n\t\tconst isZoomedOut = useValue('isZoomedOut', () => this.editor.getZoomLevel() < 0.25, [\n\t\t\tthis.editor,\n\t\t])\n\n\t\tconst { size, dash, scale } = shape.props\n\t\tconst strokeWidth = STROKE_SIZES[size]\n\n\t\tconst path = getGeoShapePath(shape)\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2 * scale,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t\tforceSolid: isZoomedOut,\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLGeoShape, ctx: SvgExportContext) {\n\t\tconst scale = shape.props.scale\n\t\t// We need to scale the shape to 1x for export\n\t\tconst newShape = {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tw: shape.props.w / scale,\n\t\t\t\th: (shape.props.h + shape.props.growY) / scale,\n\t\t\t\tgrowY: 0, // growY throws off the path calculations, so we set it to 0\n\t\t\t},\n\t\t}\n\t\tconst props = newShape.props\n\t\tctx.addExportDef(getFillDefForExport(props.fill))\n\n\t\tlet textEl\n\t\tif (!isEmptyRichText(props.richText)) {\n\t\t\tconst theme = getDefaultColorTheme(ctx)\n\t\t\tconst bounds = new Box(0, 0, props.w, (shape.props.h + shape.props.growY) / scale)\n\t\t\ttextEl = (\n\t\t\t\t<RichTextSVG\n\t\t\t\t\tfontSize={LABEL_FONT_SIZES[props.size]}\n\t\t\t\t\tfont={props.font}\n\t\t\t\t\talign={props.align}\n\t\t\t\t\tverticalAlign={props.verticalAlign}\n\t\t\t\t\trichText={props.richText}\n\t\t\t\t\tlabelColor={getColorValue(theme, props.labelColor, 'solid')}\n\t\t\t\t\tbounds={bounds}\n\t\t\t\t\tpadding={LABEL_PADDING}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<GeoShapeBody shouldScale={false} shape={newShape} forceSolid={false} />\n\t\t\t\t{textEl}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(\n\t\tshape: TLGeoShape,\n\t\t{ handle, newPoint, scaleX, scaleY, initialShape }: TLResizeInfo<TLGeoShape>\n\t) {\n\t\tconst unscaledInitialW = initialShape.props.w / initialShape.props.scale\n\t\tconst unscaledInitialH = initialShape.props.h / initialShape.props.scale\n\t\tconst unscaledGrowY = initialShape.props.growY / initialShape.props.scale\n\t\t// use the w/h from props here instead of the initialBounds here,\n\t\t// since cloud shapes calculated bounds can differ from the props w/h.\n\t\tlet unscaledW = unscaledInitialW * scaleX\n\t\tlet unscaledH = (unscaledInitialH + unscaledGrowY) * scaleY\n\t\tlet overShrinkX = 0\n\t\tlet overShrinkY = 0\n\n\t\tconst min = MIN_SIZE_WITH_LABEL\n\n\t\tif (!isEmptyRichText(shape.props.richText)) {\n\t\t\tlet newW = Math.max(Math.abs(unscaledW), min)\n\t\t\tlet newH = Math.max(Math.abs(unscaledH), min)\n\n\t\t\tif (newW < min && newH === min) newW = min\n\t\t\tif (newW === min && newH < min) newH = min\n\n\t\t\tconst unscaledLabelSize = getUnscaledLabelSize(this.editor, {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tw: newW * shape.props.scale,\n\t\t\t\t\th: newH * shape.props.scale,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tconst nextW = Math.max(Math.abs(unscaledW), unscaledLabelSize.w) * Math.sign(unscaledW)\n\t\t\tconst nextH = Math.max(Math.abs(unscaledH), unscaledLabelSize.h) * Math.sign(unscaledH)\n\t\t\toverShrinkX = Math.abs(nextW) - Math.abs(unscaledW)\n\t\t\toverShrinkY = Math.abs(nextH) - Math.abs(unscaledH)\n\n\t\t\tunscaledW = nextW\n\t\t\tunscaledH = nextH\n\t\t}\n\n\t\tconst scaledW = unscaledW * shape.props.scale\n\t\tconst scaledH = unscaledH * shape.props.scale\n\n\t\tconst offset = new Vec(0, 0)\n\n\t\t// x offsets\n\n\t\tif (scaleX < 0) {\n\t\t\toffset.x += scaledW\n\t\t}\n\n\t\tif (handle === 'left' || handle === 'top_left' || handle === 'bottom_left') {\n\t\t\toffset.x += scaleX < 0 ? overShrinkX : -overShrinkX\n\t\t}\n\n\t\t// y offsets\n\n\t\tif (scaleY < 0) {\n\t\t\toffset.y += scaledH\n\t\t}\n\n\t\tif (handle === 'top' || handle === 'top_left' || handle === 'top_right') {\n\t\t\toffset.y += scaleY < 0 ? overShrinkY : -overShrinkY\n\t\t}\n\n\t\tconst { x, y } = offset.rot(shape.rotation).add(newPoint)\n\n\t\treturn {\n\t\t\tx,\n\t\t\ty,\n\t\t\tprops: {\n\t\t\t\tw: Math.max(Math.abs(scaledW), 1),\n\t\t\t\th: Math.max(Math.abs(scaledH), 1),\n\t\t\t\tgrowY: 0,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(shape: TLGeoShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\tif (shape.props.growY) {\n\t\t\t\t// No text / some growY, set growY to 0\n\t\t\t\treturn {\n\t\t\t\t\t...shape,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\t...shape.props,\n\t\t\t\t\t\tgrowY: 0,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// No text / no growY, nothing to change\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tconst unscaledPrevHeight = shape.props.h / shape.props.scale\n\t\tconst unscaledNextHeight = getUnscaledLabelSize(this.editor, shape).h\n\n\t\tlet growY: number | null = null\n\n\t\tif (unscaledNextHeight > unscaledPrevHeight) {\n\t\t\tgrowY = unscaledNextHeight - unscaledPrevHeight\n\t\t} else {\n\t\t\tif (shape.props.growY) {\n\t\t\t\tgrowY = 0\n\t\t\t}\n\t\t}\n\n\t\tif (growY !== null) {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\t// scale the growY\n\t\t\t\t\tgrowY: growY * shape.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onBeforeUpdate(prev: TLGeoShape, next: TLGeoShape) {\n\t\t// No change to text, font, or size, no need to update update\n\t\tif (\n\t\t\tisEqual(prev.props.richText, next.props.richText) &&\n\t\t\tprev.props.font === next.props.font &&\n\t\t\tprev.props.size === next.props.size\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\t// If we got rid of the text, cancel out any growY from the prev text\n\t\tconst wasEmpty = isEmptyRichText(prev.props.richText)\n\t\tconst isEmpty = isEmptyRichText(next.props.richText)\n\t\tif (!wasEmpty && isEmpty) {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\tgrowY: 0,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\t// Get the prev width and height in unscaled values\n\t\tconst unscaledPrevWidth = prev.props.w / prev.props.scale\n\t\tconst unscaledPrevHeight = prev.props.h / prev.props.scale\n\t\tconst unscaledPrevGrowY = prev.props.growY / prev.props.scale\n\n\t\t// Get the next width and height in unscaled values\n\t\tconst unscaledNextLabelSize = getUnscaledLabelSize(this.editor, next)\n\n\t\t// When entering the first character in a label (not pasting in multiple characters...)\n\t\tif (wasEmpty && !isEmpty && renderPlaintextFromRichText(this.editor, next.props.richText)) {\n\t\t\tlet unscaledW = Math.max(unscaledPrevWidth, unscaledNextLabelSize.w)\n\t\t\tlet unscaledH = Math.max(unscaledPrevHeight, unscaledNextLabelSize.h)\n\n\t\t\tconst min = MIN_SIZE_WITH_LABEL\n\n\t\t\t// If both the width and height were less than the minimum size, make the shape square\n\t\t\tif (unscaledPrevWidth < min && unscaledPrevHeight < min) {\n\t\t\t\tunscaledW = Math.max(unscaledW, min)\n\t\t\t\tunscaledH = Math.max(unscaledH, min)\n\t\t\t\tunscaledW = Math.max(unscaledW, unscaledH)\n\t\t\t\tunscaledH = Math.max(unscaledW, unscaledH)\n\t\t\t}\n\n\t\t\t// Don't set a growY\u2014at least, not until we've implemented a growX property\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tw: unscaledW * next.props.scale,\n\t\t\t\t\th: unscaledH * next.props.scale,\n\t\t\t\t\tgrowY: 0,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\tlet growY: number | null = null\n\n\t\tif (unscaledNextLabelSize.h > unscaledPrevHeight) {\n\t\t\tgrowY = unscaledNextLabelSize.h - unscaledPrevHeight\n\t\t} else {\n\t\t\tif (unscaledPrevGrowY) {\n\t\t\t\tgrowY = 0\n\t\t\t}\n\t\t}\n\n\t\tif (growY !== null) {\n\t\t\tconst unscaledNextWidth = next.props.w / next.props.scale\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tgrowY: growY * next.props.scale,\n\t\t\t\t\tw: Math.max(unscaledNextWidth, unscaledNextLabelSize.w) * next.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\tif (unscaledNextLabelSize.w > unscaledPrevWidth) {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tw: unscaledNextLabelSize.w * next.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\t// otherwise, no update needed\n\t}\n\n\toverride onDoubleClick(shape: TLGeoShape) {\n\t\t// Little easter egg: double-clicking a rectangle / checkbox while\n\t\t// holding alt will toggle between check-box and rectangle\n\t\tif (this.editor.inputs.altKey) {\n\t\t\tswitch (shape.props.geo) {\n\t\t\t\tcase 'rectangle': {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tgeo: 'check-box' as const,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase 'check-box': {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tgeo: 'rectangle' as const,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLGeoShape,\n\t\tendShape: TLGeoShape,\n\t\tt: number\n\t): TLGeoShapeProps {\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\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\n// imperfect but good enough, should be the width of the W in the font / size combo\nconst minWidths = {\n\ts: 12,\n\tm: 14,\n\tl: 16,\n\txl: 20,\n}\n\nconst extraPaddings = {\n\ts: 2,\n\tm: 3.5,\n\tl: 5,\n\txl: 10,\n}\n\nfunction getUnscaledLabelSize(editor: Editor, shape: TLGeoShape) {\n\tconst { richText, font, size, w } = shape.props\n\n\tif (!richText || isEmptyRichText(richText)) {\n\t\treturn { w: 0, h: 0 }\n\t}\n\n\t// way too expensive to be recomputing on every update\n\tconst minWidth = minWidths[size]\n\n\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\tconst textSize = editor.textMeasure.measureHtml(html, {\n\t\t...TEXT_PROPS,\n\t\tfontFamily: FONT_FAMILIES[font],\n\t\tfontSize: LABEL_FONT_SIZES[size],\n\t\tminWidth: minWidth,\n\t\tmaxWidth: Math.max(\n\t\t\t// Guard because a DOM nodes can't be less 0\n\t\t\t0,\n\t\t\t// A 'w' width that we're setting as the min-width\n\t\t\tMath.ceil(minWidth + extraPaddings[size]),\n\t\t\t// The actual text size\n\t\t\tMath.ceil(w / shape.props.scale - LABEL_PADDING * 2)\n\t\t),\n\t})\n\n\treturn {\n\t\tw: textSize.w + LABEL_PADDING * 2,\n\t\th: textSize.h + LABEL_PADDING * 2,\n\t}\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -22,6 +22,7 @@ __export(GeoShapeBody_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(GeoShapeBody_exports);
|
|
24
24
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
25
|
+
var import_editor = require("@tldraw/editor");
|
|
25
26
|
var import_ShapeFill = require("../../shared/ShapeFill");
|
|
26
27
|
var import_default_shape_constants = require("../../shared/default-shape-constants");
|
|
27
28
|
var import_useDefaultColorTheme = require("../../shared/useDefaultColorTheme");
|
|
@@ -45,7 +46,7 @@ function GeoShapeBody({
|
|
|
45
46
|
strokeWidth,
|
|
46
47
|
forceSolid,
|
|
47
48
|
randomSeed: shape.id,
|
|
48
|
-
props: { fill: "none", stroke: theme
|
|
49
|
+
props: { fill: "none", stroke: (0, import_editor.getColorValue)(theme, color, "solid") }
|
|
49
50
|
})
|
|
50
51
|
] });
|
|
51
52
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/shapes/geo/components/GeoShapeBody.tsx"],
|
|
4
|
-
"sourcesContent": ["import { TLGeoShape } from '@tldraw/editor'\nimport { ShapeFill } from '../../shared/ShapeFill'\nimport { STROKE_SIZES } from '../../shared/default-shape-constants'\nimport { useDefaultColorTheme } from '../../shared/useDefaultColorTheme'\nimport { getGeoShapePath } from '../getGeoShapePath'\n\nexport function GeoShapeBody({\n\tshape,\n\tshouldScale,\n\tforceSolid,\n}: {\n\tshape: TLGeoShape\n\tshouldScale: boolean\n\tforceSolid: boolean\n}) {\n\tconst scaleToUse = shouldScale ? shape.props.scale : 1\n\tconst theme = useDefaultColorTheme()\n\tconst { props } = shape\n\tconst { color, fill, dash, size } = props\n\tconst strokeWidth = STROKE_SIZES[size] * scaleToUse\n\n\tconst path = getGeoShapePath(shape)\n\tconst fillPath =\n\t\tdash === 'draw' && !forceSolid\n\t\t\t? path.toDrawD({ strokeWidth, randomSeed: shape.id, passes: 1, offset: 0, onlyFilled: true })\n\t\t\t: path.toD({ onlyFilled: true })\n\n\treturn (\n\t\t<>\n\t\t\t<ShapeFill theme={theme} d={fillPath} color={color} fill={fill} scale={scaleToUse} />\n\t\t\t{path.toSvg({\n\t\t\t\tstyle: dash,\n\t\t\t\tstrokeWidth,\n\t\t\t\tforceSolid,\n\t\t\t\trandomSeed: shape.id,\n\t\t\t\tprops: { fill: 'none', stroke: theme
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BE;
|
|
4
|
+
"sourcesContent": ["import { getColorValue, TLGeoShape } from '@tldraw/editor'\nimport { ShapeFill } from '../../shared/ShapeFill'\nimport { STROKE_SIZES } from '../../shared/default-shape-constants'\nimport { useDefaultColorTheme } from '../../shared/useDefaultColorTheme'\nimport { getGeoShapePath } from '../getGeoShapePath'\n\nexport function GeoShapeBody({\n\tshape,\n\tshouldScale,\n\tforceSolid,\n}: {\n\tshape: TLGeoShape\n\tshouldScale: boolean\n\tforceSolid: boolean\n}) {\n\tconst scaleToUse = shouldScale ? shape.props.scale : 1\n\tconst theme = useDefaultColorTheme()\n\tconst { props } = shape\n\tconst { color, fill, dash, size } = props\n\tconst strokeWidth = STROKE_SIZES[size] * scaleToUse\n\n\tconst path = getGeoShapePath(shape)\n\tconst fillPath =\n\t\tdash === 'draw' && !forceSolid\n\t\t\t? path.toDrawD({ strokeWidth, randomSeed: shape.id, passes: 1, offset: 0, onlyFilled: true })\n\t\t\t: path.toD({ onlyFilled: true })\n\n\treturn (\n\t\t<>\n\t\t\t<ShapeFill theme={theme} d={fillPath} color={color} fill={fill} scale={scaleToUse} />\n\t\t\t{path.toSvg({\n\t\t\t\tstyle: dash,\n\t\t\t\tstrokeWidth,\n\t\t\t\tforceSolid,\n\t\t\t\trandomSeed: shape.id,\n\t\t\t\tprops: { fill: 'none', stroke: getColorValue(theme, color, 'solid') },\n\t\t\t})}\n\t\t</>\n\t)\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BE;AA5BF,oBAA0C;AAC1C,uBAA0B;AAC1B,qCAA6B;AAC7B,kCAAqC;AACrC,6BAAgC;AAEzB,SAAS,aAAa;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACD,GAIG;AACF,QAAM,aAAa,cAAc,MAAM,MAAM,QAAQ;AACrD,QAAM,YAAQ,kDAAqB;AACnC,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,EAAE,OAAO,MAAM,MAAM,KAAK,IAAI;AACpC,QAAM,cAAc,4CAAa,IAAI,IAAI;AAEzC,QAAM,WAAO,wCAAgB,KAAK;AAClC,QAAM,WACL,SAAS,UAAU,CAAC,aACjB,KAAK,QAAQ,EAAE,aAAa,YAAY,MAAM,IAAI,QAAQ,GAAG,QAAQ,GAAG,YAAY,KAAK,CAAC,IAC1F,KAAK,IAAI,EAAE,YAAY,KAAK,CAAC;AAEjC,SACC,4EACC;AAAA,gDAAC,8BAAU,OAAc,GAAG,UAAU,OAAc,MAAY,OAAO,YAAY;AAAA,IAClF,KAAK,MAAM;AAAA,MACX,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,OAAO,EAAE,MAAM,QAAQ,YAAQ,6BAAc,OAAO,OAAO,OAAO,EAAE;AAAA,IACrE,CAAC;AAAA,KACF;AAEF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -222,7 +222,11 @@ function HighlightRenderer({
|
|
|
222
222
|
const strokePoints = (0, import_getStrokePoints.getStrokePoints)(allPointsFromSegments, options);
|
|
223
223
|
const solidStrokePath = strokePoints.length > 1 ? (0, import_svg.getSvgPathFromStrokePoints)(strokePoints, false) : getShapeDot(shape.props.segments[0].points[0]);
|
|
224
224
|
const colorSpace = (0, import_useColorSpace.useColorSpace)();
|
|
225
|
-
const color =
|
|
225
|
+
const color = (0, import_editor.getColorValue)(
|
|
226
|
+
theme,
|
|
227
|
+
shape.props.color,
|
|
228
|
+
colorSpace === "p3" ? "highlightP3" : "highlightSrgb"
|
|
229
|
+
);
|
|
226
230
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
227
231
|
"path",
|
|
228
232
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/highlight/HighlightShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tCircle2d,\n\tEditor,\n\tPolygon2d,\n\tSVGContainer,\n\tShapeUtil,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLHighlightShapeProps,\n\tTLResizeInfo,\n\tVecLike,\n\thighlightShapeMigrations,\n\thighlightShapeProps,\n\tlast,\n\tlerp,\n\trng,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { getHighlightFreehandSettings, getPointsFromSegments } from '../draw/getPath'\nimport { FONT_SIZES } from '../shared/default-shape-constants'\nimport { getStrokeOutlinePoints } from '../shared/freehand/getStrokeOutlinePoints'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { setStrokePointRadii } from '../shared/freehand/setStrokePointRadii'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useColorSpace } from '../shared/useColorSpace'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\n/** @public */\nexport interface HighlightShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n\treadonly underlayOpacity: number\n\treadonly overlayOpacity: number\n}\n\n/** @public */\nexport class HighlightShapeUtil extends ShapeUtil<TLHighlightShape> {\n\tstatic override type = 'highlight' as const\n\tstatic override props = highlightShapeProps\n\tstatic override migrations = highlightShapeMigrations\n\n\toverride options: HighlightShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tunderlayOpacity: 0.82,\n\t\toverlayOpacity: 0.35,\n\t}\n\n\toverride hideResizeHandles(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLHighlightShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tif (getIsDot(shape)) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -strokeWidth / 2,\n\t\t\t\ty: -strokeWidth / 2,\n\t\t\t\tradius: strokeWidth / 2,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, true)\n\t\tconst opts = getHighlightFreehandSettings({ strokeWidth: sw, showAsComplete: true })\n\t\tsetStrokePointRadii(strokePoints, opts)\n\n\t\treturn new Polygon2d({\n\t\t\tpoints: getStrokeOutlinePoints(strokePoints, opts),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tcomponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride backgroundComponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid)\n\t\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\t\tlet strokePath\n\t\tif (strokePoints.length < 2) {\n\t\t\tstrokePath = getIndicatorDot(allPointsFromSegments[0], sw)\n\t\t} else {\n\t\t\tstrokePath = getSvgPathFromStrokePoints(strokePoints, false)\n\t\t}\n\n\t\treturn <path d={strokePath} />\n\t}\n\n\toverride toSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride toBackgroundSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride onResize(shape: TLHighlightShape, info: TLResizeInfo<TLHighlightShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst newSegments: TLDrawShapeSegment[] = []\n\n\t\tfor (const segment of shape.props.segments) {\n\t\t\tnewSegments.push({\n\t\t\t\t...segment,\n\t\t\t\tpoints: segment.points.map(({ x, y, z }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: scaleX * x,\n\t\t\t\t\t\ty: scaleY * y,\n\t\t\t\t\t\tz,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tsegments: newSegments,\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLHighlightShape,\n\t\tendShape: TLHighlightShape,\n\t\tt: number\n\t): TLHighlightShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\t...endShape.props,\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getShapeDot(point: VecLike) {\n\tconst r = 0.1\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIndicatorDot(point: VecLike, sw: number) {\n\tconst r = sw / 2\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getHighlightStrokePoints(\n\tshape: TLHighlightShape,\n\tstrokeWidth: number,\n\tforceSolid: boolean\n) {\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (strokeWidth / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete,\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\treturn { strokePoints, sw }\n}\n\nfunction getStrokeWidth(shape: TLHighlightShape) {\n\treturn FONT_SIZES[shape.props.size] * 1.12 * shape.props.scale\n}\n\nfunction getIsDot(shape: TLHighlightShape) {\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2\n}\n\nfunction HighlightRenderer({\n\tstrokeWidth,\n\tforceSolid,\n\tshape,\n\topacity,\n}: {\n\tstrokeWidth: number\n\tforceSolid: boolean\n\tshape: TLHighlightShape\n\topacity: number\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete: shape.props.isComplete || last(shape.props.segments)?.type === 'straight',\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\tconst solidStrokePath =\n\t\tstrokePoints.length > 1\n\t\t\t? getSvgPathFromStrokePoints(strokePoints, false)\n\t\t\t: getShapeDot(shape.props.segments[0].points[0])\n\n\tconst colorSpace = useColorSpace()\n\tconst color =
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tCircle2d,\n\tEditor,\n\tPolygon2d,\n\tSVGContainer,\n\tShapeUtil,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLHighlightShapeProps,\n\tTLResizeInfo,\n\tVecLike,\n\tgetColorValue,\n\thighlightShapeMigrations,\n\thighlightShapeProps,\n\tlast,\n\tlerp,\n\trng,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { getHighlightFreehandSettings, getPointsFromSegments } from '../draw/getPath'\nimport { FONT_SIZES } from '../shared/default-shape-constants'\nimport { getStrokeOutlinePoints } from '../shared/freehand/getStrokeOutlinePoints'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { setStrokePointRadii } from '../shared/freehand/setStrokePointRadii'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useColorSpace } from '../shared/useColorSpace'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\n/** @public */\nexport interface HighlightShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n\treadonly underlayOpacity: number\n\treadonly overlayOpacity: number\n}\n\n/** @public */\nexport class HighlightShapeUtil extends ShapeUtil<TLHighlightShape> {\n\tstatic override type = 'highlight' as const\n\tstatic override props = highlightShapeProps\n\tstatic override migrations = highlightShapeMigrations\n\n\toverride options: HighlightShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tunderlayOpacity: 0.82,\n\t\toverlayOpacity: 0.35,\n\t}\n\n\toverride hideResizeHandles(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLHighlightShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tif (getIsDot(shape)) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -strokeWidth / 2,\n\t\t\t\ty: -strokeWidth / 2,\n\t\t\t\tradius: strokeWidth / 2,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, true)\n\t\tconst opts = getHighlightFreehandSettings({ strokeWidth: sw, showAsComplete: true })\n\t\tsetStrokePointRadii(strokePoints, opts)\n\n\t\treturn new Polygon2d({\n\t\t\tpoints: getStrokeOutlinePoints(strokePoints, opts),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tcomponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride backgroundComponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid)\n\t\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\t\tlet strokePath\n\t\tif (strokePoints.length < 2) {\n\t\t\tstrokePath = getIndicatorDot(allPointsFromSegments[0], sw)\n\t\t} else {\n\t\t\tstrokePath = getSvgPathFromStrokePoints(strokePoints, false)\n\t\t}\n\n\t\treturn <path d={strokePath} />\n\t}\n\n\toverride toSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride toBackgroundSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride onResize(shape: TLHighlightShape, info: TLResizeInfo<TLHighlightShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst newSegments: TLDrawShapeSegment[] = []\n\n\t\tfor (const segment of shape.props.segments) {\n\t\t\tnewSegments.push({\n\t\t\t\t...segment,\n\t\t\t\tpoints: segment.points.map(({ x, y, z }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: scaleX * x,\n\t\t\t\t\t\ty: scaleY * y,\n\t\t\t\t\t\tz,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tsegments: newSegments,\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLHighlightShape,\n\t\tendShape: TLHighlightShape,\n\t\tt: number\n\t): TLHighlightShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\t...endShape.props,\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getShapeDot(point: VecLike) {\n\tconst r = 0.1\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIndicatorDot(point: VecLike, sw: number) {\n\tconst r = sw / 2\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getHighlightStrokePoints(\n\tshape: TLHighlightShape,\n\tstrokeWidth: number,\n\tforceSolid: boolean\n) {\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (strokeWidth / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete,\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\treturn { strokePoints, sw }\n}\n\nfunction getStrokeWidth(shape: TLHighlightShape) {\n\treturn FONT_SIZES[shape.props.size] * 1.12 * shape.props.scale\n}\n\nfunction getIsDot(shape: TLHighlightShape) {\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2\n}\n\nfunction HighlightRenderer({\n\tstrokeWidth,\n\tforceSolid,\n\tshape,\n\topacity,\n}: {\n\tstrokeWidth: number\n\tforceSolid: boolean\n\tshape: TLHighlightShape\n\topacity: number\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete: shape.props.isComplete || last(shape.props.segments)?.type === 'straight',\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\tconst solidStrokePath =\n\t\tstrokePoints.length > 1\n\t\t\t? getSvgPathFromStrokePoints(strokePoints, false)\n\t\t\t: getShapeDot(shape.props.segments[0].points[0])\n\n\tconst colorSpace = useColorSpace()\n\n\tconst color = getColorValue(\n\t\ttheme,\n\t\tshape.props.color,\n\t\tcolorSpace === 'p3' ? 'highlightP3' : 'highlightSrgb'\n\t)\n\n\treturn (\n\t\t<path\n\t\t\td={solidStrokePath}\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tfill=\"none\"\n\t\t\tpointerEvents=\"all\"\n\t\t\tstroke={color}\n\t\t\tstrokeWidth={sw}\n\t\t\topacity={opacity}\n\t\t/>\n\t)\n}\n\nfunction useHighlightForceSolid(editor: Editor, shape: TLHighlightShape) {\n\treturn useValue(\n\t\t'forceSolid',\n\t\t() => {\n\t\t\tconst sw = getStrokeWidth(shape)\n\t\t\tconst zoomLevel = editor.getZoomLevel()\n\t\t\tif (sw / zoomLevel < 1.5) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t},\n\t\t[editor]\n\t)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -56,6 +56,9 @@ class ImageShapeUtil extends import_editor.BaseBoxShapeUtil {
|
|
|
56
56
|
canCrop() {
|
|
57
57
|
return true;
|
|
58
58
|
}
|
|
59
|
+
isExportBoundsContainer() {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
59
62
|
getDefaultProps() {
|
|
60
63
|
return {
|
|
61
64
|
w: 100,
|
|
@@ -253,9 +256,9 @@ const ImageShape = (0, import_react.memo)(function ImageShape2({ shape }) {
|
|
|
253
256
|
overflow: "hidden",
|
|
254
257
|
width: shape.props.w,
|
|
255
258
|
height: shape.props.h,
|
|
256
|
-
color: "var(--color-text-3)",
|
|
257
|
-
backgroundColor: "var(--color-low)",
|
|
258
|
-
border: "1px solid var(--color-low-border)"
|
|
259
|
+
color: "var(--tl-color-text-3)",
|
|
260
|
+
backgroundColor: "var(--tl-color-low)",
|
|
261
|
+
border: "1px solid var(--tl-color-low-border)"
|
|
259
262
|
},
|
|
260
263
|
children: [
|
|
261
264
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/image/ImageShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\tBaseBoxShapeUtil,\n\tEditor,\n\tEllipse2d,\n\tFileHelpers,\n\tGeometry2d,\n\tHTMLContainer,\n\tImage,\n\tMediaHelpers,\n\tRectangle2d,\n\tSvgExportContext,\n\tTLAsset,\n\tTLAssetId,\n\tTLImageShape,\n\tTLImageShapeProps,\n\tTLResizeInfo,\n\tTLShapePartial,\n\tVec,\n\tWeakCache,\n\tfetch,\n\timageShapeMigrations,\n\timageShapeProps,\n\tlerp,\n\tmodulate,\n\tresizeBox,\n\tstructuredClone,\n\ttoDomPrecision,\n\tuseEditor,\n\tuseUniqueSafeId,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { memo, useEffect, useState } from 'react'\nimport { BrokenAssetIcon } from '../shared/BrokenAssetIcon'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { getUncroppedSize } from '../shared/crop'\nimport { useImageOrVideoAsset } from '../shared/useImageOrVideoAsset'\nimport { usePrefersReducedMotion } from '../shared/usePrefersReducedMotion'\n\nasync function getDataURIFromURL(url: string): Promise<string> {\n\tconst response = await fetch(url)\n\tconst blob = await response.blob()\n\treturn FileHelpers.blobToDataUrl(blob)\n}\n\nconst imageSvgExportCache = new WeakCache<TLAsset, Promise<string | null>>()\n\n/** @public */\nexport class ImageShapeUtil extends BaseBoxShapeUtil<TLImageShape> {\n\tstatic override type = 'image' as const\n\tstatic override props = imageShapeProps\n\tstatic override migrations = imageShapeMigrations\n\n\toverride isAspectRatioLocked() {\n\t\treturn true\n\t}\n\toverride canCrop() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLImageShape['props'] {\n\t\treturn {\n\t\t\tw: 100,\n\t\t\th: 100,\n\t\t\tassetId: null,\n\t\t\tplaying: true,\n\t\t\turl: '',\n\t\t\tcrop: null,\n\t\t\tflipX: false,\n\t\t\tflipY: false,\n\t\t\taltText: '',\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLImageShape): Geometry2d {\n\t\tif (shape.props.crop?.isCircle) {\n\t\t\treturn new Ellipse2d({\n\t\t\t\twidth: shape.props.w,\n\t\t\t\theight: shape.props.h,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\treturn new Rectangle2d({\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\toverride getAriaDescriptor(shape: TLImageShape) {\n\t\treturn shape.props.altText\n\t}\n\n\toverride onResize(shape: TLImageShape, info: TLResizeInfo<TLImageShape>) {\n\t\tlet resized: TLImageShape = resizeBox(shape, info)\n\t\tconst { flipX, flipY } = info.initialShape.props\n\t\tconst { scaleX, scaleY, mode } = info\n\n\t\tresized = {\n\t\t\t...resized,\n\t\t\tprops: {\n\t\t\t\t...resized.props,\n\t\t\t\tflipX: scaleX < 0 !== flipX,\n\t\t\t\tflipY: scaleY < 0 !== flipY,\n\t\t\t},\n\t\t}\n\t\tif (!shape.props.crop) return resized\n\n\t\tconst flipCropHorizontally =\n\t\t\t// We used the flip horizontally feature\n\t\t\t(mode === 'scale_shape' && scaleX === -1) ||\n\t\t\t// We resized the shape past it's bounds, so it flipped\n\t\t\t(mode === 'resize_bounds' && flipX !== resized.props.flipX)\n\t\tconst flipCropVertically =\n\t\t\t// We used the flip vertically feature\n\t\t\t(mode === 'scale_shape' && scaleY === -1) ||\n\t\t\t// We resized the shape past it's bounds, so it flipped\n\t\t\t(mode === 'resize_bounds' && flipY !== resized.props.flipY)\n\n\t\tconst { topLeft, bottomRight } = shape.props.crop\n\t\tresized.props.crop = {\n\t\t\ttopLeft: {\n\t\t\t\tx: flipCropHorizontally ? 1 - bottomRight.x : topLeft.x,\n\t\t\t\ty: flipCropVertically ? 1 - bottomRight.y : topLeft.y,\n\t\t\t},\n\t\t\tbottomRight: {\n\t\t\t\tx: flipCropHorizontally ? 1 - topLeft.x : bottomRight.x,\n\t\t\t\ty: flipCropVertically ? 1 - topLeft.y : bottomRight.y,\n\t\t\t},\n\t\t\tisCircle: shape.props.crop.isCircle,\n\t\t}\n\t\treturn resized\n\t}\n\n\tcomponent(shape: TLImageShape) {\n\t\treturn <ImageShape shape={shape} />\n\t}\n\n\tindicator(shape: TLImageShape) {\n\t\tconst isCropping = this.editor.getCroppingShapeId() === shape.id\n\t\tif (isCropping) return null\n\n\t\tif (shape.props.crop?.isCircle) {\n\t\t\treturn (\n\t\t\t\t<ellipse\n\t\t\t\t\tcx={toDomPrecision(shape.props.w / 2)}\n\t\t\t\t\tcy={toDomPrecision(shape.props.h / 2)}\n\t\t\t\t\trx={toDomPrecision(shape.props.w / 2)}\n\t\t\t\t\try={toDomPrecision(shape.props.h / 2)}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\treturn <rect width={toDomPrecision(shape.props.w)} height={toDomPrecision(shape.props.h)} />\n\t}\n\n\toverride async toSvg(shape: TLImageShape, ctx: SvgExportContext) {\n\t\tconst props = shape.props\n\t\tif (!props.assetId) return null\n\n\t\tconst asset = this.editor.getAsset(props.assetId)\n\n\t\tif (!asset) return null\n\n\t\tconst { w } = getUncroppedSize(shape.props, props.crop)\n\n\t\tconst src = await imageSvgExportCache.get(asset, async () => {\n\t\t\tlet src = await ctx.resolveAssetUrl(asset.id, w)\n\t\t\tif (!src) return null\n\t\t\tif (\n\t\t\t\tsrc.startsWith('blob:') ||\n\t\t\t\tsrc.startsWith('http') ||\n\t\t\t\tsrc.startsWith('/') ||\n\t\t\t\tsrc.startsWith('./')\n\t\t\t) {\n\t\t\t\t// If it's a remote image, we need to fetch it and convert it to a data URI\n\t\t\t\tsrc = (await getDataURIFromURL(src)) || ''\n\t\t\t}\n\n\t\t\t// If it's animated then we need to get the first frame\n\t\t\tif (getIsAnimated(this.editor, asset.id)) {\n\t\t\t\tconst { promise } = getFirstFrameOfAnimatedImage(src)\n\t\t\t\tsrc = await promise\n\t\t\t}\n\t\t\treturn src\n\t\t})\n\n\t\tif (!src) return null\n\n\t\treturn <SvgImage shape={shape} src={src} />\n\t}\n\n\toverride onDoubleClickEdge(shape: TLImageShape) {\n\t\tconst props = shape.props\n\t\tif (!props) return\n\n\t\tif (this.editor.getCroppingShapeId() !== shape.id) {\n\t\t\treturn\n\t\t}\n\n\t\tconst crop = structuredClone(props.crop) || {\n\t\t\ttopLeft: { x: 0, y: 0 },\n\t\t\tbottomRight: { x: 1, y: 1 },\n\t\t}\n\n\t\t// The true asset dimensions\n\t\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\n\t\tconst pointDelta = new Vec(crop.topLeft.x * w, crop.topLeft.y * h).rot(shape.rotation)\n\n\t\tconst partial: TLShapePartial<TLImageShape> = {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tx: shape.x - pointDelta.x,\n\t\t\ty: shape.y - pointDelta.y,\n\t\t\tprops: {\n\t\t\t\tcrop: {\n\t\t\t\t\ttopLeft: { x: 0, y: 0 },\n\t\t\t\t\tbottomRight: { x: 1, y: 1 },\n\t\t\t\t},\n\t\t\t\tw,\n\t\t\t\th,\n\t\t\t},\n\t\t}\n\n\t\tthis.editor.updateShapes([partial])\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLImageShape,\n\t\tendShape: TLImageShape,\n\t\tt: number\n\t): TLImageShapeProps {\n\t\tfunction interpolateCrop(\n\t\t\tstartShape: TLImageShape,\n\t\t\tendShape: TLImageShape\n\t\t): TLImageShapeProps['crop'] {\n\t\t\tif (startShape.props.crop === null && endShape.props.crop === null) return null\n\n\t\t\tconst startTL = startShape.props.crop?.topLeft || { x: 0, y: 0 }\n\t\t\tconst startBR = startShape.props.crop?.bottomRight || { x: 1, y: 1 }\n\t\t\tconst endTL = endShape.props.crop?.topLeft || { x: 0, y: 0 }\n\t\t\tconst endBR = endShape.props.crop?.bottomRight || { x: 1, y: 1 }\n\n\t\t\treturn {\n\t\t\t\ttopLeft: { x: lerp(startTL.x, endTL.x, t), y: lerp(startTL.y, endTL.y, t) },\n\t\t\t\tbottomRight: { x: lerp(startBR.x, endBR.x, t), y: lerp(startBR.y, endBR.y, t) },\n\t\t\t}\n\t\t}\n\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\tcrop: interpolateCrop(startShape, endShape),\n\t\t}\n\t}\n}\n\nconst ImageShape = memo(function ImageShape({ shape }: { shape: TLImageShape }) {\n\tconst editor = useEditor()\n\n\tconst { w } = getUncroppedSize(shape.props, shape.props.crop)\n\tconst { asset, url } = useImageOrVideoAsset({\n\t\tshapeId: shape.id,\n\t\tassetId: shape.props.assetId,\n\t\twidth: w,\n\t})\n\n\tconst prefersReducedMotion = usePrefersReducedMotion()\n\tconst [staticFrameSrc, setStaticFrameSrc] = useState('')\n\tconst [loadedUrl, setLoadedUrl] = useState<null | string>(null)\n\tconst isAnimated = asset && getIsAnimated(editor, asset.id)\n\n\tuseEffect(() => {\n\t\tif (url && isAnimated) {\n\t\t\tconst { promise, cancel } = getFirstFrameOfAnimatedImage(url)\n\n\t\t\tpromise.then((dataUrl) => {\n\t\t\t\tsetStaticFrameSrc(dataUrl)\n\t\t\t\tsetLoadedUrl(url)\n\t\t\t})\n\n\t\t\treturn () => {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t}\n\t}, [editor, isAnimated, prefersReducedMotion, url])\n\n\tconst showCropPreview = useValue(\n\t\t'show crop preview',\n\t\t() =>\n\t\t\tshape.id === editor.getOnlySelectedShapeId() &&\n\t\t\teditor.getCroppingShapeId() === shape.id &&\n\t\t\teditor.isIn('select.crop'),\n\t\t[editor, shape.id]\n\t)\n\n\t// We only want to reduce motion for mimeTypes that have motion\n\tconst reduceMotion =\n\t\tprefersReducedMotion && (asset?.props.mimeType?.includes('video') || isAnimated)\n\n\tconst containerStyle = getCroppedContainerStyle(shape)\n\n\tconst nextSrc = url === loadedUrl ? null : url\n\tconst loadedSrc = reduceMotion ? staticFrameSrc : loadedUrl\n\n\t// This logic path is for when it's broken/missing asset.\n\tif (!url && !asset?.props.src) {\n\t\treturn (\n\t\t\t<HTMLContainer\n\t\t\t\tid={shape.id}\n\t\t\t\tstyle={{\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tcolor: 'var(--color-text-3)',\n\t\t\t\t\tbackgroundColor: 'var(--color-low)',\n\t\t\t\t\tborder: '1px solid var(--color-low-border)',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={classNames('tl-image-container', asset && 'tl-image-container-loading')}\n\t\t\t\t\tstyle={containerStyle}\n\t\t\t\t>\n\t\t\t\t\t{asset ? null : <BrokenAssetIcon />}\n\t\t\t\t</div>\n\t\t\t\t{'url' in shape.props && shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\t// We don't set crossOrigin for non-animated images because for Cloudflare we don't currently\n\t// have that set up.\n\tconst crossOrigin = isAnimated ? 'anonymous' : undefined\n\n\treturn (\n\t\t<>\n\t\t\t{showCropPreview && loadedSrc && (\n\t\t\t\t<div style={containerStyle}>\n\t\t\t\t\t<img\n\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\tstyle={{ ...getFlipStyle(shape), opacity: 0.1 }}\n\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\tsrc={loadedSrc}\n\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<HTMLContainer\n\t\t\t\tid={shape.id}\n\t\t\t\tstyle={{\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tborderRadius: shape.props.crop?.isCircle ? '50%' : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={classNames('tl-image-container')} style={containerStyle}>\n\t\t\t\t\t{/* We have two images: the currently loaded image, and the next image that\n\t\t\t\t\twe're waiting to load. we keep the loaded image mounted while we're waiting\n\t\t\t\t\tfor the next one by storing the loaded URL in state. We use `key` props with\n\t\t\t\t\tthe src of the image so that when the next image is ready, the previous one will\n\t\t\t\t\tbe unmounted and the next will be shown with the browser having to remount a\n\t\t\t\t\tfresh image and decoded it again from the cache. */}\n\t\t\t\t\t{loadedSrc && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={loadedSrc}\n\t\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\t\tstyle={getFlipStyle(shape)}\n\t\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\t\tsrc={loadedSrc}\n\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{nextSrc && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={nextSrc}\n\t\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\t\tstyle={getFlipStyle(shape)}\n\t\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\t\tsrc={nextSrc}\n\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\talt={shape.props.altText}\n\t\t\t\t\t\t\tonLoad={() => setLoadedUrl(nextSrc)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</HTMLContainer>\n\t\t</>\n\t)\n})\n\nfunction getIsAnimated(editor: Editor, assetId: TLAssetId) {\n\tconst asset = assetId ? editor.getAsset(assetId) : undefined\n\n\tif (!asset) return false\n\n\treturn (\n\t\t('mimeType' in asset.props && MediaHelpers.isAnimatedImageType(asset?.props.mimeType)) ||\n\t\t('isAnimated' in asset.props && asset.props.isAnimated)\n\t)\n}\n\n/**\n * When an image is cropped we need to translate the image to show the portion withing the cropped\n * area. We do this by translating the image by the negative of the top left corner of the crop\n * area.\n *\n * @param shape - Shape The image shape for which to get the container style\n * @returns - Styles to apply to the image container\n */\nfunction getCroppedContainerStyle(shape: TLImageShape) {\n\tconst crop = shape.props.crop\n\tconst topLeft = crop?.topLeft\n\tif (!topLeft) {\n\t\treturn {\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t}\n\t}\n\n\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\tconst offsetX = -topLeft.x * w\n\tconst offsetY = -topLeft.y * h\n\treturn {\n\t\ttransform: `translate(${offsetX}px, ${offsetY}px)`,\n\t\twidth: w,\n\t\theight: h,\n\t}\n}\n\nfunction getFlipStyle(shape: TLImageShape, size?: { width: number; height: number }) {\n\tconst { flipX, flipY, crop } = shape.props\n\tif (!flipX && !flipY) return undefined\n\n\tlet cropOffsetX\n\tlet cropOffsetY\n\tif (crop) {\n\t\t// We have to do all this extra math because of the whole transform origin around 0,0\n\t\t// instead of center in SVG-land, ugh.\n\t\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\n\t\t// Find the resulting w/h of the crop in normalized (0-1) coordinates\n\t\tconst cropWidth = crop.bottomRight.x - crop.topLeft.x\n\t\tconst cropHeight = crop.bottomRight.y - crop.topLeft.y\n\n\t\t// Map from the normalized crop coordinate space to shape pixel space\n\t\tcropOffsetX = modulate(crop.topLeft.x, [0, 1 - cropWidth], [0, w - shape.props.w])\n\t\tcropOffsetY = modulate(crop.topLeft.y, [0, 1 - cropHeight], [0, h - shape.props.h])\n\t}\n\n\tconst scale = `scale(${flipX ? -1 : 1}, ${flipY ? -1 : 1})`\n\tconst translate = size\n\t\t? `translate(${(flipX ? size.width : 0) - (cropOffsetX ? cropOffsetX : 0)}px,\n\t\t ${(flipY ? size.height : 0) - (cropOffsetY ? cropOffsetY : 0)}px)`\n\t\t: ''\n\n\treturn {\n\t\ttransform: `${translate} ${scale}`,\n\t\t// in SVG, flipping around the center doesn't work so we use explicit width/height\n\t\ttransformOrigin: size ? '0 0' : 'center center',\n\t}\n}\n\nfunction SvgImage({ shape, src }: { shape: TLImageShape; src: string }) {\n\tconst cropClipId = useUniqueSafeId()\n\tconst containerStyle = getCroppedContainerStyle(shape)\n\tconst crop = shape.props.crop\n\n\tif (containerStyle.transform && crop) {\n\t\tconst { transform: cropTransform, width, height } = containerStyle\n\t\tconst croppedWidth = (crop.bottomRight.x - crop.topLeft.x) * width\n\t\tconst croppedHeight = (crop.bottomRight.y - crop.topLeft.y) * height\n\n\t\tconst points = [\n\t\t\tnew Vec(0, 0),\n\t\t\tnew Vec(croppedWidth, 0),\n\t\t\tnew Vec(croppedWidth, croppedHeight),\n\t\t\tnew Vec(0, croppedHeight),\n\t\t]\n\n\t\tconst flip = getFlipStyle(shape, { width, height })\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<defs>\n\t\t\t\t\t<clipPath id={cropClipId}>\n\t\t\t\t\t\t{crop.isCircle ? (\n\t\t\t\t\t\t\t<ellipse\n\t\t\t\t\t\t\t\tcx={croppedWidth / 2}\n\t\t\t\t\t\t\t\tcy={croppedHeight / 2}\n\t\t\t\t\t\t\t\trx={croppedWidth / 2}\n\t\t\t\t\t\t\t\try={croppedHeight / 2}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<polygon points={points.map((p) => `${p.x},${p.y}`).join(' ')} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</clipPath>\n\t\t\t\t</defs>\n\t\t\t\t<g clipPath={`url(#${cropClipId})`}>\n\t\t\t\t\t<image\n\t\t\t\t\t\thref={src}\n\t\t\t\t\t\twidth={width}\n\t\t\t\t\t\theight={height}\n\t\t\t\t\t\taria-label={shape.props.altText}\n\t\t\t\t\t\tstyle={flip ? { ...flip } : { transform: cropTransform }}\n\t\t\t\t\t/>\n\t\t\t\t</g>\n\t\t\t</>\n\t\t)\n\t} else {\n\t\treturn (\n\t\t\t<image\n\t\t\t\thref={src}\n\t\t\t\twidth={shape.props.w}\n\t\t\t\theight={shape.props.h}\n\t\t\t\taria-label={shape.props.altText}\n\t\t\t\tstyle={getFlipStyle(shape, { width: shape.props.w, height: shape.props.h })}\n\t\t\t/>\n\t\t)\n\t}\n}\n\nfunction getFirstFrameOfAnimatedImage(url: string) {\n\tlet cancelled = false\n\n\tconst promise = new Promise<string>((resolve) => {\n\t\tconst image = Image()\n\t\timage.onload = () => {\n\t\t\tif (cancelled) return\n\n\t\t\tconst canvas = document.createElement('canvas')\n\t\t\tcanvas.width = image.width\n\t\t\tcanvas.height = image.height\n\n\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\tif (!ctx) return\n\n\t\t\tctx.drawImage(image, 0, 0)\n\t\t\tresolve(canvas.toDataURL())\n\t\t}\n\t\timage.crossOrigin = 'anonymous'\n\t\timage.src = url\n\t})\n\n\treturn { promise, cancel: () => (cancelled = true) }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import {\n\tBaseBoxShapeUtil,\n\tEditor,\n\tEllipse2d,\n\tFileHelpers,\n\tGeometry2d,\n\tHTMLContainer,\n\tImage,\n\tMediaHelpers,\n\tRectangle2d,\n\tSvgExportContext,\n\tTLAsset,\n\tTLAssetId,\n\tTLImageShape,\n\tTLImageShapeProps,\n\tTLResizeInfo,\n\tTLShapePartial,\n\tVec,\n\tWeakCache,\n\tfetch,\n\timageShapeMigrations,\n\timageShapeProps,\n\tlerp,\n\tmodulate,\n\tresizeBox,\n\tstructuredClone,\n\ttoDomPrecision,\n\tuseEditor,\n\tuseUniqueSafeId,\n\tuseValue,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { memo, useEffect, useState } from 'react'\nimport { BrokenAssetIcon } from '../shared/BrokenAssetIcon'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { getUncroppedSize } from '../shared/crop'\nimport { useImageOrVideoAsset } from '../shared/useImageOrVideoAsset'\nimport { usePrefersReducedMotion } from '../shared/usePrefersReducedMotion'\n\nasync function getDataURIFromURL(url: string): Promise<string> {\n\tconst response = await fetch(url)\n\tconst blob = await response.blob()\n\treturn FileHelpers.blobToDataUrl(blob)\n}\n\nconst imageSvgExportCache = new WeakCache<TLAsset, Promise<string | null>>()\n\n/** @public */\nexport class ImageShapeUtil extends BaseBoxShapeUtil<TLImageShape> {\n\tstatic override type = 'image' as const\n\tstatic override props = imageShapeProps\n\tstatic override migrations = imageShapeMigrations\n\n\toverride isAspectRatioLocked() {\n\t\treturn true\n\t}\n\toverride canCrop() {\n\t\treturn true\n\t}\n\toverride isExportBoundsContainer(): boolean {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLImageShape['props'] {\n\t\treturn {\n\t\t\tw: 100,\n\t\t\th: 100,\n\t\t\tassetId: null,\n\t\t\tplaying: true,\n\t\t\turl: '',\n\t\t\tcrop: null,\n\t\t\tflipX: false,\n\t\t\tflipY: false,\n\t\t\taltText: '',\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLImageShape): Geometry2d {\n\t\tif (shape.props.crop?.isCircle) {\n\t\t\treturn new Ellipse2d({\n\t\t\t\twidth: shape.props.w,\n\t\t\t\theight: shape.props.h,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\treturn new Rectangle2d({\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\toverride getAriaDescriptor(shape: TLImageShape) {\n\t\treturn shape.props.altText\n\t}\n\n\toverride onResize(shape: TLImageShape, info: TLResizeInfo<TLImageShape>) {\n\t\tlet resized: TLImageShape = resizeBox(shape, info)\n\t\tconst { flipX, flipY } = info.initialShape.props\n\t\tconst { scaleX, scaleY, mode } = info\n\n\t\tresized = {\n\t\t\t...resized,\n\t\t\tprops: {\n\t\t\t\t...resized.props,\n\t\t\t\tflipX: scaleX < 0 !== flipX,\n\t\t\t\tflipY: scaleY < 0 !== flipY,\n\t\t\t},\n\t\t}\n\t\tif (!shape.props.crop) return resized\n\n\t\tconst flipCropHorizontally =\n\t\t\t// We used the flip horizontally feature\n\t\t\t(mode === 'scale_shape' && scaleX === -1) ||\n\t\t\t// We resized the shape past it's bounds, so it flipped\n\t\t\t(mode === 'resize_bounds' && flipX !== resized.props.flipX)\n\t\tconst flipCropVertically =\n\t\t\t// We used the flip vertically feature\n\t\t\t(mode === 'scale_shape' && scaleY === -1) ||\n\t\t\t// We resized the shape past it's bounds, so it flipped\n\t\t\t(mode === 'resize_bounds' && flipY !== resized.props.flipY)\n\n\t\tconst { topLeft, bottomRight } = shape.props.crop\n\t\tresized.props.crop = {\n\t\t\ttopLeft: {\n\t\t\t\tx: flipCropHorizontally ? 1 - bottomRight.x : topLeft.x,\n\t\t\t\ty: flipCropVertically ? 1 - bottomRight.y : topLeft.y,\n\t\t\t},\n\t\t\tbottomRight: {\n\t\t\t\tx: flipCropHorizontally ? 1 - topLeft.x : bottomRight.x,\n\t\t\t\ty: flipCropVertically ? 1 - topLeft.y : bottomRight.y,\n\t\t\t},\n\t\t\tisCircle: shape.props.crop.isCircle,\n\t\t}\n\t\treturn resized\n\t}\n\n\tcomponent(shape: TLImageShape) {\n\t\treturn <ImageShape shape={shape} />\n\t}\n\n\tindicator(shape: TLImageShape) {\n\t\tconst isCropping = this.editor.getCroppingShapeId() === shape.id\n\t\tif (isCropping) return null\n\n\t\tif (shape.props.crop?.isCircle) {\n\t\t\treturn (\n\t\t\t\t<ellipse\n\t\t\t\t\tcx={toDomPrecision(shape.props.w / 2)}\n\t\t\t\t\tcy={toDomPrecision(shape.props.h / 2)}\n\t\t\t\t\trx={toDomPrecision(shape.props.w / 2)}\n\t\t\t\t\try={toDomPrecision(shape.props.h / 2)}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\treturn <rect width={toDomPrecision(shape.props.w)} height={toDomPrecision(shape.props.h)} />\n\t}\n\n\toverride async toSvg(shape: TLImageShape, ctx: SvgExportContext) {\n\t\tconst props = shape.props\n\t\tif (!props.assetId) return null\n\n\t\tconst asset = this.editor.getAsset(props.assetId)\n\n\t\tif (!asset) return null\n\n\t\tconst { w } = getUncroppedSize(shape.props, props.crop)\n\n\t\tconst src = await imageSvgExportCache.get(asset, async () => {\n\t\t\tlet src = await ctx.resolveAssetUrl(asset.id, w)\n\t\t\tif (!src) return null\n\t\t\tif (\n\t\t\t\tsrc.startsWith('blob:') ||\n\t\t\t\tsrc.startsWith('http') ||\n\t\t\t\tsrc.startsWith('/') ||\n\t\t\t\tsrc.startsWith('./')\n\t\t\t) {\n\t\t\t\t// If it's a remote image, we need to fetch it and convert it to a data URI\n\t\t\t\tsrc = (await getDataURIFromURL(src)) || ''\n\t\t\t}\n\n\t\t\t// If it's animated then we need to get the first frame\n\t\t\tif (getIsAnimated(this.editor, asset.id)) {\n\t\t\t\tconst { promise } = getFirstFrameOfAnimatedImage(src)\n\t\t\t\tsrc = await promise\n\t\t\t}\n\t\t\treturn src\n\t\t})\n\n\t\tif (!src) return null\n\n\t\treturn <SvgImage shape={shape} src={src} />\n\t}\n\n\toverride onDoubleClickEdge(shape: TLImageShape) {\n\t\tconst props = shape.props\n\t\tif (!props) return\n\n\t\tif (this.editor.getCroppingShapeId() !== shape.id) {\n\t\t\treturn\n\t\t}\n\n\t\tconst crop = structuredClone(props.crop) || {\n\t\t\ttopLeft: { x: 0, y: 0 },\n\t\t\tbottomRight: { x: 1, y: 1 },\n\t\t}\n\n\t\t// The true asset dimensions\n\t\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\n\t\tconst pointDelta = new Vec(crop.topLeft.x * w, crop.topLeft.y * h).rot(shape.rotation)\n\n\t\tconst partial: TLShapePartial<TLImageShape> = {\n\t\t\tid: shape.id,\n\t\t\ttype: shape.type,\n\t\t\tx: shape.x - pointDelta.x,\n\t\t\ty: shape.y - pointDelta.y,\n\t\t\tprops: {\n\t\t\t\tcrop: {\n\t\t\t\t\ttopLeft: { x: 0, y: 0 },\n\t\t\t\t\tbottomRight: { x: 1, y: 1 },\n\t\t\t\t},\n\t\t\t\tw,\n\t\t\t\th,\n\t\t\t},\n\t\t}\n\n\t\tthis.editor.updateShapes([partial])\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLImageShape,\n\t\tendShape: TLImageShape,\n\t\tt: number\n\t): TLImageShapeProps {\n\t\tfunction interpolateCrop(\n\t\t\tstartShape: TLImageShape,\n\t\t\tendShape: TLImageShape\n\t\t): TLImageShapeProps['crop'] {\n\t\t\tif (startShape.props.crop === null && endShape.props.crop === null) return null\n\n\t\t\tconst startTL = startShape.props.crop?.topLeft || { x: 0, y: 0 }\n\t\t\tconst startBR = startShape.props.crop?.bottomRight || { x: 1, y: 1 }\n\t\t\tconst endTL = endShape.props.crop?.topLeft || { x: 0, y: 0 }\n\t\t\tconst endBR = endShape.props.crop?.bottomRight || { x: 1, y: 1 }\n\n\t\t\treturn {\n\t\t\t\ttopLeft: { x: lerp(startTL.x, endTL.x, t), y: lerp(startTL.y, endTL.y, t) },\n\t\t\t\tbottomRight: { x: lerp(startBR.x, endBR.x, t), y: lerp(startBR.y, endBR.y, t) },\n\t\t\t}\n\t\t}\n\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\tcrop: interpolateCrop(startShape, endShape),\n\t\t}\n\t}\n}\n\nconst ImageShape = memo(function ImageShape({ shape }: { shape: TLImageShape }) {\n\tconst editor = useEditor()\n\n\tconst { w } = getUncroppedSize(shape.props, shape.props.crop)\n\tconst { asset, url } = useImageOrVideoAsset({\n\t\tshapeId: shape.id,\n\t\tassetId: shape.props.assetId,\n\t\twidth: w,\n\t})\n\n\tconst prefersReducedMotion = usePrefersReducedMotion()\n\tconst [staticFrameSrc, setStaticFrameSrc] = useState('')\n\tconst [loadedUrl, setLoadedUrl] = useState<null | string>(null)\n\tconst isAnimated = asset && getIsAnimated(editor, asset.id)\n\n\tuseEffect(() => {\n\t\tif (url && isAnimated) {\n\t\t\tconst { promise, cancel } = getFirstFrameOfAnimatedImage(url)\n\n\t\t\tpromise.then((dataUrl) => {\n\t\t\t\tsetStaticFrameSrc(dataUrl)\n\t\t\t\tsetLoadedUrl(url)\n\t\t\t})\n\n\t\t\treturn () => {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t}\n\t}, [editor, isAnimated, prefersReducedMotion, url])\n\n\tconst showCropPreview = useValue(\n\t\t'show crop preview',\n\t\t() =>\n\t\t\tshape.id === editor.getOnlySelectedShapeId() &&\n\t\t\teditor.getCroppingShapeId() === shape.id &&\n\t\t\teditor.isIn('select.crop'),\n\t\t[editor, shape.id]\n\t)\n\n\t// We only want to reduce motion for mimeTypes that have motion\n\tconst reduceMotion =\n\t\tprefersReducedMotion && (asset?.props.mimeType?.includes('video') || isAnimated)\n\n\tconst containerStyle = getCroppedContainerStyle(shape)\n\n\tconst nextSrc = url === loadedUrl ? null : url\n\tconst loadedSrc = reduceMotion ? staticFrameSrc : loadedUrl\n\n\t// This logic path is for when it's broken/missing asset.\n\tif (!url && !asset?.props.src) {\n\t\treturn (\n\t\t\t<HTMLContainer\n\t\t\t\tid={shape.id}\n\t\t\t\tstyle={{\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tcolor: 'var(--tl-color-text-3)',\n\t\t\t\t\tbackgroundColor: 'var(--tl-color-low)',\n\t\t\t\t\tborder: '1px solid var(--tl-color-low-border)',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={classNames('tl-image-container', asset && 'tl-image-container-loading')}\n\t\t\t\t\tstyle={containerStyle}\n\t\t\t\t>\n\t\t\t\t\t{asset ? null : <BrokenAssetIcon />}\n\t\t\t\t</div>\n\t\t\t\t{'url' in shape.props && shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</HTMLContainer>\n\t\t)\n\t}\n\n\t// We don't set crossOrigin for non-animated images because for Cloudflare we don't currently\n\t// have that set up.\n\tconst crossOrigin = isAnimated ? 'anonymous' : undefined\n\n\treturn (\n\t\t<>\n\t\t\t{showCropPreview && loadedSrc && (\n\t\t\t\t<div style={containerStyle}>\n\t\t\t\t\t<img\n\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\tstyle={{ ...getFlipStyle(shape), opacity: 0.1 }}\n\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\tsrc={loadedSrc}\n\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<HTMLContainer\n\t\t\t\tid={shape.id}\n\t\t\t\tstyle={{\n\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\theight: shape.props.h,\n\t\t\t\t\tborderRadius: shape.props.crop?.isCircle ? '50%' : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={classNames('tl-image-container')} style={containerStyle}>\n\t\t\t\t\t{/* We have two images: the currently loaded image, and the next image that\n\t\t\t\t\twe're waiting to load. we keep the loaded image mounted while we're waiting\n\t\t\t\t\tfor the next one by storing the loaded URL in state. We use `key` props with\n\t\t\t\t\tthe src of the image so that when the next image is ready, the previous one will\n\t\t\t\t\tbe unmounted and the next will be shown with the browser having to remount a\n\t\t\t\t\tfresh image and decoded it again from the cache. */}\n\t\t\t\t\t{loadedSrc && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={loadedSrc}\n\t\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\t\tstyle={getFlipStyle(shape)}\n\t\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\t\tsrc={loadedSrc}\n\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\talt=\"\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{nextSrc && (\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tkey={nextSrc}\n\t\t\t\t\t\t\tclassName=\"tl-image\"\n\t\t\t\t\t\t\tstyle={getFlipStyle(shape)}\n\t\t\t\t\t\t\tcrossOrigin={crossOrigin}\n\t\t\t\t\t\t\tsrc={nextSrc}\n\t\t\t\t\t\t\treferrerPolicy=\"strict-origin-when-cross-origin\"\n\t\t\t\t\t\t\tdraggable={false}\n\t\t\t\t\t\t\talt={shape.props.altText}\n\t\t\t\t\t\t\tonLoad={() => setLoadedUrl(nextSrc)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</HTMLContainer>\n\t\t</>\n\t)\n})\n\nfunction getIsAnimated(editor: Editor, assetId: TLAssetId) {\n\tconst asset = assetId ? editor.getAsset(assetId) : undefined\n\n\tif (!asset) return false\n\n\treturn (\n\t\t('mimeType' in asset.props && MediaHelpers.isAnimatedImageType(asset?.props.mimeType)) ||\n\t\t('isAnimated' in asset.props && asset.props.isAnimated)\n\t)\n}\n\n/**\n * When an image is cropped we need to translate the image to show the portion withing the cropped\n * area. We do this by translating the image by the negative of the top left corner of the crop\n * area.\n *\n * @param shape - Shape The image shape for which to get the container style\n * @returns - Styles to apply to the image container\n */\nfunction getCroppedContainerStyle(shape: TLImageShape) {\n\tconst crop = shape.props.crop\n\tconst topLeft = crop?.topLeft\n\tif (!topLeft) {\n\t\treturn {\n\t\t\twidth: shape.props.w,\n\t\t\theight: shape.props.h,\n\t\t}\n\t}\n\n\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\tconst offsetX = -topLeft.x * w\n\tconst offsetY = -topLeft.y * h\n\treturn {\n\t\ttransform: `translate(${offsetX}px, ${offsetY}px)`,\n\t\twidth: w,\n\t\theight: h,\n\t}\n}\n\nfunction getFlipStyle(shape: TLImageShape, size?: { width: number; height: number }) {\n\tconst { flipX, flipY, crop } = shape.props\n\tif (!flipX && !flipY) return undefined\n\n\tlet cropOffsetX\n\tlet cropOffsetY\n\tif (crop) {\n\t\t// We have to do all this extra math because of the whole transform origin around 0,0\n\t\t// instead of center in SVG-land, ugh.\n\t\tconst { w, h } = getUncroppedSize(shape.props, crop)\n\n\t\t// Find the resulting w/h of the crop in normalized (0-1) coordinates\n\t\tconst cropWidth = crop.bottomRight.x - crop.topLeft.x\n\t\tconst cropHeight = crop.bottomRight.y - crop.topLeft.y\n\n\t\t// Map from the normalized crop coordinate space to shape pixel space\n\t\tcropOffsetX = modulate(crop.topLeft.x, [0, 1 - cropWidth], [0, w - shape.props.w])\n\t\tcropOffsetY = modulate(crop.topLeft.y, [0, 1 - cropHeight], [0, h - shape.props.h])\n\t}\n\n\tconst scale = `scale(${flipX ? -1 : 1}, ${flipY ? -1 : 1})`\n\tconst translate = size\n\t\t? `translate(${(flipX ? size.width : 0) - (cropOffsetX ? cropOffsetX : 0)}px,\n\t\t ${(flipY ? size.height : 0) - (cropOffsetY ? cropOffsetY : 0)}px)`\n\t\t: ''\n\n\treturn {\n\t\ttransform: `${translate} ${scale}`,\n\t\t// in SVG, flipping around the center doesn't work so we use explicit width/height\n\t\ttransformOrigin: size ? '0 0' : 'center center',\n\t}\n}\n\nfunction SvgImage({ shape, src }: { shape: TLImageShape; src: string }) {\n\tconst cropClipId = useUniqueSafeId()\n\tconst containerStyle = getCroppedContainerStyle(shape)\n\tconst crop = shape.props.crop\n\n\tif (containerStyle.transform && crop) {\n\t\tconst { transform: cropTransform, width, height } = containerStyle\n\t\tconst croppedWidth = (crop.bottomRight.x - crop.topLeft.x) * width\n\t\tconst croppedHeight = (crop.bottomRight.y - crop.topLeft.y) * height\n\n\t\tconst points = [\n\t\t\tnew Vec(0, 0),\n\t\t\tnew Vec(croppedWidth, 0),\n\t\t\tnew Vec(croppedWidth, croppedHeight),\n\t\t\tnew Vec(0, croppedHeight),\n\t\t]\n\n\t\tconst flip = getFlipStyle(shape, { width, height })\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<defs>\n\t\t\t\t\t<clipPath id={cropClipId}>\n\t\t\t\t\t\t{crop.isCircle ? (\n\t\t\t\t\t\t\t<ellipse\n\t\t\t\t\t\t\t\tcx={croppedWidth / 2}\n\t\t\t\t\t\t\t\tcy={croppedHeight / 2}\n\t\t\t\t\t\t\t\trx={croppedWidth / 2}\n\t\t\t\t\t\t\t\try={croppedHeight / 2}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<polygon points={points.map((p) => `${p.x},${p.y}`).join(' ')} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</clipPath>\n\t\t\t\t</defs>\n\t\t\t\t<g clipPath={`url(#${cropClipId})`}>\n\t\t\t\t\t<image\n\t\t\t\t\t\thref={src}\n\t\t\t\t\t\twidth={width}\n\t\t\t\t\t\theight={height}\n\t\t\t\t\t\taria-label={shape.props.altText}\n\t\t\t\t\t\tstyle={flip ? { ...flip } : { transform: cropTransform }}\n\t\t\t\t\t/>\n\t\t\t\t</g>\n\t\t\t</>\n\t\t)\n\t} else {\n\t\treturn (\n\t\t\t<image\n\t\t\t\thref={src}\n\t\t\t\twidth={shape.props.w}\n\t\t\t\theight={shape.props.h}\n\t\t\t\taria-label={shape.props.altText}\n\t\t\t\tstyle={getFlipStyle(shape, { width: shape.props.w, height: shape.props.h })}\n\t\t\t/>\n\t\t)\n\t}\n}\n\nfunction getFirstFrameOfAnimatedImage(url: string) {\n\tlet cancelled = false\n\n\tconst promise = new Promise<string>((resolve) => {\n\t\tconst image = Image()\n\t\timage.onload = () => {\n\t\t\tif (cancelled) return\n\n\t\t\tconst canvas = document.createElement('canvas')\n\t\t\tcanvas.width = image.width\n\t\t\tcanvas.height = image.height\n\n\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\tif (!ctx) return\n\n\t\t\tctx.drawImage(image, 0, 0)\n\t\t\tresolve(canvas.toDataURL())\n\t\t}\n\t\timage.crossOrigin = 'anonymous'\n\t\timage.src = url\n\t})\n\n\treturn { promise, cancel: () => (cancelled = true) }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["src", "startShape", "endShape", "ImageShape", "classNames"]
|
|
7
7
|
}
|
|
@@ -277,7 +277,11 @@ function LineShapeSvg({
|
|
|
277
277
|
strokeWidth,
|
|
278
278
|
forceSolid,
|
|
279
279
|
randomSeed: shape.id,
|
|
280
|
-
props: {
|
|
280
|
+
props: {
|
|
281
|
+
transform: `scale(${scale})`,
|
|
282
|
+
stroke: (0, import_editor.getColorValue)(theme, color, "solid"),
|
|
283
|
+
fill: "none"
|
|
284
|
+
}
|
|
281
285
|
});
|
|
282
286
|
}
|
|
283
287
|
//# sourceMappingURL=LineShapeUtil.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/shapes/line/LineShapeUtil.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n\tGroup2d,\n\tHandleSnapGeometry,\n\tSVGContainer,\n\tShapeUtil,\n\tTLHandle,\n\tTLHandleDragInfo,\n\tTLLineShape,\n\tTLLineShapePoint,\n\tTLResizeInfo,\n\tVec,\n\tWeakCache,\n\tZERO_INDEX_KEY,\n\tassert,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tlerp,\n\tlineShapeMigrations,\n\tlineShapeProps,\n\tmapObjectMapValues,\n\tmaybeSnapToGrid,\n\tsortByIndex,\n} from '@tldraw/editor'\n\nimport { STROKE_SIZES } from '../arrow/shared'\nimport { PathBuilder, PathBuilderGeometry2d } from '../shared/PathBuilder'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\nconst handlesCache = new WeakCache<TLLineShape['props'], TLHandle[]>()\n\n/** @public */\nexport class LineShapeUtil extends ShapeUtil<TLLineShape> {\n\tstatic override type = 'line' as const\n\tstatic override props = lineShapeProps\n\tstatic override migrations = lineShapeMigrations\n\n\toverride hideResizeHandles() {\n\t\treturn true\n\t}\n\toverride hideRotateHandle() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsBg() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLLineShape['props'] {\n\t\tconst [start, end] = getIndices(2)\n\t\treturn {\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tcolor: 'black',\n\t\t\tspline: 'line',\n\t\t\tpoints: {\n\t\t\t\t[start]: { id: start, index: start, x: 0, y: 0 },\n\t\t\t\t[end]: { id: end, index: end, x: 0.1, y: 0.1 },\n\t\t\t},\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLLineShape) {\n\t\t// todo: should we have min size?\n\t\tconst geometry = getPathForLineShape(shape).toGeometry()\n\t\tassert(geometry instanceof PathBuilderGeometry2d)\n\t\treturn geometry\n\t}\n\n\toverride getHandles(shape: TLLineShape) {\n\t\treturn handlesCache.get(shape.props, () => {\n\t\t\tconst spline = this.getGeometry(shape)\n\n\t\t\tconst points = linePointsToArray(shape)\n\t\t\tconst results: TLHandle[] = points.map((point) => ({\n\t\t\t\t...point,\n\t\t\t\tid: point.index,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tcanSnap: true,\n\t\t\t}))\n\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tconst index = getIndexBetween(points[i].index, points[i + 1].index)\n\t\t\t\tconst segment = spline.getSegments()[i]\n\t\t\t\tconst point = segment.interpolateAlongEdge(0.5)\n\t\t\t\tresults.push({\n\t\t\t\t\tid: index,\n\t\t\t\t\ttype: 'create',\n\t\t\t\t\tindex,\n\t\t\t\t\tx: point.x,\n\t\t\t\t\ty: point.y,\n\t\t\t\t\tcanSnap: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn results.sort(sortByIndex)\n\t\t})\n\t}\n\n\t// Events\n\n\toverride onResize(shape: TLLineShape, info: TLResizeInfo<TLLineShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tpoints: mapObjectMapValues(shape.props.points, (_, { id, index, x, y }) => ({\n\t\t\t\t\tid,\n\t\t\t\t\tindex,\n\t\t\t\t\tx: x * scaleX,\n\t\t\t\t\ty: y * scaleY,\n\t\t\t\t})),\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(next: TLLineShape): void | TLLineShape {\n\t\tconst {\n\t\t\tprops: { points },\n\t\t} = next\n\t\tconst pointKeys = Object.keys(points)\n\n\t\tif (pointKeys.length < 2) {\n\t\t\treturn\n\t\t}\n\n\t\tconst firstPoint = points[pointKeys[0]]\n\t\tconst allSame = pointKeys.every((key) => {\n\t\t\tconst point = points[key]\n\t\t\treturn point.x === firstPoint.x && point.y === firstPoint.y\n\t\t})\n\t\tif (allSame) {\n\t\t\tconst lastKey = pointKeys[pointKeys.length - 1]\n\t\t\tpoints[lastKey] = {\n\t\t\t\t...points[lastKey],\n\t\t\t\tx: points[lastKey].x + 0.1,\n\t\t\t\ty: points[lastKey].y + 0.1,\n\t\t\t}\n\t\t\treturn next\n\t\t}\n\t\treturn\n\t}\n\n\toverride onHandleDrag(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\tconst newPoint = maybeSnapToGrid(new Vec(handle.x, handle.y), this.editor)\n\t\treturn {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tpoints: {\n\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t[handle.id]: { id: handle.id, index: handle.index, x: newPoint.x, y: newPoint.y },\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onHandleDragStart(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\t// For line shapes, if we're dragging a \"create\" handle, then\n\t\t// create a new vertex handle at that point; and make this handle\n\t\t// the handle that we're dragging.\n\t\tif (handle.type === 'create') {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tpoints: {\n\t\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t\t[handle.index]: { id: handle.index, index: handle.index, x: handle.x, y: handle.y },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\n\tcomponent(shape: TLLineShape) {\n\t\treturn (\n\t\t\t<SVGContainer style={{ minWidth: 50, minHeight: 50 }}>\n\t\t\t\t<LineShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLLineShape) {\n\t\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\t\tconst path = getPathForLineShape(shape)\n\t\tconst { dash } = shape.props\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLLineShape) {\n\t\treturn <LineShapeSvg shouldScale shape={shape} />\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLLineShape): HandleSnapGeometry {\n\t\tconst points = linePointsToArray(shape)\n\t\treturn {\n\t\t\tpoints,\n\t\t\tgetSelfSnapPoints: (handle) => {\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// We want to skip the current and adjacent handles\n\t\t\t\treturn points.filter((_, i) => Math.abs(i - index) > 1).map(Vec.From)\n\t\t\t},\n\t\t\tgetSelfSnapOutline: (handle) => {\n\t\t\t\t// We want to skip the segments that include the handle, so\n\t\t\t\t// find the index of the handle that shares the same index property\n\t\t\t\t// as the initial dragging handle; this catches a quirk of create handles\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// Get all the outline segments from the shape that don't include the handle\n\t\t\t\tconst segments = this.getGeometry(shape)\n\t\t\t\t\t.getSegments()\n\t\t\t\t\t.filter((_, i) => i !== index - 1 && i !== index)\n\n\t\t\t\tif (!segments.length) return null\n\t\t\t\treturn new Group2d({ children: segments })\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLLineShape,\n\t\tendShape: TLLineShape,\n\t\tt: number\n\t): TLLineShape['props'] {\n\t\tconst startPoints = linePointsToArray(startShape)\n\t\tconst endPoints = linePointsToArray(endShape)\n\n\t\tconst pointsToUseStart: TLLineShapePoint[] = []\n\t\tconst pointsToUseEnd: TLLineShapePoint[] = []\n\n\t\tlet index = ZERO_INDEX_KEY\n\n\t\tif (startPoints.length > endPoints.length) {\n\t\t\t// we'll need to expand points\n\t\t\tfor (let i = 0; i < startPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = { ...startPoints[i] }\n\t\t\t\tif (endPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[endPoints.length - 1], id: index }\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else if (endPoints.length > startPoints.length) {\n\t\t\t// we'll need to converge points\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i] }\n\t\t\t\tif (startPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseStart[i] = {\n\t\t\t\t\t\t...startPoints[startPoints.length - 1],\n\t\t\t\t\t\tid: index,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseStart[i] = { ...startPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else {\n\t\t\t// noop, easy\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = startPoints[i]\n\t\t\t\tpointsToUseEnd[i] = endPoints[i]\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tpoints: Object.fromEntries(\n\t\t\t\tpointsToUseStart.map((point, i) => {\n\t\t\t\t\tconst endPoint = pointsToUseEnd[i]\n\t\t\t\t\treturn [\n\t\t\t\t\t\tpoint.id,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...point,\n\t\t\t\t\t\t\tx: lerp(point.x, endPoint.x, t),\n\t\t\t\t\t\t\ty: lerp(point.y, endPoint.y, t),\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction linePointsToArray(shape: TLLineShape) {\n\treturn Object.values(shape.props.points).sort(sortByIndex)\n}\n\nconst pathCache = new WeakCache<TLLineShape, PathBuilder>()\nfunction getPathForLineShape(shape: TLLineShape): PathBuilder {\n\treturn pathCache.get(shape, () => {\n\t\tconst points = linePointsToArray(shape).map(Vec.From)\n\n\t\tswitch (shape.props.spline) {\n\t\t\tcase 'cubic': {\n\t\t\t\treturn PathBuilder.cubicSplineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t\tcase 'line': {\n\t\t\t\treturn PathBuilder.lineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunction LineShapeSvg({\n\tshape,\n\tshouldScale = false,\n\tforceSolid = false,\n}: {\n\tshape: TLLineShape\n\tshouldScale?: boolean\n\tforceSolid?: boolean\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst path = getPathForLineShape(shape)\n\tconst { dash, color, size } = shape.props\n\n\tconst scaleFactor = 1 / shape.props.scale\n\n\tconst scale = shouldScale ? scaleFactor : 1\n\n\tconst strokeWidth = STROKE_SIZES[size] * shape.props.scale\n\n\treturn path.toSvg({\n\t\tstyle: dash,\n\t\tstrokeWidth,\n\t\tforceSolid,\n\t\trandomSeed: shape.id,\n\t\tprops: { transform: `scale(${scale})`, stroke: theme[color].solid, fill: 'none' },\n\t})\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["import {\n\tGroup2d,\n\tHandleSnapGeometry,\n\tSVGContainer,\n\tShapeUtil,\n\tTLHandle,\n\tTLHandleDragInfo,\n\tTLLineShape,\n\tTLLineShapePoint,\n\tTLResizeInfo,\n\tVec,\n\tWeakCache,\n\tZERO_INDEX_KEY,\n\tassert,\n\tgetColorValue,\n\tgetIndexAbove,\n\tgetIndexBetween,\n\tgetIndices,\n\tlerp,\n\tlineShapeMigrations,\n\tlineShapeProps,\n\tmapObjectMapValues,\n\tmaybeSnapToGrid,\n\tsortByIndex,\n} from '@tldraw/editor'\n\nimport { STROKE_SIZES } from '../arrow/shared'\nimport { PathBuilder, PathBuilderGeometry2d } from '../shared/PathBuilder'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\nconst handlesCache = new WeakCache<TLLineShape['props'], TLHandle[]>()\n\n/** @public */\nexport class LineShapeUtil extends ShapeUtil<TLLineShape> {\n\tstatic override type = 'line' as const\n\tstatic override props = lineShapeProps\n\tstatic override migrations = lineShapeMigrations\n\n\toverride hideResizeHandles() {\n\t\treturn true\n\t}\n\toverride hideRotateHandle() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsFg() {\n\t\treturn true\n\t}\n\toverride hideSelectionBoundsBg() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLLineShape['props'] {\n\t\tconst [start, end] = getIndices(2)\n\t\treturn {\n\t\t\tdash: 'draw',\n\t\t\tsize: 'm',\n\t\t\tcolor: 'black',\n\t\t\tspline: 'line',\n\t\t\tpoints: {\n\t\t\t\t[start]: { id: start, index: start, x: 0, y: 0 },\n\t\t\t\t[end]: { id: end, index: end, x: 0.1, y: 0.1 },\n\t\t\t},\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLLineShape) {\n\t\t// todo: should we have min size?\n\t\tconst geometry = getPathForLineShape(shape).toGeometry()\n\t\tassert(geometry instanceof PathBuilderGeometry2d)\n\t\treturn geometry\n\t}\n\n\toverride getHandles(shape: TLLineShape) {\n\t\treturn handlesCache.get(shape.props, () => {\n\t\t\tconst spline = this.getGeometry(shape)\n\n\t\t\tconst points = linePointsToArray(shape)\n\t\t\tconst results: TLHandle[] = points.map((point) => ({\n\t\t\t\t...point,\n\t\t\t\tid: point.index,\n\t\t\t\ttype: 'vertex',\n\t\t\t\tcanSnap: true,\n\t\t\t}))\n\n\t\t\tfor (let i = 0; i < points.length - 1; i++) {\n\t\t\t\tconst index = getIndexBetween(points[i].index, points[i + 1].index)\n\t\t\t\tconst segment = spline.getSegments()[i]\n\t\t\t\tconst point = segment.interpolateAlongEdge(0.5)\n\t\t\t\tresults.push({\n\t\t\t\t\tid: index,\n\t\t\t\t\ttype: 'create',\n\t\t\t\t\tindex,\n\t\t\t\t\tx: point.x,\n\t\t\t\t\ty: point.y,\n\t\t\t\t\tcanSnap: true,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn results.sort(sortByIndex)\n\t\t})\n\t}\n\n\t// Events\n\n\toverride onResize(shape: TLLineShape, info: TLResizeInfo<TLLineShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tpoints: mapObjectMapValues(shape.props.points, (_, { id, index, x, y }) => ({\n\t\t\t\t\tid,\n\t\t\t\t\tindex,\n\t\t\t\t\tx: x * scaleX,\n\t\t\t\t\ty: y * scaleY,\n\t\t\t\t})),\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(next: TLLineShape): void | TLLineShape {\n\t\tconst {\n\t\t\tprops: { points },\n\t\t} = next\n\t\tconst pointKeys = Object.keys(points)\n\n\t\tif (pointKeys.length < 2) {\n\t\t\treturn\n\t\t}\n\n\t\tconst firstPoint = points[pointKeys[0]]\n\t\tconst allSame = pointKeys.every((key) => {\n\t\t\tconst point = points[key]\n\t\t\treturn point.x === firstPoint.x && point.y === firstPoint.y\n\t\t})\n\t\tif (allSame) {\n\t\t\tconst lastKey = pointKeys[pointKeys.length - 1]\n\t\t\tpoints[lastKey] = {\n\t\t\t\t...points[lastKey],\n\t\t\t\tx: points[lastKey].x + 0.1,\n\t\t\t\ty: points[lastKey].y + 0.1,\n\t\t\t}\n\t\t\treturn next\n\t\t}\n\t\treturn\n\t}\n\n\toverride onHandleDrag(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\tconst newPoint = maybeSnapToGrid(new Vec(handle.x, handle.y), this.editor)\n\t\treturn {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tpoints: {\n\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t[handle.id]: { id: handle.id, index: handle.index, x: newPoint.x, y: newPoint.y },\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onHandleDragStart(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {\n\t\t// For line shapes, if we're dragging a \"create\" handle, then\n\t\t// create a new vertex handle at that point; and make this handle\n\t\t// the handle that we're dragging.\n\t\tif (handle.type === 'create') {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tpoints: {\n\t\t\t\t\t\t...shape.props.points,\n\t\t\t\t\t\t[handle.index]: { id: handle.index, index: handle.index, x: handle.x, y: handle.y },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\n\tcomponent(shape: TLLineShape) {\n\t\treturn (\n\t\t\t<SVGContainer style={{ minWidth: 50, minHeight: 50 }}>\n\t\t\t\t<LineShapeSvg shape={shape} />\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLLineShape) {\n\t\tconst strokeWidth = STROKE_SIZES[shape.props.size] * shape.props.scale\n\t\tconst path = getPathForLineShape(shape)\n\t\tconst { dash } = shape.props\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLLineShape) {\n\t\treturn <LineShapeSvg shouldScale shape={shape} />\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLLineShape): HandleSnapGeometry {\n\t\tconst points = linePointsToArray(shape)\n\t\treturn {\n\t\t\tpoints,\n\t\t\tgetSelfSnapPoints: (handle) => {\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// We want to skip the current and adjacent handles\n\t\t\t\treturn points.filter((_, i) => Math.abs(i - index) > 1).map(Vec.From)\n\t\t\t},\n\t\t\tgetSelfSnapOutline: (handle) => {\n\t\t\t\t// We want to skip the segments that include the handle, so\n\t\t\t\t// find the index of the handle that shares the same index property\n\t\t\t\t// as the initial dragging handle; this catches a quirk of create handles\n\t\t\t\tconst index = this.getHandles(shape)\n\t\t\t\t\t.filter((h) => h.type === 'vertex')\n\t\t\t\t\t.findIndex((h) => h.id === handle.id)!\n\n\t\t\t\t// Get all the outline segments from the shape that don't include the handle\n\t\t\t\tconst segments = this.getGeometry(shape)\n\t\t\t\t\t.getSegments()\n\t\t\t\t\t.filter((_, i) => i !== index - 1 && i !== index)\n\n\t\t\t\tif (!segments.length) return null\n\t\t\t\treturn new Group2d({ children: segments })\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLLineShape,\n\t\tendShape: TLLineShape,\n\t\tt: number\n\t): TLLineShape['props'] {\n\t\tconst startPoints = linePointsToArray(startShape)\n\t\tconst endPoints = linePointsToArray(endShape)\n\n\t\tconst pointsToUseStart: TLLineShapePoint[] = []\n\t\tconst pointsToUseEnd: TLLineShapePoint[] = []\n\n\t\tlet index = ZERO_INDEX_KEY\n\n\t\tif (startPoints.length > endPoints.length) {\n\t\t\t// we'll need to expand points\n\t\t\tfor (let i = 0; i < startPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = { ...startPoints[i] }\n\t\t\t\tif (endPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[endPoints.length - 1], id: index }\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else if (endPoints.length > startPoints.length) {\n\t\t\t// we'll need to converge points\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseEnd[i] = { ...endPoints[i] }\n\t\t\t\tif (startPoints[i] === undefined) {\n\t\t\t\t\tpointsToUseStart[i] = {\n\t\t\t\t\t\t...startPoints[startPoints.length - 1],\n\t\t\t\t\t\tid: index,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpointsToUseStart[i] = { ...startPoints[i], id: index }\n\t\t\t\t}\n\t\t\t\tindex = getIndexAbove(index)\n\t\t\t}\n\t\t} else {\n\t\t\t// noop, easy\n\t\t\tfor (let i = 0; i < endPoints.length; i++) {\n\t\t\t\tpointsToUseStart[i] = startPoints[i]\n\t\t\t\tpointsToUseEnd[i] = endPoints[i]\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tpoints: Object.fromEntries(\n\t\t\t\tpointsToUseStart.map((point, i) => {\n\t\t\t\t\tconst endPoint = pointsToUseEnd[i]\n\t\t\t\t\treturn [\n\t\t\t\t\t\tpoint.id,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...point,\n\t\t\t\t\t\t\tx: lerp(point.x, endPoint.x, t),\n\t\t\t\t\t\t\ty: lerp(point.y, endPoint.y, t),\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction linePointsToArray(shape: TLLineShape) {\n\treturn Object.values(shape.props.points).sort(sortByIndex)\n}\n\nconst pathCache = new WeakCache<TLLineShape, PathBuilder>()\nfunction getPathForLineShape(shape: TLLineShape): PathBuilder {\n\treturn pathCache.get(shape, () => {\n\t\tconst points = linePointsToArray(shape).map(Vec.From)\n\n\t\tswitch (shape.props.spline) {\n\t\t\tcase 'cubic': {\n\t\t\t\treturn PathBuilder.cubicSplineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t\tcase 'line': {\n\t\t\t\treturn PathBuilder.lineThroughPoints(points, { endOffsets: 0 })\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunction LineShapeSvg({\n\tshape,\n\tshouldScale = false,\n\tforceSolid = false,\n}: {\n\tshape: TLLineShape\n\tshouldScale?: boolean\n\tforceSolid?: boolean\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst path = getPathForLineShape(shape)\n\tconst { dash, color, size } = shape.props\n\n\tconst scaleFactor = 1 / shape.props.scale\n\n\tconst scale = shouldScale ? scaleFactor : 1\n\n\tconst strokeWidth = STROKE_SIZES[size] * shape.props.scale\n\n\treturn path.toSvg({\n\t\tstyle: dash,\n\t\tstrokeWidth,\n\t\tforceSolid,\n\t\trandomSeed: shape.id,\n\t\tprops: {\n\t\t\ttransform: `scale(${scale})`,\n\t\t\tstroke: getColorValue(theme, color, 'solid'),\n\t\t\tfill: 'none',\n\t\t},\n\t})\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -220,7 +220,7 @@ class NoteShapeUtil extends import_editor.ShapeUtil {
|
|
|
220
220
|
style: {
|
|
221
221
|
width: nw,
|
|
222
222
|
height: nh,
|
|
223
|
-
backgroundColor: theme
|
|
223
|
+
backgroundColor: (0, import_editor.getColorValue)(theme, color, "noteFill"),
|
|
224
224
|
borderBottom: hideShadows ? isDarkMode ? `${2 * scale}px solid rgb(20, 20, 20)` : `${2 * scale}px solid rgb(144, 144, 144)` : "none",
|
|
225
225
|
boxShadow: hideShadows ? "none" : getNoteShadow(shape.id, rotation, scale)
|
|
226
226
|
},
|
|
@@ -236,7 +236,7 @@ class NoteShapeUtil extends import_editor.ShapeUtil {
|
|
|
236
236
|
verticalAlign,
|
|
237
237
|
richText,
|
|
238
238
|
isSelected,
|
|
239
|
-
labelColor: labelColor === "black" ? theme
|
|
239
|
+
labelColor: labelColor === "black" ? (0, import_editor.getColorValue)(theme, color, "noteText") : (0, import_editor.getColorValue)(theme, labelColor, "fill"),
|
|
240
240
|
wrap: true,
|
|
241
241
|
padding: import_default_shape_constants.LABEL_PADDING * scale,
|
|
242
242
|
hasCustomTabBehavior: true,
|
|
@@ -270,7 +270,7 @@ class NoteShapeUtil extends import_editor.ShapeUtil {
|
|
|
270
270
|
align: shape.props.align,
|
|
271
271
|
verticalAlign: shape.props.verticalAlign,
|
|
272
272
|
richText: shape.props.richText,
|
|
273
|
-
labelColor: theme
|
|
273
|
+
labelColor: (0, import_editor.getColorValue)(theme, shape.props.color, "noteText"),
|
|
274
274
|
bounds,
|
|
275
275
|
padding: import_default_shape_constants.LABEL_PADDING,
|
|
276
276
|
showTextOutline: false
|
|
@@ -284,7 +284,7 @@ class NoteShapeUtil extends import_editor.ShapeUtil {
|
|
|
284
284
|
rx: 1,
|
|
285
285
|
width: import_noteHelpers.NOTE_SIZE,
|
|
286
286
|
height: bounds.h,
|
|
287
|
-
fill: theme
|
|
287
|
+
fill: (0, import_editor.getColorValue)(theme, shape.props.color, "noteFill")
|
|
288
288
|
}
|
|
289
289
|
),
|
|
290
290
|
textLabel
|