tldraw 5.2.0-next.e2b8d10bf10e → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCS.md +20294 -0
- package/README.md +13 -1
- package/RELEASE_NOTES.md +2908 -0
- package/dist-cjs/index.d.ts +110 -23
- package/dist-cjs/index.js +3 -3
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawImage.js +0 -1
- package/dist-cjs/lib/TldrawImage.js.map +2 -2
- package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js +2 -1
- package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
- package/dist-cjs/lib/defaultEmbedDefinitions.js +3 -2
- package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
- package/dist-cjs/lib/defaultOverlayUtils.js +11 -11
- package/dist-cjs/lib/defaultOverlayUtils.js.map +2 -2
- package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js +76 -64
- package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js.map +2 -2
- package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js +1 -1
- package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js.map +2 -2
- package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js +107 -0
- package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +12 -3
- package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js +54 -6
- package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/getPath.js +1 -1
- package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +45 -47
- package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/FrameShapeTool.js +23 -18
- package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +11 -7
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -11
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +5 -1
- package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +31 -41
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/noteHelpers.js +1 -1
- package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
- package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +28 -6
- package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +3 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js +3 -3
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js +17 -3
- package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/core.js +424 -0
- package/dist-cjs/lib/shapes/shared/freehand/core.js.map +7 -0
- package/dist-cjs/lib/shapes/shared/freehand/fmt.js +106 -0
- package/dist-cjs/lib/shapes/shared/freehand/fmt.js.map +7 -0
- package/dist-cjs/lib/shapes/shared/freehand/getStroke.js +6 -6
- package/dist-cjs/lib/shapes/shared/freehand/getStroke.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js +320 -86
- package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js.map +3 -3
- package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js +20 -96
- package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js.map +3 -3
- package/dist-cjs/lib/shapes/shared/freehand/svg.js +55 -19
- package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/svgInk.js +189 -97
- package/dist-cjs/lib/shapes/shared/freehand/svgInk.js.map +3 -3
- package/dist-cjs/lib/shapes/shared/freehand/types.js.map +1 -1
- package/dist-cjs/lib/shapes/shared/interpolate-props.js +6 -2
- package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
- package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +3 -0
- package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/HandTool.js +16 -6
- package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +10 -1
- package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
- package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js +84 -0
- package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js.map +7 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +12 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +4 -0
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +107 -46
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +4 -3
- package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
- package/dist-cjs/lib/ui/components/A11y.js +2 -0
- package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +14 -1
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js +0 -6
- package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +2 -2
- package/dist-cjs/lib/ui/components/Dialogs.js +17 -37
- package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
- package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js +19 -4
- package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +12 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +47 -70
- package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +25 -46
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js +1 -1
- package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +1 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/menu-items.js +7 -0
- package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js +2 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +14 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +2 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +0 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js +1 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +70 -1
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/asset-urls.js +5 -8
- package/dist-cjs/lib/ui/context/asset-urls.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +13 -0
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
- package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +2 -0
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-cjs/lib/utils/embeds/embeds.js +4 -4
- package/dist-cjs/lib/utils/embeds/embeds.js.map +2 -2
- package/dist-cjs/lib/utils/test-helpers.js +2 -2
- package/dist-cjs/lib/utils/test-helpers.js.map +2 -2
- package/dist-cjs/lib/utils/text/richText.js +3 -1
- package/dist-cjs/lib/utils/text/richText.js.map +2 -2
- package/dist-esm/index.d.mts +110 -23
- package/dist-esm/index.mjs +5 -3
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawImage.mjs +0 -1
- package/dist-esm/lib/TldrawImage.mjs.map +2 -2
- package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs +2 -1
- package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
- package/dist-esm/lib/defaultEmbedDefinitions.mjs +3 -2
- package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
- package/dist-esm/lib/defaultOverlayUtils.mjs +11 -11
- package/dist-esm/lib/defaultOverlayUtils.mjs.map +2 -2
- package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs +77 -65
- package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs.map +2 -2
- package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs +1 -1
- package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs.map +2 -2
- package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs +87 -0
- package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +9 -1
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +15 -3
- package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +54 -6
- package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -1
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/getPath.mjs +1 -1
- package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +46 -47
- package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs +23 -18
- package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +4 -0
- package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +12 -7
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -11
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +6 -1
- package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +32 -42
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/noteHelpers.mjs +1 -1
- package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +29 -6
- package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +3 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +4 -3
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs +17 -3
- package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/core.mjs +404 -0
- package/dist-esm/lib/shapes/shared/freehand/core.mjs.map +7 -0
- package/dist-esm/lib/shapes/shared/freehand/fmt.mjs +86 -0
- package/dist-esm/lib/shapes/shared/freehand/fmt.mjs.map +7 -0
- package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs +7 -7
- package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs +332 -86
- package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs.map +3 -3
- package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs +31 -96
- package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs.map +3 -3
- package/dist-esm/lib/shapes/shared/freehand/svg.mjs +55 -19
- package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs +214 -99
- package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs.map +3 -3
- package/dist-esm/lib/shapes/shared/interpolate-props.mjs +6 -2
- package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +4 -0
- package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/HandTool.mjs +16 -6
- package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +10 -1
- package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
- package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs +64 -0
- package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs.map +7 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +12 -0
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +4 -0
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +108 -46
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/ui/TldrawUi.mjs +4 -3
- package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
- package/dist-esm/lib/ui/components/A11y.mjs +2 -0
- package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +21 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs +0 -6
- package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Dialogs.mjs +19 -39
- package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
- package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs +20 -5
- package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +12 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +47 -70
- package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +25 -46
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs +1 -1
- package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +1 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/menu-items.mjs +7 -0
- package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs +2 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +14 -3
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +2 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +2 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +0 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs +1 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +71 -1
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/asset-urls.mjs +5 -8
- package/dist-esm/lib/ui/context/asset-urls.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +13 -0
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
- package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +2 -0
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/dist-esm/lib/utils/embeds/embeds.mjs +4 -4
- package/dist-esm/lib/utils/embeds/embeds.mjs.map +2 -2
- package/dist-esm/lib/utils/test-helpers.mjs +2 -2
- package/dist-esm/lib/utils/test-helpers.mjs.map +2 -2
- package/dist-esm/lib/utils/text/richText.mjs +3 -1
- package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
- package/package.json +11 -6
- package/src/index.ts +6 -1
- package/src/lib/TldrawImage.tsx +2 -2
- package/src/lib/bindings/arrow/ArrowBindingUtil.ts +5 -1
- package/src/lib/defaultEmbedDefinitions.ts +28 -6
- package/src/lib/defaultOverlayUtils.ts +11 -11
- package/src/lib/overlays/SelectionForegroundOverlayUtil.ts +91 -72
- package/src/lib/overlays/ShapeHandleOverlayUtil.ts +3 -1
- package/src/lib/overlays/ShapeIndicatorOverlayUtil.ts +133 -0
- package/src/lib/shapes/arrow/toolStates/Pointing.tsx +11 -1
- package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +16 -3
- package/src/lib/shapes/bookmark/bookmarks.ts +105 -15
- package/src/lib/shapes/draw/DrawShapeUtil.tsx +7 -5
- package/src/lib/shapes/draw/getPath.ts +1 -1
- package/src/lib/shapes/draw/toolStates/Drawing.ts +55 -48
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +14 -4
- package/src/lib/shapes/frame/FrameShapeTool.ts +35 -24
- package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +46 -0
- package/src/lib/shapes/geo/GeoShapeUtil.tsx +2 -1
- package/src/lib/shapes/geo/toolStates/Pointing.ts +5 -0
- package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +14 -11
- package/src/lib/shapes/image/ImageShapeUtil.tsx +7 -11
- package/src/lib/shapes/line/LineShapeTool.test.ts +41 -0
- package/src/lib/shapes/line/toolStates/Pointing.ts +12 -2
- package/src/lib/shapes/note/NoteShapeUtil.tsx +36 -51
- package/src/lib/shapes/note/noteCloning.test.ts +5 -5
- package/src/lib/shapes/note/noteHelpers.ts +1 -1
- package/src/lib/shapes/note/toolStates/Pointing.ts +40 -7
- package/src/lib/shapes/shared/PlainTextLabel.tsx +3 -3
- package/src/lib/shapes/shared/RichTextLabel.tsx +4 -3
- package/src/lib/shapes/shared/defaultStyleDefs.tsx +25 -3
- package/src/lib/shapes/shared/freehand/core.ts +547 -0
- package/src/lib/shapes/shared/freehand/fmt.ts +106 -0
- package/src/lib/shapes/shared/freehand/getStroke.ts +7 -7
- package/src/lib/shapes/shared/freehand/getStrokeOutlinePoints.ts +451 -139
- package/src/lib/shapes/shared/freehand/getStrokePoints.ts +33 -153
- package/src/lib/shapes/shared/freehand/svg.ts +72 -23
- package/src/lib/shapes/shared/freehand/svgInk.ts +281 -136
- package/src/lib/shapes/shared/freehand/types.ts +0 -1
- package/src/lib/shapes/shared/interpolate-props.ts +6 -2
- package/src/lib/shapes/text/toolStates/Pointing.ts +5 -0
- package/src/lib/tools/HandTool/HandTool.ts +19 -6
- package/src/lib/tools/HandTool/childStates/Dragging.ts +17 -1
- package/src/lib/tools/HandTool/childStates/OneFingerZooming.ts +79 -0
- package/src/lib/tools/SelectTool/childStates/Idle.ts +16 -2
- package/src/lib/tools/SelectTool/childStates/PointingShape.ts +8 -0
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +137 -49
- package/src/lib/ui/TldrawUi.tsx +3 -3
- package/src/lib/ui/components/A11y.tsx +2 -0
- package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +32 -2
- package/src/lib/ui/components/ContextMenu/DefaultContextMenuContent.tsx +5 -6
- package/src/lib/ui/components/DefaultFollowingIndicator.tsx +2 -2
- package/src/lib/ui/components/Dialogs.tsx +20 -23
- package/src/lib/ui/components/HelperButtons/BackToContent.tsx +32 -4
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +10 -0
- package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +60 -74
- package/src/lib/ui/components/Minimap/MinimapManager.ts +35 -57
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.tsx +2 -2
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuContent.tsx +2 -1
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.tsx +2 -1
- package/src/lib/ui/components/SharePanel/DefaultPeopleMenuItem.tsx +3 -3
- package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +5 -0
- package/src/lib/ui/components/menu-items.tsx +9 -0
- package/src/lib/ui/components/primitives/TldrawUiDropdownMenu.tsx +3 -1
- package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +15 -3
- package/src/lib/ui/components/primitives/TldrawUiInput.tsx +4 -0
- package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +7 -0
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +0 -2
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.tsx +0 -1
- package/src/lib/ui/context/actions.tsx +88 -1
- package/src/lib/ui/context/asset-urls.tsx +9 -8
- package/src/lib/ui/context/events.tsx +2 -0
- package/src/lib/ui/hooks/useKeyboardShortcuts.ts +45 -7
- package/src/lib/ui/hooks/useTools.tsx +7 -1
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +20 -9
- package/src/lib/utils/embeds/embeds.test.ts +14 -12
- package/src/lib/utils/embeds/embeds.ts +10 -4
- package/src/lib/utils/test-helpers.ts +3 -3
- package/src/lib/utils/text/richText.test.ts +36 -0
- package/src/lib/utils/text/richText.ts +9 -1
- package/src/test/HandTool.test.ts +93 -0
- package/src/test/ImageShapeUtil.test.ts +88 -0
- package/src/test/SelectTool.test.ts +102 -1
- package/src/test/__snapshots__/drawing.test.ts.snap +2 -1
- package/src/test/attribution.test.ts +40 -29
- package/src/test/bookmark-shapes.test.ts +256 -28
- package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +2 -2
- package/src/test/commands/clipboardCallbacks.test.ts +3 -1
- package/src/test/commands/getSvgString.test.ts +30 -0
- package/src/test/commands/penmode.test.ts +97 -1
- package/src/test/commands/setCamera.test.ts +12 -0
- package/src/test/dragFromToolbar.test.ts +67 -0
- package/src/test/drawing.test.ts +48 -7
- package/src/test/frames.test.ts +72 -0
- package/src/test/freehand/corpus/presets.ts +71 -0
- package/src/test/freehand/corpus/real.ts +370 -0
- package/src/test/freehand/corpus/strokes.ts +50 -0
- package/src/test/freehand/svg.test.ts +20 -0
- package/src/test/freehand/wellformed.test.ts +30 -0
- package/src/test/long-press-create.test.ts +102 -0
- package/src/test/overlays/CollaboratorBrushOverlayUtil.test.ts +4 -4
- package/src/test/overlays/CollaboratorCursorOverlayUtil.test.ts +18 -18
- package/src/test/overlays/CollaboratorHintOverlayUtil.test.ts +7 -7
- package/src/test/overlays/CollaboratorScribbleOverlayUtil.test.ts +3 -3
- package/src/test/overlays/OverlayManager.test.ts +1 -1
- package/src/test/overlays/SelectionForegroundOverlayUtil.test.ts +58 -0
- package/src/test/overlays/ShapeHandleOverlayUtil.test.ts +2 -2
- package/src/test/overlays/ShapeIndicatorOverlayUtil.test.ts +36 -0
- package/src/test/resizing.test.ts +250 -0
- package/src/test/right-click-context-menu.test.ts +90 -0
- package/src/test/rightClickPanning.test.ts +11 -0
- package/src/test/selection-omnibus.test.ts +15 -2
- package/src/test/spatialIndex.test.ts +132 -0
- package/src/test/translating.test.ts +0 -6
- package/src/test/ui/ContextMenu.test.tsx +146 -3
- package/src/test/ui/Dialogs.test.tsx +256 -0
- package/src/test/ui/copyHoveredStyles.test.tsx +154 -0
- package/src/test/ui/keyboardShortcuts.test.tsx +266 -0
- package/tldraw.css +35 -12
- package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js +0 -100
- package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js.map +0 -7
- package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs +0 -80
- package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs.map +0 -7
- package/src/lib/shapes/shared/freehand/setStrokePointRadii.ts +0 -127
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
const MIN_PRESSURE = 0.025;
|
|
2
|
+
const RATE_OF_PRESSURE_CHANGE = 0.275;
|
|
3
|
+
const easeOutQuad = (t) => t * (2 - t);
|
|
4
|
+
const easeOutCubic = (t) => --t * t * t + 1;
|
|
5
|
+
const { min } = Math;
|
|
6
|
+
let pointCapacity = 256;
|
|
7
|
+
let pointX = new Float64Array(pointCapacity);
|
|
8
|
+
let pointY = new Float64Array(pointCapacity);
|
|
9
|
+
let inputX = new Float64Array(pointCapacity);
|
|
10
|
+
let inputY = new Float64Array(pointCapacity);
|
|
11
|
+
let inputZ = new Float64Array(pointCapacity);
|
|
12
|
+
let pressures = new Float64Array(pointCapacity);
|
|
13
|
+
let distances = new Float64Array(pointCapacity);
|
|
14
|
+
let runningLengths = new Float64Array(pointCapacity);
|
|
15
|
+
let radii = new Float64Array(pointCapacity);
|
|
16
|
+
let pointCount = 0;
|
|
17
|
+
function ensurePointCapacity(n) {
|
|
18
|
+
if (n <= pointCapacity) return;
|
|
19
|
+
while (pointCapacity < n) pointCapacity *= 2;
|
|
20
|
+
pointX = new Float64Array(pointCapacity);
|
|
21
|
+
pointY = new Float64Array(pointCapacity);
|
|
22
|
+
inputX = new Float64Array(pointCapacity);
|
|
23
|
+
inputY = new Float64Array(pointCapacity);
|
|
24
|
+
inputZ = new Float64Array(pointCapacity);
|
|
25
|
+
pressures = new Float64Array(pointCapacity);
|
|
26
|
+
distances = new Float64Array(pointCapacity);
|
|
27
|
+
runningLengths = new Float64Array(pointCapacity);
|
|
28
|
+
radii = new Float64Array(pointCapacity);
|
|
29
|
+
}
|
|
30
|
+
let stageCapacity = 256;
|
|
31
|
+
let stageX = new Float64Array(stageCapacity);
|
|
32
|
+
let stageY = new Float64Array(stageCapacity);
|
|
33
|
+
let stageZ = new Float64Array(stageCapacity);
|
|
34
|
+
function ensureStageCapacity(n) {
|
|
35
|
+
if (n <= stageCapacity) return;
|
|
36
|
+
while (stageCapacity < n) stageCapacity *= 2;
|
|
37
|
+
stageX = new Float64Array(stageCapacity);
|
|
38
|
+
stageY = new Float64Array(stageCapacity);
|
|
39
|
+
stageZ = new Float64Array(stageCapacity);
|
|
40
|
+
}
|
|
41
|
+
function zOf(p, clampZ) {
|
|
42
|
+
const z = p.z === void 0 ? 1 : p.z;
|
|
43
|
+
return clampZ && z < MIN_PRESSURE ? MIN_PRESSURE : z;
|
|
44
|
+
}
|
|
45
|
+
function ingest(rawInputPoints, options = {}) {
|
|
46
|
+
const { streamline = 0.5, size = 16, simulatePressure = false } = options;
|
|
47
|
+
pointCount = 0;
|
|
48
|
+
const rawLen = rawInputPoints.length;
|
|
49
|
+
if (rawLen === 0) return;
|
|
50
|
+
const t = 0.15 + (1 - streamline) * 0.85;
|
|
51
|
+
ensureStageCapacity(rawLen + 8);
|
|
52
|
+
ensurePointCapacity(rawLen + 8);
|
|
53
|
+
const stX = stageX;
|
|
54
|
+
const stY = stageY;
|
|
55
|
+
const stZ = stageZ;
|
|
56
|
+
const minDist2 = (size / 3) ** 2;
|
|
57
|
+
const clampZ = !simulatePressure;
|
|
58
|
+
const first = rawInputPoints[0];
|
|
59
|
+
let firstZ = zOf(first, clampZ);
|
|
60
|
+
let startIdx = 1;
|
|
61
|
+
while (startIdx < rawLen) {
|
|
62
|
+
const pt = rawInputPoints[startIdx];
|
|
63
|
+
const dx = pt.x - first.x;
|
|
64
|
+
const dy = pt.y - first.y;
|
|
65
|
+
if (dx * dx + dy * dy > minDist2) break;
|
|
66
|
+
firstZ = Math.max(firstZ, zOf(pt, clampZ));
|
|
67
|
+
startIdx++;
|
|
68
|
+
}
|
|
69
|
+
stX[0] = first.x;
|
|
70
|
+
stY[0] = first.y;
|
|
71
|
+
stZ[0] = firstZ;
|
|
72
|
+
let m = 1;
|
|
73
|
+
for (let i = startIdx; i < rawLen; i++) {
|
|
74
|
+
const pt = rawInputPoints[i];
|
|
75
|
+
stX[m] = pt.x;
|
|
76
|
+
stY[m] = pt.y;
|
|
77
|
+
stZ[m] = zOf(pt, clampZ);
|
|
78
|
+
m++;
|
|
79
|
+
}
|
|
80
|
+
let pointsRemovedFromNearEnd = 0;
|
|
81
|
+
if (m > 1) {
|
|
82
|
+
const lastX = stX[m - 1];
|
|
83
|
+
const lastY = stY[m - 1];
|
|
84
|
+
let j = m - 2;
|
|
85
|
+
while (j >= 0) {
|
|
86
|
+
const dx = stX[j] - lastX;
|
|
87
|
+
const dy = stY[j] - lastY;
|
|
88
|
+
if (dx * dx + dy * dy > minDist2) break;
|
|
89
|
+
j--;
|
|
90
|
+
pointsRemovedFromNearEnd++;
|
|
91
|
+
}
|
|
92
|
+
if (j < m - 2) {
|
|
93
|
+
stX[j + 1] = lastX;
|
|
94
|
+
stY[j + 1] = lastY;
|
|
95
|
+
stZ[j + 1] = stZ[m - 1];
|
|
96
|
+
m = j + 2;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const isComplete = options.last || !options.simulatePressure || m > 1 && (stX[m - 1] - stX[m - 2]) * (stX[m - 1] - stX[m - 2]) + (stY[m - 1] - stY[m - 2]) * (stY[m - 1] - stY[m - 2]) < size ** 2 || pointsRemovedFromNearEnd > 0;
|
|
100
|
+
if (m === 2 && options.simulatePressure) {
|
|
101
|
+
const x0 = stX[0];
|
|
102
|
+
const y0 = stY[0];
|
|
103
|
+
const z0 = stZ[0];
|
|
104
|
+
const x1 = stX[1];
|
|
105
|
+
const y1 = stY[1];
|
|
106
|
+
const z1 = stZ[1];
|
|
107
|
+
for (let i = 1; i < 5; i++) {
|
|
108
|
+
const u2 = i / 4;
|
|
109
|
+
stX[i] = x0 + (x1 - x0) * u2;
|
|
110
|
+
stY[i] = y0 + (y1 - y0) * u2;
|
|
111
|
+
stZ[i] = (z0 + (z1 - z0)) * i / 4;
|
|
112
|
+
}
|
|
113
|
+
m = 5;
|
|
114
|
+
}
|
|
115
|
+
const ptX = pointX;
|
|
116
|
+
const ptY = pointY;
|
|
117
|
+
const inX = inputX;
|
|
118
|
+
const inY = inputY;
|
|
119
|
+
const inZ = inputZ;
|
|
120
|
+
const press = pressures;
|
|
121
|
+
const dists = distances;
|
|
122
|
+
const runs = runningLengths;
|
|
123
|
+
const rads = radii;
|
|
124
|
+
ptX[0] = stX[0];
|
|
125
|
+
ptY[0] = stY[0];
|
|
126
|
+
inX[0] = stX[0];
|
|
127
|
+
inY[0] = stY[0];
|
|
128
|
+
inZ[0] = stZ[0];
|
|
129
|
+
press[0] = simulatePressure ? 0.5 : stZ[0];
|
|
130
|
+
dists[0] = 0;
|
|
131
|
+
runs[0] = 0;
|
|
132
|
+
rads[0] = 1;
|
|
133
|
+
let count = 1;
|
|
134
|
+
if (isComplete && streamline > 0) {
|
|
135
|
+
stX[m] = stX[m - 1];
|
|
136
|
+
stY[m] = stY[m - 1];
|
|
137
|
+
stZ[m] = stZ[m - 1];
|
|
138
|
+
m++;
|
|
139
|
+
}
|
|
140
|
+
let totalLength = 0;
|
|
141
|
+
let prevX = stX[0];
|
|
142
|
+
let prevY = stY[0];
|
|
143
|
+
const u = 1 - t;
|
|
144
|
+
const isLast = options.last;
|
|
145
|
+
for (let i = 1; i < m; i++) {
|
|
146
|
+
let x, y;
|
|
147
|
+
if (!t || isLast && i === m - 1) {
|
|
148
|
+
x = stX[i];
|
|
149
|
+
y = stY[i];
|
|
150
|
+
} else {
|
|
151
|
+
x = stX[i] + (prevX - stX[i]) * u;
|
|
152
|
+
y = stY[i] + (prevY - stY[i]) * u;
|
|
153
|
+
}
|
|
154
|
+
if (Math.abs(prevX - x) < 1e-4 && Math.abs(prevY - y) < 1e-4) continue;
|
|
155
|
+
const distance = ((y - prevY) ** 2 + (x - prevX) ** 2) ** 0.5;
|
|
156
|
+
totalLength += distance;
|
|
157
|
+
if (i < 4 && totalLength < size) continue;
|
|
158
|
+
ptX[count] = x;
|
|
159
|
+
ptY[count] = y;
|
|
160
|
+
inX[count] = stX[i];
|
|
161
|
+
inY[count] = stY[i];
|
|
162
|
+
inZ[count] = stZ[i];
|
|
163
|
+
press[count] = simulatePressure ? 0.5 : stZ[i];
|
|
164
|
+
dists[count] = distance;
|
|
165
|
+
runs[count] = totalLength;
|
|
166
|
+
rads[count] = 1;
|
|
167
|
+
count++;
|
|
168
|
+
prevX = x;
|
|
169
|
+
prevY = y;
|
|
170
|
+
}
|
|
171
|
+
if (totalLength < 1) {
|
|
172
|
+
let max = 0.5;
|
|
173
|
+
for (let i = 0; i < count; i++) max = Math.max(max, press[i]);
|
|
174
|
+
for (let i = 0; i < count; i++) press[i] = max;
|
|
175
|
+
}
|
|
176
|
+
pointCount = count;
|
|
177
|
+
}
|
|
178
|
+
function resolveTaper(taper, size, totalLength) {
|
|
179
|
+
if (!taper) return 0;
|
|
180
|
+
return taper === true ? Math.max(size, totalLength) : taper;
|
|
181
|
+
}
|
|
182
|
+
function computeRadii(options) {
|
|
183
|
+
const {
|
|
184
|
+
size = 16,
|
|
185
|
+
thinning = 0.5,
|
|
186
|
+
simulatePressure = true,
|
|
187
|
+
easing = (t) => t,
|
|
188
|
+
start = {},
|
|
189
|
+
end = {}
|
|
190
|
+
} = options;
|
|
191
|
+
const { easing: taperStartEase = easeOutQuad } = start;
|
|
192
|
+
const { easing: taperEndEase = easeOutCubic } = end;
|
|
193
|
+
const n = pointCount;
|
|
194
|
+
const press = pressures;
|
|
195
|
+
const dists = distances;
|
|
196
|
+
const runs = runningLengths;
|
|
197
|
+
const rads = radii;
|
|
198
|
+
const totalLength = runs[n - 1];
|
|
199
|
+
if (!simulatePressure && totalLength < size) {
|
|
200
|
+
let max = 0.5;
|
|
201
|
+
for (let i = 0; i < n; i++) max = Math.max(max, press[i]);
|
|
202
|
+
for (let i = 0; i < n; i++) {
|
|
203
|
+
press[i] = max;
|
|
204
|
+
rads[i] = size * easing(0.5 - thinning * (0.5 - max));
|
|
205
|
+
}
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
let prevPressure = press[0];
|
|
209
|
+
for (let i = 0; i < n; i++) {
|
|
210
|
+
if (runs[i] > size * 5) break;
|
|
211
|
+
const sp = min(1, dists[i] / size);
|
|
212
|
+
let p;
|
|
213
|
+
if (simulatePressure) {
|
|
214
|
+
const rp = min(1, 1 - sp);
|
|
215
|
+
p = min(1, prevPressure + (rp - prevPressure) * (sp * RATE_OF_PRESSURE_CHANGE));
|
|
216
|
+
} else {
|
|
217
|
+
p = min(1, prevPressure + (press[i] - prevPressure) * 0.5);
|
|
218
|
+
}
|
|
219
|
+
prevPressure = prevPressure + (p - prevPressure) * 0.5;
|
|
220
|
+
}
|
|
221
|
+
const taperStart = resolveTaper(start.taper, size, totalLength);
|
|
222
|
+
const taperEnd = resolveTaper(end.taper, size, totalLength);
|
|
223
|
+
const hasTaper = taperStart || taperEnd;
|
|
224
|
+
for (let i = 0; i < n; i++) {
|
|
225
|
+
let radius;
|
|
226
|
+
if (thinning) {
|
|
227
|
+
let pressure = press[i];
|
|
228
|
+
const sp = min(1, dists[i] / size);
|
|
229
|
+
if (simulatePressure) {
|
|
230
|
+
const rp = min(1, 1 - sp);
|
|
231
|
+
pressure = min(1, prevPressure + (rp - prevPressure) * (sp * RATE_OF_PRESSURE_CHANGE));
|
|
232
|
+
} else {
|
|
233
|
+
pressure = min(1, prevPressure + (pressure - prevPressure) * (sp * RATE_OF_PRESSURE_CHANGE));
|
|
234
|
+
}
|
|
235
|
+
radius = size * easing(0.5 - thinning * (0.5 - pressure));
|
|
236
|
+
prevPressure = pressure;
|
|
237
|
+
} else {
|
|
238
|
+
radius = size / 2;
|
|
239
|
+
}
|
|
240
|
+
if (hasTaper) {
|
|
241
|
+
const runningLength = runs[i];
|
|
242
|
+
const ts = runningLength < taperStart ? taperStartEase(runningLength / taperStart) : 1;
|
|
243
|
+
const te = totalLength - runningLength < taperEnd ? taperEndEase((totalLength - runningLength) / taperEnd) : 1;
|
|
244
|
+
radius = Math.max(0.01, radius * Math.min(ts, te));
|
|
245
|
+
}
|
|
246
|
+
rads[i] = radius;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
let srcCapacity = 256;
|
|
250
|
+
let srcX = new Float64Array(srcCapacity);
|
|
251
|
+
let srcY = new Float64Array(srcCapacity);
|
|
252
|
+
let srcZ = new Float64Array(srcCapacity);
|
|
253
|
+
let srcInputX = new Float64Array(srcCapacity);
|
|
254
|
+
let srcInputY = new Float64Array(srcCapacity);
|
|
255
|
+
let srcRadius = new Float64Array(srcCapacity);
|
|
256
|
+
let srcRunningLength = new Float64Array(srcCapacity);
|
|
257
|
+
let srcIsCap = new Uint8Array(srcCapacity);
|
|
258
|
+
let srcCount = 0;
|
|
259
|
+
function ensureSrcCapacity(n) {
|
|
260
|
+
if (n <= srcCapacity) return;
|
|
261
|
+
while (srcCapacity < n) srcCapacity *= 2;
|
|
262
|
+
srcX = new Float64Array(srcCapacity);
|
|
263
|
+
srcY = new Float64Array(srcCapacity);
|
|
264
|
+
srcZ = new Float64Array(srcCapacity);
|
|
265
|
+
srcInputX = new Float64Array(srcCapacity);
|
|
266
|
+
srcInputY = new Float64Array(srcCapacity);
|
|
267
|
+
srcRadius = new Float64Array(srcCapacity);
|
|
268
|
+
srcRunningLength = new Float64Array(srcCapacity);
|
|
269
|
+
srcIsCap = new Uint8Array(srcCapacity);
|
|
270
|
+
}
|
|
271
|
+
function loadSrcFromStrokePoints(strokePoints) {
|
|
272
|
+
const n = strokePoints.length;
|
|
273
|
+
ensureSrcCapacity(n);
|
|
274
|
+
const sx = srcX;
|
|
275
|
+
const sy = srcY;
|
|
276
|
+
const sz = srcZ;
|
|
277
|
+
const six = srcInputX;
|
|
278
|
+
const siy = srcInputY;
|
|
279
|
+
const sr = srcRadius;
|
|
280
|
+
const srl = srcRunningLength;
|
|
281
|
+
const scap = srcIsCap;
|
|
282
|
+
const first = strokePoints[0];
|
|
283
|
+
const last = strokePoints[n - 1];
|
|
284
|
+
for (let i = 0; i < n; i++) {
|
|
285
|
+
const sp = strokePoints[i];
|
|
286
|
+
const point = sp.point;
|
|
287
|
+
const input = sp.input;
|
|
288
|
+
sx[i] = point.x;
|
|
289
|
+
sy[i] = point.y;
|
|
290
|
+
sz[i] = point.z;
|
|
291
|
+
six[i] = input.x;
|
|
292
|
+
siy[i] = input.y;
|
|
293
|
+
sr[i] = sp.radius;
|
|
294
|
+
srl[i] = sp.runningLength;
|
|
295
|
+
scap[i] = sp === first || sp === last ? 1 : 0;
|
|
296
|
+
}
|
|
297
|
+
srcCount = n;
|
|
298
|
+
}
|
|
299
|
+
function loadSrcFromPipeline() {
|
|
300
|
+
const n = pointCount;
|
|
301
|
+
ensureSrcCapacity(n);
|
|
302
|
+
const sx = srcX;
|
|
303
|
+
const sy = srcY;
|
|
304
|
+
const sz = srcZ;
|
|
305
|
+
const six = srcInputX;
|
|
306
|
+
const siy = srcInputY;
|
|
307
|
+
const sr = srcRadius;
|
|
308
|
+
const srl = srcRunningLength;
|
|
309
|
+
const scap = srcIsCap;
|
|
310
|
+
const ptX = pointX;
|
|
311
|
+
const ptY = pointY;
|
|
312
|
+
const inX = inputX;
|
|
313
|
+
const inY = inputY;
|
|
314
|
+
const inZ = inputZ;
|
|
315
|
+
const runs = runningLengths;
|
|
316
|
+
const rads = radii;
|
|
317
|
+
for (let i = 0; i < n; i++) {
|
|
318
|
+
sx[i] = ptX[i];
|
|
319
|
+
sy[i] = ptY[i];
|
|
320
|
+
sz[i] = inZ[i];
|
|
321
|
+
six[i] = inX[i];
|
|
322
|
+
siy[i] = inY[i];
|
|
323
|
+
sr[i] = rads[i];
|
|
324
|
+
srl[i] = runs[i];
|
|
325
|
+
scap[i] = i === 0 || i === n - 1 ? 1 : 0;
|
|
326
|
+
}
|
|
327
|
+
srcCount = n;
|
|
328
|
+
}
|
|
329
|
+
function loadSrcPartition(a, aElbow, innerStart, innerEnd, b, bElbow, dupQuirk) {
|
|
330
|
+
ensureSrcCapacity(innerEnd - innerStart + 3);
|
|
331
|
+
const sx = srcX;
|
|
332
|
+
const sy = srcY;
|
|
333
|
+
const sz = srcZ;
|
|
334
|
+
const six = srcInputX;
|
|
335
|
+
const siy = srcInputY;
|
|
336
|
+
const sr = srcRadius;
|
|
337
|
+
const srl = srcRunningLength;
|
|
338
|
+
const scap = srcIsCap;
|
|
339
|
+
const ptX = pointX;
|
|
340
|
+
const ptY = pointY;
|
|
341
|
+
const inX = inputX;
|
|
342
|
+
const inY = inputY;
|
|
343
|
+
const inZ = inputZ;
|
|
344
|
+
const runs = runningLengths;
|
|
345
|
+
const rads = radii;
|
|
346
|
+
sx[0] = aElbow ? inX[a] : ptX[a];
|
|
347
|
+
sy[0] = aElbow ? inY[a] : ptY[a];
|
|
348
|
+
sz[0] = inZ[a];
|
|
349
|
+
six[0] = inX[a];
|
|
350
|
+
siy[0] = inY[a];
|
|
351
|
+
sr[0] = rads[a];
|
|
352
|
+
srl[0] = runs[a];
|
|
353
|
+
scap[0] = 1;
|
|
354
|
+
let w = 1;
|
|
355
|
+
for (let i = innerStart; i <= innerEnd; i++) {
|
|
356
|
+
sx[w] = ptX[i];
|
|
357
|
+
sy[w] = ptY[i];
|
|
358
|
+
sz[w] = inZ[i];
|
|
359
|
+
six[w] = inX[i];
|
|
360
|
+
siy[w] = inY[i];
|
|
361
|
+
sr[w] = rads[i];
|
|
362
|
+
srl[w] = runs[i];
|
|
363
|
+
scap[w] = 0;
|
|
364
|
+
w++;
|
|
365
|
+
}
|
|
366
|
+
if (dupQuirk) scap[w - 1] = 1;
|
|
367
|
+
sx[w] = bElbow ? inX[b] : ptX[b];
|
|
368
|
+
sy[w] = bElbow ? inY[b] : ptY[b];
|
|
369
|
+
sz[w] = inZ[b];
|
|
370
|
+
six[w] = inX[b];
|
|
371
|
+
siy[w] = inY[b];
|
|
372
|
+
sr[w] = rads[b];
|
|
373
|
+
srl[w] = runs[b];
|
|
374
|
+
scap[w] = 1;
|
|
375
|
+
srcCount = w + 1;
|
|
376
|
+
}
|
|
377
|
+
export {
|
|
378
|
+
computeRadii,
|
|
379
|
+
distances,
|
|
380
|
+
ingest,
|
|
381
|
+
inputX,
|
|
382
|
+
inputY,
|
|
383
|
+
inputZ,
|
|
384
|
+
loadSrcFromPipeline,
|
|
385
|
+
loadSrcFromStrokePoints,
|
|
386
|
+
loadSrcPartition,
|
|
387
|
+
pointCount,
|
|
388
|
+
pointX,
|
|
389
|
+
pointY,
|
|
390
|
+
pressures,
|
|
391
|
+
radii,
|
|
392
|
+
resolveTaper,
|
|
393
|
+
runningLengths,
|
|
394
|
+
srcCount,
|
|
395
|
+
srcInputX,
|
|
396
|
+
srcInputY,
|
|
397
|
+
srcIsCap,
|
|
398
|
+
srcRadius,
|
|
399
|
+
srcRunningLength,
|
|
400
|
+
srcX,
|
|
401
|
+
srcY,
|
|
402
|
+
srcZ
|
|
403
|
+
};
|
|
404
|
+
//# sourceMappingURL=core.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/lib/shapes/shared/freehand/core.ts"],
|
|
4
|
+
"sourcesContent": ["import { VecLike } from '@tldraw/editor'\nimport type { StrokeOptions, StrokePoint } from './types'\n\n// The stroke pipeline's internal representation: one module-level set of reusable\n// struct-of-arrays buffers instead of per-point objects. Like fmt.ts's byte buffer, the\n// buffers are non-reentrant: each public entry point fully consumes them before returning,\n// and the next call overwrites them.\n//\n// A stroke point's vector is not stored; it is derived on the fly from consecutive points\n// (the unit vector pointing back at the predecessor). A point's distance is stored rather\n// than derived from running lengths because `runningLength[i] - runningLength[i - 1]` is\n// not bit-identical to the accumulated distance in floating point.\n//\n// Hot loops capture the array bindings into locals: the arrays never grow mid-fill\n// (capacity is ensured up front), and locals avoid re-reading the module binding on\n// every access.\n\nconst MIN_PRESSURE = 0.025\n\n// This is the rate of change for simulated pressure. It could be an option.\nconst RATE_OF_PRESSURE_CHANGE = 0.275\n\n// Default taper easings, mirroring `EASINGS.easeOutQuad` and `EASINGS.easeOutCubic`\n// from `@tldraw/editor`.\nconst easeOutQuad = (t: number) => t * (2 - t)\nconst easeOutCubic = (t: number) => --t * t * t + 1\n\nconst { min } = Math\n\n// ---------------------------------------------------------------------------------\n// Pipeline buffers: one slot per stroke point, filled by `ingest`, radii filled in by\n// `computeRadii`. Callers ensure capacity before filling, so growth never copies.\n// ---------------------------------------------------------------------------------\n\nlet pointCapacity = 256\n/** Streamlined (smoothed) point coordinates. */\nexport let pointX = new Float64Array(pointCapacity)\nexport let pointY = new Float64Array(pointCapacity)\n/** The original input coordinates (used for elbows and sharp corners). */\nexport let inputX = new Float64Array(pointCapacity)\nexport let inputY = new Float64Array(pointCapacity)\n/** The input z (pressure channel) after clamping; kept for materializing StrokePoints. */\nexport let inputZ = new Float64Array(pointCapacity)\nexport let pressures = new Float64Array(pointCapacity)\nexport let distances = new Float64Array(pointCapacity)\nexport let runningLengths = new Float64Array(pointCapacity)\nexport let radii = new Float64Array(pointCapacity)\nexport let pointCount = 0\n\nfunction ensurePointCapacity(n: number) {\n\tif (n <= pointCapacity) return\n\twhile (pointCapacity < n) pointCapacity *= 2\n\tpointX = new Float64Array(pointCapacity)\n\tpointY = new Float64Array(pointCapacity)\n\tinputX = new Float64Array(pointCapacity)\n\tinputY = new Float64Array(pointCapacity)\n\tinputZ = new Float64Array(pointCapacity)\n\tpressures = new Float64Array(pointCapacity)\n\tdistances = new Float64Array(pointCapacity)\n\trunningLengths = new Float64Array(pointCapacity)\n\tradii = new Float64Array(pointCapacity)\n}\n\n// Staging buffers for the effective input sequence in `ingest` (after stripping\n// near-start/near-end points, the two-point interpolation, and the duplicated last\n// point) \u2014 replaces the cloned `pts` array of the object pipeline.\nlet stageCapacity = 256\nlet stageX = new Float64Array(stageCapacity)\nlet stageY = new Float64Array(stageCapacity)\nlet stageZ = new Float64Array(stageCapacity)\n\nfunction ensureStageCapacity(n: number) {\n\tif (n <= stageCapacity) return\n\twhile (stageCapacity < n) stageCapacity *= 2\n\tstageX = new Float64Array(stageCapacity)\n\tstageY = new Float64Array(stageCapacity)\n\tstageZ = new Float64Array(stageCapacity)\n}\n\n/** The z of a raw input point as `Vec.From` plus the pressure clamp would produce it. */\nfunction zOf(p: VecLike, clampZ: boolean): number {\n\tconst z = p.z === undefined ? 1 : p.z\n\t// Some pens or OSes report z=0 even while the pen is touching, so we clamp rather\n\t// than strip to avoid removing real input.\n\treturn clampZ && z < MIN_PRESSURE ? MIN_PRESSURE : z\n}\n\n/**\n * Phase 1: ingest and streamline raw input points straight into the pipeline buffers.\n * Mirrors what getStrokePoints used to do with per-point objects, keeping every\n * order-sensitive step: the pressure clamp, near-start/near-end stripping, the two-point\n * simulated-pressure interpolation, the early-noise skip, and the short-stroke pressure\n * fixup.\n *\n * @internal\n */\nexport function ingest(rawInputPoints: VecLike[], options: StrokeOptions = {}): void {\n\tconst { streamline = 0.5, size = 16, simulatePressure = false } = options\n\n\tpointCount = 0\n\tconst rawLen = rawInputPoints.length\n\tif (rawLen === 0) return\n\n\t// Find the interpolation level between points.\n\tconst t = 0.15 + (1 - streamline) * 0.85\n\n\tensureStageCapacity(rawLen + 8)\n\tensurePointCapacity(rawLen + 8)\n\n\tconst stX = stageX\n\tconst stY = stageY\n\tconst stZ = stageZ\n\n\tconst minDist2 = (size / 3) ** 2\n\tconst clampZ = !simulatePressure\n\n\t// Strip points that are too close to the first point, accumulating the maximum\n\t// pressure among them into the first point.\n\tconst first = rawInputPoints[0]\n\tlet firstZ = zOf(first, clampZ)\n\tlet startIdx = 1\n\twhile (startIdx < rawLen) {\n\t\tconst pt = rawInputPoints[startIdx]\n\t\tconst dx = pt.x - first.x\n\t\tconst dy = pt.y - first.y\n\t\tif (dx * dx + dy * dy > minDist2) break\n\t\tfirstZ = Math.max(firstZ, zOf(pt, clampZ))\n\t\tstartIdx++\n\t}\n\n\t// Stage the surviving points.\n\tstX[0] = first.x\n\tstY[0] = first.y\n\tstZ[0] = firstZ\n\tlet m = 1\n\tfor (let i = startIdx; i < rawLen; i++) {\n\t\tconst pt = rawInputPoints[i]\n\t\tstX[m] = pt.x\n\t\tstY[m] = pt.y\n\t\tstZ[m] = zOf(pt, clampZ)\n\t\tm++\n\t}\n\n\t// Strip points that are too close to the last point. This can consume the whole\n\t// sequence, leaving just the last point.\n\tlet pointsRemovedFromNearEnd = 0\n\tif (m > 1) {\n\t\tconst lastX = stX[m - 1]\n\t\tconst lastY = stY[m - 1]\n\t\tlet j = m - 2\n\t\twhile (j >= 0) {\n\t\t\tconst dx = stX[j] - lastX\n\t\t\tconst dy = stY[j] - lastY\n\t\t\tif (dx * dx + dy * dy > minDist2) break\n\t\t\tj--\n\t\t\tpointsRemovedFromNearEnd++\n\t\t}\n\t\tif (j < m - 2) {\n\t\t\tstX[j + 1] = lastX\n\t\t\tstY[j + 1] = lastY\n\t\t\tstZ[j + 1] = stZ[m - 1]\n\t\t\tm = j + 2\n\t\t}\n\t}\n\n\tconst isComplete =\n\t\toptions.last ||\n\t\t!options.simulatePressure ||\n\t\t(m > 1 &&\n\t\t\t(stX[m - 1] - stX[m - 2]) * (stX[m - 1] - stX[m - 2]) +\n\t\t\t\t(stY[m - 1] - stY[m - 2]) * (stY[m - 1] - stY[m - 2]) <\n\t\t\t\tsize ** 2) ||\n\t\tpointsRemovedFromNearEnd > 0\n\n\t// Add extra points between the two, to help avoid \"dash\" lines for strokes with\n\t// tapered start and ends.\n\tif (m === 2 && options.simulatePressure) {\n\t\tconst x0 = stX[0]\n\t\tconst y0 = stY[0]\n\t\tconst z0 = stZ[0]\n\t\tconst x1 = stX[1]\n\t\tconst y1 = stY[1]\n\t\tconst z1 = stZ[1]\n\t\tfor (let i = 1; i < 5; i++) {\n\t\t\tconst u = i / 4\n\t\t\tstX[i] = x0 + (x1 - x0) * u\n\t\t\tstY[i] = y0 + (y1 - y0) * u\n\t\t\tstZ[i] = ((z0 + (z1 - z0)) * i) / 4\n\t\t}\n\t\tm = 5\n\t}\n\n\tconst ptX = pointX\n\tconst ptY = pointY\n\tconst inX = inputX\n\tconst inY = inputY\n\tconst inZ = inputZ\n\tconst press = pressures\n\tconst dists = distances\n\tconst runs = runningLengths\n\tconst rads = radii\n\n\t// The first point needs no adjustment.\n\tptX[0] = stX[0]\n\tptY[0] = stY[0]\n\tinX[0] = stX[0]\n\tinY[0] = stY[0]\n\tinZ[0] = stZ[0]\n\tpress[0] = simulatePressure ? 0.5 : stZ[0]\n\tdists[0] = 0\n\truns[0] = 0\n\trads[0] = 1\n\tlet count = 1\n\n\tif (isComplete && streamline > 0) {\n\t\tstX[m] = stX[m - 1]\n\t\tstY[m] = stY[m - 1]\n\t\tstZ[m] = stZ[m - 1]\n\t\tm++\n\t}\n\n\t// We use the totalLength to keep track of the total distance, and prevX/prevY as the\n\t// latest streamlined point, to calculate the next point's distance.\n\tlet totalLength = 0\n\tlet prevX = stX[0]\n\tlet prevY = stY[0]\n\tconst u = 1 - t\n\tconst isLast = options.last\n\n\tfor (let i = 1; i < m; i++) {\n\t\tlet x: number, y: number\n\t\tif (!t || (isLast && i === m - 1)) {\n\t\t\tx = stX[i]\n\t\t\ty = stY[i]\n\t\t} else {\n\t\t\tx = stX[i] + (prevX - stX[i]) * u\n\t\t\ty = stY[i] + (prevY - stY[i]) * u\n\t\t}\n\n\t\t// If the new point is the same as the previous point, skip ahead.\n\t\tif (Math.abs(prevX - x) < 0.0001 && Math.abs(prevY - y) < 0.0001) continue\n\n\t\t// How far is the new point from the previous point?\n\t\tconst distance = ((y - prevY) ** 2 + (x - prevX) ** 2) ** 0.5\n\n\t\t// Add this distance to the total \"running length\" of the line.\n\t\ttotalLength += distance\n\n\t\t// At the start of the line, we wait until the new point is a certain distance\n\t\t// away from the original point, to avoid noise.\n\t\tif (i < 4 && totalLength < size) continue\n\n\t\tptX[count] = x\n\t\tptY[count] = y\n\t\tinX[count] = stX[i]\n\t\tinY[count] = stY[i]\n\t\tinZ[count] = stZ[i]\n\t\tpress[count] = simulatePressure ? 0.5 : stZ[i]\n\t\tdists[count] = distance\n\t\truns[count] = totalLength\n\t\trads[count] = 1\n\t\tcount++\n\t\tprevX = x\n\t\tprevY = y\n\t}\n\n\tif (totalLength < 1) {\n\t\tlet max = 0.5\n\t\tfor (let i = 0; i < count; i++) max = Math.max(max, press[i])\n\t\tfor (let i = 0; i < count; i++) press[i] = max\n\t}\n\n\tpointCount = count\n}\n\n/**\n * Resolve a taper option to a distance: `true` tapers over the whole stroke, `false` or\n * `undefined` not at all.\n *\n * @internal\n */\nexport function resolveTaper(\n\ttaper: number | boolean | undefined,\n\tsize: number,\n\ttotalLength: number\n): number {\n\tif (!taper) return 0\n\treturn taper === true ? Math.max(size, totalLength) : taper\n}\n\n/**\n * Phase 2: compute each point's radius from its pressure, distance and running length.\n * Same recurrences as the object pipeline, with the taper pass folded into the main\n * radius loop.\n *\n * @internal\n */\nexport function computeRadii(options: StrokeOptions): void {\n\tconst {\n\t\tsize = 16,\n\t\tthinning = 0.5,\n\t\tsimulatePressure = true,\n\t\teasing = (t) => t,\n\t\tstart = {},\n\t\tend = {},\n\t} = options\n\n\tconst { easing: taperStartEase = easeOutQuad } = start\n\tconst { easing: taperEndEase = easeOutCubic } = end\n\n\tconst n = pointCount\n\tconst press = pressures\n\tconst dists = distances\n\tconst runs = runningLengths\n\tconst rads = radii\n\n\tconst totalLength = runs[n - 1]\n\n\tif (!simulatePressure && totalLength < size) {\n\t\tlet max = 0.5\n\t\tfor (let i = 0; i < n; i++) max = Math.max(max, press[i])\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tpress[i] = max\n\t\t\trads[i] = size * easing(0.5 - thinning * (0.5 - max))\n\t\t}\n\t\treturn\n\t}\n\n\t// Calculate initial pressure based on the average of the first n number of points.\n\t// This prevents \"dots\" at the start of the line. Drawn lines almost always start slow!\n\tlet prevPressure = press[0]\n\tfor (let i = 0; i < n; i++) {\n\t\tif (runs[i] > size * 5) break\n\t\tconst sp = min(1, dists[i] / size)\n\t\tlet p: number\n\t\tif (simulatePressure) {\n\t\t\tconst rp = min(1, 1 - sp)\n\t\t\tp = min(1, prevPressure + (rp - prevPressure) * (sp * RATE_OF_PRESSURE_CHANGE))\n\t\t} else {\n\t\t\tp = min(1, prevPressure + (press[i] - prevPressure) * 0.5)\n\t\t}\n\t\tprevPressure = prevPressure + (p - prevPressure) * 0.5\n\t}\n\n\tconst taperStart = resolveTaper(start.taper, size, totalLength)\n\tconst taperEnd = resolveTaper(end.taper, size, totalLength)\n\n\tconst hasTaper = taperStart || taperEnd\n\n\t// Now calculate pressure and radius for each point. If the point falls within a taper\n\t// distance from either end, scale its radius by the smaller taper strength.\n\tfor (let i = 0; i < n; i++) {\n\t\tlet radius: number\n\t\tif (thinning) {\n\t\t\tlet pressure = press[i]\n\t\t\tconst sp = min(1, dists[i] / size)\n\t\t\tif (simulatePressure) {\n\t\t\t\t// If we're simulating pressure, then do so based on the distance between the\n\t\t\t\t// current point and the previous point, and the size of the stroke.\n\t\t\t\tconst rp = min(1, 1 - sp)\n\t\t\t\tpressure = min(1, prevPressure + (rp - prevPressure) * (sp * RATE_OF_PRESSURE_CHANGE))\n\t\t\t} else {\n\t\t\t\t// Otherwise, use the input pressure slightly smoothed based on the distance\n\t\t\t\t// between the current point and the previous point.\n\t\t\t\tpressure = min(1, prevPressure + (pressure - prevPressure) * (sp * RATE_OF_PRESSURE_CHANGE))\n\t\t\t}\n\t\t\tradius = size * easing(0.5 - thinning * (0.5 - pressure))\n\t\t\tprevPressure = pressure\n\t\t} else {\n\t\t\tradius = size / 2\n\t\t}\n\n\t\tif (hasTaper) {\n\t\t\tconst runningLength = runs[i]\n\t\t\tconst ts = runningLength < taperStart ? taperStartEase(runningLength / taperStart) : 1\n\t\t\tconst te =\n\t\t\t\ttotalLength - runningLength < taperEnd\n\t\t\t\t\t? taperEndEase((totalLength - runningLength) / taperEnd)\n\t\t\t\t\t: 1\n\t\t\tradius = Math.max(0.01, radius * Math.min(ts, te))\n\t\t}\n\n\t\trads[i] = radius\n\t}\n}\n\n// ---------------------------------------------------------------------------------\n// Track-source buffers: the (sub)sequence of stroke points the outline tracks are built\n// from \u2014 the whole stroke for getStroke/getStrokeOutlinePoints, one elbow partition at a\n// time for svgInk. `srcIsCap` marks points to treat as the first/last point when placing\n// the outline (the identity check `point === first || point === last` of the object\n// pipeline). Elbow points are loaded with their input coordinates as their point.\n// ---------------------------------------------------------------------------------\n\nlet srcCapacity = 256\nexport let srcX = new Float64Array(srcCapacity)\nexport let srcY = new Float64Array(srcCapacity)\nexport let srcZ = new Float64Array(srcCapacity)\nexport let srcInputX = new Float64Array(srcCapacity)\nexport let srcInputY = new Float64Array(srcCapacity)\nexport let srcRadius = new Float64Array(srcCapacity)\nexport let srcRunningLength = new Float64Array(srcCapacity)\nexport let srcIsCap = new Uint8Array(srcCapacity)\nexport let srcCount = 0\n\nfunction ensureSrcCapacity(n: number) {\n\tif (n <= srcCapacity) return\n\twhile (srcCapacity < n) srcCapacity *= 2\n\tsrcX = new Float64Array(srcCapacity)\n\tsrcY = new Float64Array(srcCapacity)\n\tsrcZ = new Float64Array(srcCapacity)\n\tsrcInputX = new Float64Array(srcCapacity)\n\tsrcInputY = new Float64Array(srcCapacity)\n\tsrcRadius = new Float64Array(srcCapacity)\n\tsrcRunningLength = new Float64Array(srcCapacity)\n\tsrcIsCap = new Uint8Array(srcCapacity)\n}\n\n/** Load the track source from materialized StrokePoints. @internal */\nexport function loadSrcFromStrokePoints(strokePoints: StrokePoint[]): void {\n\tconst n = strokePoints.length\n\tensureSrcCapacity(n)\n\tconst sx = srcX\n\tconst sy = srcY\n\tconst sz = srcZ\n\tconst six = srcInputX\n\tconst siy = srcInputY\n\tconst sr = srcRadius\n\tconst srl = srcRunningLength\n\tconst scap = srcIsCap\n\tconst first = strokePoints[0]\n\tconst last = strokePoints[n - 1]\n\tfor (let i = 0; i < n; i++) {\n\t\tconst sp = strokePoints[i]\n\t\tconst point = sp.point\n\t\tconst input = sp.input\n\t\tsx[i] = point.x\n\t\tsy[i] = point.y\n\t\tsz[i] = point.z\n\t\tsix[i] = input.x\n\t\tsiy[i] = input.y\n\t\tsr[i] = sp.radius\n\t\tsrl[i] = sp.runningLength\n\t\tscap[i] = sp === first || sp === last ? 1 : 0\n\t}\n\tsrcCount = n\n}\n\n/** Load the track source from the whole pipeline. @internal */\nexport function loadSrcFromPipeline(): void {\n\tconst n = pointCount\n\tensureSrcCapacity(n)\n\tconst sx = srcX\n\tconst sy = srcY\n\tconst sz = srcZ\n\tconst six = srcInputX\n\tconst siy = srcInputY\n\tconst sr = srcRadius\n\tconst srl = srcRunningLength\n\tconst scap = srcIsCap\n\tconst ptX = pointX\n\tconst ptY = pointY\n\tconst inX = inputX\n\tconst inY = inputY\n\tconst inZ = inputZ\n\tconst runs = runningLengths\n\tconst rads = radii\n\tfor (let i = 0; i < n; i++) {\n\t\tsx[i] = ptX[i]\n\t\tsy[i] = ptY[i]\n\t\tsz[i] = inZ[i]\n\t\tsix[i] = inX[i]\n\t\tsiy[i] = inY[i]\n\t\tsr[i] = rads[i]\n\t\tsrl[i] = runs[i]\n\t\tscap[i] = i === 0 || i === n - 1 ? 1 : 0\n\t}\n\tsrcCount = n\n}\n\n/**\n * Load one elbow partition from the pipeline as the track source: boundary point `a`,\n * the surviving inner points `innerStart..innerEnd`, and boundary point `b`. Elbow\n * boundaries read the input coordinates instead of the streamlined ones. When a hard\n * elbow's duplicated end point survived cleanup (`dupQuirk`), the inner copy of `b` is\n * also marked as a cap point, matching the object pipeline where both array slots held\n * the same point object.\n *\n * @internal\n */\nexport function loadSrcPartition(\n\ta: number,\n\taElbow: boolean,\n\tinnerStart: number,\n\tinnerEnd: number,\n\tb: number,\n\tbElbow: boolean,\n\tdupQuirk: boolean\n): void {\n\tensureSrcCapacity(innerEnd - innerStart + 3)\n\tconst sx = srcX\n\tconst sy = srcY\n\tconst sz = srcZ\n\tconst six = srcInputX\n\tconst siy = srcInputY\n\tconst sr = srcRadius\n\tconst srl = srcRunningLength\n\tconst scap = srcIsCap\n\tconst ptX = pointX\n\tconst ptY = pointY\n\tconst inX = inputX\n\tconst inY = inputY\n\tconst inZ = inputZ\n\tconst runs = runningLengths\n\tconst rads = radii\n\n\tsx[0] = aElbow ? inX[a] : ptX[a]\n\tsy[0] = aElbow ? inY[a] : ptY[a]\n\tsz[0] = inZ[a]\n\tsix[0] = inX[a]\n\tsiy[0] = inY[a]\n\tsr[0] = rads[a]\n\tsrl[0] = runs[a]\n\tscap[0] = 1\n\tlet w = 1\n\tfor (let i = innerStart; i <= innerEnd; i++) {\n\t\tsx[w] = ptX[i]\n\t\tsy[w] = ptY[i]\n\t\tsz[w] = inZ[i]\n\t\tsix[w] = inX[i]\n\t\tsiy[w] = inY[i]\n\t\tsr[w] = rads[i]\n\t\tsrl[w] = runs[i]\n\t\tscap[w] = 0\n\t\tw++\n\t}\n\tif (dupQuirk) scap[w - 1] = 1\n\tsx[w] = bElbow ? inX[b] : ptX[b]\n\tsy[w] = bElbow ? inY[b] : ptY[b]\n\tsz[w] = inZ[b]\n\tsix[w] = inX[b]\n\tsiy[w] = inY[b]\n\tsr[w] = rads[b]\n\tsrl[w] = runs[b]\n\tscap[w] = 1\n\tsrcCount = w + 1\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["u"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
let buf = new Uint8Array(65536);
|
|
2
|
+
let pos = 0;
|
|
3
|
+
const decoder = new TextDecoder();
|
|
4
|
+
function ensure(n) {
|
|
5
|
+
if (pos + n > buf.length) {
|
|
6
|
+
const next = new Uint8Array(buf.length * 2);
|
|
7
|
+
next.set(buf);
|
|
8
|
+
buf = next;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function resetPath() {
|
|
12
|
+
pos = 0;
|
|
13
|
+
}
|
|
14
|
+
function writeStr(s) {
|
|
15
|
+
ensure(s.length);
|
|
16
|
+
for (let i = 0; i < s.length; i++) {
|
|
17
|
+
buf[pos++] = s.charCodeAt(i);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function writeC(n) {
|
|
21
|
+
ensure(16);
|
|
22
|
+
if (n < 0) {
|
|
23
|
+
buf[pos++] = 45;
|
|
24
|
+
n = -n;
|
|
25
|
+
}
|
|
26
|
+
const i = n / 100 | 0;
|
|
27
|
+
const f = n - i * 100;
|
|
28
|
+
if (i === 0) {
|
|
29
|
+
if (f === 0) {
|
|
30
|
+
buf[pos++] = 48;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
} else if (i < 10) {
|
|
34
|
+
buf[pos++] = 48 + i;
|
|
35
|
+
} else if (i < 100) {
|
|
36
|
+
buf[pos++] = 48 + (i / 10 | 0);
|
|
37
|
+
buf[pos++] = 48 + i % 10;
|
|
38
|
+
} else {
|
|
39
|
+
const start = pos;
|
|
40
|
+
let m = i;
|
|
41
|
+
while (m > 0) {
|
|
42
|
+
buf[pos++] = 48 + m % 10;
|
|
43
|
+
m = m / 10 | 0;
|
|
44
|
+
}
|
|
45
|
+
let lo = start;
|
|
46
|
+
let hi = pos - 1;
|
|
47
|
+
while (lo < hi) {
|
|
48
|
+
const t = buf[lo];
|
|
49
|
+
buf[lo] = buf[hi];
|
|
50
|
+
buf[hi] = t;
|
|
51
|
+
lo++;
|
|
52
|
+
hi--;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (f !== 0) {
|
|
56
|
+
buf[pos++] = 46;
|
|
57
|
+
const d2 = f % 10;
|
|
58
|
+
buf[pos++] = 48 + (f / 10 | 0);
|
|
59
|
+
if (d2 !== 0) {
|
|
60
|
+
buf[pos++] = 48 + d2;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function writeCPair(nx, ny) {
|
|
65
|
+
writeC(nx);
|
|
66
|
+
buf[pos++] = 44;
|
|
67
|
+
writeC(ny);
|
|
68
|
+
buf[pos++] = 32;
|
|
69
|
+
}
|
|
70
|
+
function finishPath() {
|
|
71
|
+
const s = decoder.decode(buf.subarray(0, pos));
|
|
72
|
+
pos = 0;
|
|
73
|
+
return s;
|
|
74
|
+
}
|
|
75
|
+
function toCenti(v) {
|
|
76
|
+
return Math.round(v * 100);
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
finishPath,
|
|
80
|
+
resetPath,
|
|
81
|
+
toCenti,
|
|
82
|
+
writeC,
|
|
83
|
+
writeCPair,
|
|
84
|
+
writeStr
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=fmt.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/lib/shapes/shared/freehand/fmt.ts"],
|
|
4
|
+
"sourcesContent": ["// Fast SVG path data building.\n//\n// Browsers don't render differences below a hundredth of a pixel, so we emit at most 2 decimal\n// places. Stringifying doubles rounded to 2 decimals is slow (they routinely miss V8's fast\n// float-to-string path), and concatenating many small strings costs more than the math itself.\n// Instead we round every coordinate to an integer number of hundredths (\"centi-pixels\") and\n// write decimal digits straight into a byte buffer, decoding to a string once per path.\n//\n// Paths use relative commands (t/q/a/l) wherever possible: deltas between consecutive points\n// are small numbers, which keeps the path data compact. Because deltas are differences of the\n// rounded integers, they sum back to the rounded absolute positions exactly: no drift.\n\nlet buf = new Uint8Array(65536)\nlet pos = 0\nconst decoder = new TextDecoder()\n\nfunction ensure(n: number) {\n\tif (pos + n > buf.length) {\n\t\tconst next = new Uint8Array(buf.length * 2)\n\t\tnext.set(buf)\n\t\tbuf = next\n\t}\n}\n\n/** Start a new path. Builders must call this before writing. */\nexport function resetPath() {\n\tpos = 0\n}\n\n/** Append a string of ASCII characters (command letters, arc flags) to the path. */\nexport function writeStr(s: string) {\n\tensure(s.length)\n\tfor (let i = 0; i < s.length; i++) {\n\t\tbuf[pos++] = s.charCodeAt(i)\n\t}\n}\n\n/**\n * Append a value given in integer hundredths, e.g. 255 as `2.55`, -30 as `-.3`, 0 as `0`.\n * Assumes |n| < 2^31, which holds for canvas coordinates (|v| < ~21 million px).\n */\nexport function writeC(n: number) {\n\tensure(16)\n\tif (n < 0) {\n\t\tbuf[pos++] = 45 // '-'\n\t\tn = -n\n\t}\n\tconst i = (n / 100) | 0\n\tconst f = n - i * 100\n\tif (i === 0) {\n\t\tif (f === 0) {\n\t\t\tbuf[pos++] = 48 // '0'\n\t\t\treturn\n\t\t}\n\t} else if (i < 10) {\n\t\tbuf[pos++] = 48 + i\n\t} else if (i < 100) {\n\t\tbuf[pos++] = 48 + ((i / 10) | 0)\n\t\tbuf[pos++] = 48 + (i % 10)\n\t} else {\n\t\tconst start = pos\n\t\tlet m = i\n\t\twhile (m > 0) {\n\t\t\tbuf[pos++] = 48 + (m % 10)\n\t\t\tm = (m / 10) | 0\n\t\t}\n\t\t// digits came out least-significant first; reverse them\n\t\tlet lo = start\n\t\tlet hi = pos - 1\n\t\twhile (lo < hi) {\n\t\t\tconst t = buf[lo]\n\t\t\tbuf[lo] = buf[hi]\n\t\t\tbuf[hi] = t\n\t\t\tlo++\n\t\t\thi--\n\t\t}\n\t}\n\tif (f !== 0) {\n\t\tbuf[pos++] = 46 // '.'\n\t\tconst d2 = f % 10\n\t\tbuf[pos++] = 48 + ((f / 10) | 0)\n\t\tif (d2 !== 0) {\n\t\t\tbuf[pos++] = 48 + d2\n\t\t}\n\t}\n}\n\n/** Append a coordinate pair given in integer hundredths as `x,y `. */\nexport function writeCPair(nx: number, ny: number) {\n\twriteC(nx)\n\tbuf[pos++] = 44 // ','\n\twriteC(ny)\n\tbuf[pos++] = 32 // ' '\n}\n\n/** Finish the path: decode everything written since `resetPath` and reset the writer. */\nexport function finishPath(): string {\n\tconst s = decoder.decode(buf.subarray(0, pos))\n\tpos = 0\n\treturn s\n}\n\n/** Round a coordinate to integer hundredths. */\nexport function toCenti(v: number): number {\n\treturn Math.round(v * 100)\n}\n"],
|
|
5
|
+
"mappings": "AAYA,IAAI,MAAM,IAAI,WAAW,KAAK;AAC9B,IAAI,MAAM;AACV,MAAM,UAAU,IAAI,YAAY;AAEhC,SAAS,OAAO,GAAW;AAC1B,MAAI,MAAM,IAAI,IAAI,QAAQ;AACzB,UAAM,OAAO,IAAI,WAAW,IAAI,SAAS,CAAC;AAC1C,SAAK,IAAI,GAAG;AACZ,UAAM;AAAA,EACP;AACD;AAGO,SAAS,YAAY;AAC3B,QAAM;AACP;AAGO,SAAS,SAAS,GAAW;AACnC,SAAO,EAAE,MAAM;AACf,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AAClC,QAAI,KAAK,IAAI,EAAE,WAAW,CAAC;AAAA,EAC5B;AACD;AAMO,SAAS,OAAO,GAAW;AACjC,SAAO,EAAE;AACT,MAAI,IAAI,GAAG;AACV,QAAI,KAAK,IAAI;AACb,QAAI,CAAC;AAAA,EACN;AACA,QAAM,IAAK,IAAI,MAAO;AACtB,QAAM,IAAI,IAAI,IAAI;AAClB,MAAI,MAAM,GAAG;AACZ,QAAI,MAAM,GAAG;AACZ,UAAI,KAAK,IAAI;AACb;AAAA,IACD;AAAA,EACD,WAAW,IAAI,IAAI;AAClB,QAAI,KAAK,IAAI,KAAK;AAAA,EACnB,WAAW,IAAI,KAAK;AACnB,QAAI,KAAK,IAAI,MAAO,IAAI,KAAM;AAC9B,QAAI,KAAK,IAAI,KAAM,IAAI;AAAA,EACxB,OAAO;AACN,UAAM,QAAQ;AACd,QAAI,IAAI;AACR,WAAO,IAAI,GAAG;AACb,UAAI,KAAK,IAAI,KAAM,IAAI;AACvB,UAAK,IAAI,KAAM;AAAA,IAChB;AAEA,QAAI,KAAK;AACT,QAAI,KAAK,MAAM;AACf,WAAO,KAAK,IAAI;AACf,YAAM,IAAI,IAAI,EAAE;AAChB,UAAI,EAAE,IAAI,IAAI,EAAE;AAChB,UAAI,EAAE,IAAI;AACV;AACA;AAAA,IACD;AAAA,EACD;AACA,MAAI,MAAM,GAAG;AACZ,QAAI,KAAK,IAAI;AACb,UAAM,KAAK,IAAI;AACf,QAAI,KAAK,IAAI,MAAO,IAAI,KAAM;AAC9B,QAAI,OAAO,GAAG;AACb,UAAI,KAAK,IAAI,KAAK;AAAA,IACnB;AAAA,EACD;AACD;AAGO,SAAS,WAAW,IAAY,IAAY;AAClD,SAAO,EAAE;AACT,MAAI,KAAK,IAAI;AACb,SAAO,EAAE;AACT,MAAI,KAAK,IAAI;AACd;AAGO,SAAS,aAAqB;AACpC,QAAM,IAAI,QAAQ,OAAO,IAAI,SAAS,GAAG,GAAG,CAAC;AAC7C,QAAM;AACN,SAAO;AACR;AAGO,SAAS,QAAQ,GAAmB;AAC1C,SAAO,KAAK,MAAM,IAAI,GAAG;AAC1B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { setStrokePointRadii } from "./setStrokePointRadii.mjs";
|
|
1
|
+
import { computeRadii, ingest, loadSrcFromPipeline, pointCount } from "./core.mjs";
|
|
2
|
+
import { outlineFromSrc } from "./getStrokeOutlinePoints.mjs";
|
|
4
3
|
function getStroke(points, options = {}) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
);
|
|
4
|
+
ingest(points, options);
|
|
5
|
+
if (pointCount === 0) return [];
|
|
6
|
+
computeRadii(options);
|
|
7
|
+
loadSrcFromPipeline();
|
|
8
|
+
return outlineFromSrc(options);
|
|
9
9
|
}
|
|
10
10
|
export {
|
|
11
11
|
getStroke
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/shapes/shared/freehand/getStroke.ts"],
|
|
4
|
-
"sourcesContent": ["import { Vec, VecLike } from '@tldraw/editor'\nimport {
|
|
5
|
-
"mappings": "AACA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { Vec, VecLike } from '@tldraw/editor'\nimport { computeRadii, ingest, loadSrcFromPipeline, pointCount } from './core'\nimport { outlineFromSrc } from './getStrokeOutlinePoints'\nimport type { StrokeOptions } from './types'\n\n/**\n * ## getStroke\n *\n * Get an array of points describing a polygon that surrounds the input points.\n *\n * @param points - An array of points (as `[x, y, pressure]` or `{x, y, pressure}`). Pressure is\n * optional in both cases.\n * @param options - An object with options.\n * @public\n */\n\nexport function getStroke(points: VecLike[], options: StrokeOptions = {}): Vec[] {\n\tingest(points, options)\n\tif (pointCount === 0) return []\n\tcomputeRadii(options)\n\tloadSrcFromPipeline()\n\treturn outlineFromSrc(options)\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,cAAc,QAAQ,qBAAqB,kBAAkB;AACtE,SAAS,sBAAsB;AAcxB,SAAS,UAAU,QAAmB,UAAyB,CAAC,GAAU;AAChF,SAAO,QAAQ,OAAO;AACtB,MAAI,eAAe,EAAG,QAAO,CAAC;AAC9B,eAAa,OAAO;AACpB,sBAAoB;AACpB,SAAO,eAAe,OAAO;AAC9B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|