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
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
import { Vec } from '@tldraw/editor'
|
|
1
|
+
import { Vec, VecLike } from '@tldraw/editor'
|
|
2
|
+
import {
|
|
3
|
+
loadSrcFromStrokePoints,
|
|
4
|
+
resolveTaper,
|
|
5
|
+
srcCount,
|
|
6
|
+
srcInputX,
|
|
7
|
+
srcInputY,
|
|
8
|
+
srcIsCap,
|
|
9
|
+
srcRadius,
|
|
10
|
+
srcRunningLength,
|
|
11
|
+
srcX,
|
|
12
|
+
srcY,
|
|
13
|
+
srcZ,
|
|
14
|
+
} from './core'
|
|
2
15
|
import type { StrokeOptions, StrokePoint } from './types'
|
|
3
16
|
|
|
4
17
|
const { PI } = Math
|
|
@@ -6,43 +19,188 @@ const { PI } = Math
|
|
|
6
19
|
// Browser strokes seem to be off if PI is regular, a tiny offset seems to fix it
|
|
7
20
|
const FIXED_PI = PI + 0.0001
|
|
8
21
|
|
|
22
|
+
// How far the simplified outline tracks may deviate from the raw tracks, as a fraction of the
|
|
23
|
+
// stroke size. Well below visible thresholds: the parity harness shows sub-0.1px differences at
|
|
24
|
+
// default stroke sizes.
|
|
25
|
+
const TRACK_TOLERANCE_RATIO = 0.05
|
|
26
|
+
|
|
27
|
+
// The maximum number of intermediate points the track simplifier may drop per kept segment.
|
|
28
|
+
const SIMPLIFY_WINDOW = 8
|
|
29
|
+
|
|
30
|
+
// How many steps to take when rounding a corner
|
|
31
|
+
const MIN_ROUNDED_CORNER_STEPS = 8
|
|
32
|
+
const MAX_ROUNDED_CORNER_STEPS = 13
|
|
33
|
+
|
|
34
|
+
// How many steps to take when rounding a corner
|
|
35
|
+
const MIN_CAP_STEPS = 8
|
|
36
|
+
const MAX_CAP_STEPS = 29
|
|
37
|
+
|
|
38
|
+
// Dot product threshold for identifying a hard corner
|
|
39
|
+
const HARD_CORNER_DPR = -0.62
|
|
40
|
+
|
|
41
|
+
// ---------------------------------------------------------------------------------
|
|
42
|
+
// Track buffers: the left and right outline tracks, written by `buildTracks` and read
|
|
43
|
+
// either by svgInk's path writer or materialized into Vecs by the public functions.
|
|
44
|
+
// Reusable and non-reentrant, like the pipeline buffers in core.ts.
|
|
45
|
+
// ---------------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
let trackCapacity = 1024
|
|
48
|
+
export let trackLeftX = new Float64Array(trackCapacity)
|
|
49
|
+
export let trackLeftY = new Float64Array(trackCapacity)
|
|
50
|
+
export let trackRightX = new Float64Array(trackCapacity)
|
|
51
|
+
export let trackRightY = new Float64Array(trackCapacity)
|
|
52
|
+
export let trackLeftCount = 0
|
|
53
|
+
export let trackRightCount = 0
|
|
54
|
+
|
|
55
|
+
// Tracks grow while being written (corners append a variable number of points), so unlike
|
|
56
|
+
// the other buffers a grow here must copy the points written so far.
|
|
57
|
+
function growTracks() {
|
|
58
|
+
trackCapacity *= 2
|
|
59
|
+
const nlx = new Float64Array(trackCapacity)
|
|
60
|
+
nlx.set(trackLeftX)
|
|
61
|
+
trackLeftX = nlx
|
|
62
|
+
const nly = new Float64Array(trackCapacity)
|
|
63
|
+
nly.set(trackLeftY)
|
|
64
|
+
trackLeftY = nly
|
|
65
|
+
const nrx = new Float64Array(trackCapacity)
|
|
66
|
+
nrx.set(trackRightX)
|
|
67
|
+
trackRightX = nrx
|
|
68
|
+
const nry = new Float64Array(trackCapacity)
|
|
69
|
+
nry.set(trackRightY)
|
|
70
|
+
trackRightY = nry
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Drop track points that lie within tolderance (`tol`) of the segment between their kept neighbors.
|
|
75
|
+
* The outline tracks are dense on gentle curves and straight runs where the quadratic smoothing
|
|
76
|
+
* used for rendering needs far fewer points; this keeps the simplified polyline within `tol` of
|
|
77
|
+
* the original one. Works in place: kept points are compacted toward the front of the arrays.
|
|
78
|
+
*
|
|
79
|
+
* @param xs - The x coordinates of the track to simplify
|
|
80
|
+
* @param ys - The y coordinates of the track to simplify
|
|
81
|
+
* @param len - The number of points in the track
|
|
82
|
+
* @param tol - The tolerance
|
|
83
|
+
*
|
|
84
|
+
* @returns The number of points in the simplified track.
|
|
85
|
+
*/
|
|
86
|
+
function simplifyTrack(xs: Float64Array, ys: Float64Array, len: number, tol: number): number {
|
|
87
|
+
if (len <= 2 || tol <= 0) return len
|
|
88
|
+
const tol2 = tol * tol
|
|
89
|
+
let out = 1
|
|
90
|
+
let anchor = 0
|
|
91
|
+
const lastIdx = len - 1
|
|
92
|
+
while (anchor < lastIdx) {
|
|
93
|
+
let best = anchor + 1
|
|
94
|
+
const maxJ = anchor + SIMPLIFY_WINDOW > lastIdx ? lastIdx : anchor + SIMPLIFY_WINDOW
|
|
95
|
+
const ax = xs[anchor]
|
|
96
|
+
const ay = ys[anchor]
|
|
97
|
+
outer: for (let j = anchor + 2; j <= maxJ; j++) {
|
|
98
|
+
const acx = xs[j] - ax
|
|
99
|
+
const acy = ys[j] - ay
|
|
100
|
+
const l2 = acx * acx + acy * acy
|
|
101
|
+
for (let k = anchor + 1; k < j; k++) {
|
|
102
|
+
let t = l2 === 0 ? 0 : ((xs[k] - ax) * acx + (ys[k] - ay) * acy) / l2
|
|
103
|
+
t = t < 0 ? 0 : t > 1 ? 1 : t
|
|
104
|
+
const ex = xs[k] - (ax + acx * t)
|
|
105
|
+
const ey = ys[k] - (ay + acy * t)
|
|
106
|
+
if (ex * ex + ey * ey > tol2) break outer
|
|
107
|
+
}
|
|
108
|
+
best = j
|
|
109
|
+
}
|
|
110
|
+
// Compaction never overtakes the read cursor: the `out`th kept index is always >= out.
|
|
111
|
+
xs[out] = xs[best]
|
|
112
|
+
ys[out] = ys[best]
|
|
113
|
+
out++
|
|
114
|
+
anchor = best
|
|
115
|
+
}
|
|
116
|
+
return out
|
|
117
|
+
}
|
|
118
|
+
|
|
9
119
|
/**
|
|
120
|
+
* Build the left and right outline tracks for the stroke points currently loaded in the
|
|
121
|
+
* track-source buffers, into the track buffers. This is the array core of
|
|
122
|
+
* `getStrokeOutlineTracks`.
|
|
123
|
+
*
|
|
124
|
+
* `hasAnchor`/`anchorX`/`anchorY` carry the original predecessor of point 1 when the
|
|
125
|
+
* caller has cut or altered the sequence in front of it (svgInk's elbow partitions): the
|
|
126
|
+
* second point's vector is derived from the anchor rather than from point 0, preserving
|
|
127
|
+
* the direction it had in the uncut stroke. It only applies when there are more than two
|
|
128
|
+
* points; two-point sequences derive both vectors from each other.
|
|
129
|
+
*
|
|
10
130
|
* @internal
|
|
11
131
|
*/
|
|
12
|
-
export function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
132
|
+
export function buildTracks(
|
|
133
|
+
options: StrokeOptions,
|
|
134
|
+
hasAnchor: boolean,
|
|
135
|
+
anchorX: number,
|
|
136
|
+
anchorY: number
|
|
137
|
+
): void {
|
|
16
138
|
const { size = 16, smoothing = 0.5 } = options
|
|
17
139
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
140
|
+
let lc = 0
|
|
141
|
+
let rc = 0
|
|
142
|
+
trackLeftCount = 0
|
|
143
|
+
trackRightCount = 0
|
|
22
144
|
|
|
23
|
-
const
|
|
24
|
-
|
|
145
|
+
const n = srcCount
|
|
146
|
+
|
|
147
|
+
// We can't do anything with an empty array or a stroke with negative size.
|
|
148
|
+
if (n === 0 || size <= 0) return
|
|
149
|
+
|
|
150
|
+
// Local captures of the source buffers, hoisting the binding reads out of the loop.
|
|
151
|
+
// The track buffers can grow mid-loop, so those are re-captured after growth.
|
|
152
|
+
const sx = srcX
|
|
153
|
+
const sy = srcY
|
|
154
|
+
const six = srcInputX
|
|
155
|
+
const siy = srcInputY
|
|
156
|
+
const sr = srcRadius
|
|
157
|
+
const srl = srcRunningLength
|
|
158
|
+
const scap = srcIsCap
|
|
159
|
+
let lxs = trackLeftX
|
|
160
|
+
let lys = trackLeftY
|
|
161
|
+
let rxs = trackRightX
|
|
162
|
+
let rys = trackRightY
|
|
25
163
|
|
|
26
164
|
// The total length of the line
|
|
27
|
-
const totalLength =
|
|
165
|
+
const totalLength = srl[n - 1]
|
|
28
166
|
|
|
29
167
|
// The minimum allowed distance between points (squared)
|
|
30
168
|
const minDistance = Math.pow(size * smoothing, 2)
|
|
31
169
|
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
170
|
+
// Stroke point vectors are derived on the fly from consecutive points: a point's vector is
|
|
171
|
+
// the unit vector pointing back at its predecessor (matching what getStrokePoints used to
|
|
172
|
+
// store). The first point shares the second point's vector; a lone point keeps the legacy
|
|
173
|
+
// unnormalized (1, 1).
|
|
174
|
+
let curVecX = 1
|
|
175
|
+
let curVecY = 1
|
|
176
|
+
if (n > 1) {
|
|
177
|
+
const dx = sx[0] - sx[1]
|
|
178
|
+
const dy = sy[0] - sy[1]
|
|
179
|
+
const l = (dx * dx + dy * dy) ** 0.5
|
|
180
|
+
if (l === 0) {
|
|
181
|
+
curVecX = dx
|
|
182
|
+
curVecY = dy
|
|
183
|
+
} else {
|
|
184
|
+
curVecX = dx / l
|
|
185
|
+
curVecY = dy / l
|
|
186
|
+
}
|
|
187
|
+
}
|
|
35
188
|
|
|
36
189
|
// Previous vector
|
|
37
|
-
let
|
|
190
|
+
let prevVecX = curVecX
|
|
191
|
+
let prevVecY = curVecY
|
|
38
192
|
|
|
39
193
|
// Previous left and right points
|
|
40
|
-
let
|
|
41
|
-
let
|
|
194
|
+
let plx = sx[0]
|
|
195
|
+
let ply = sy[0]
|
|
196
|
+
let prx = plx
|
|
197
|
+
let pry = ply
|
|
42
198
|
|
|
43
199
|
// Temporary left and right points
|
|
44
|
-
let
|
|
45
|
-
let
|
|
200
|
+
let tlx = plx
|
|
201
|
+
let tly = ply
|
|
202
|
+
let trx = prx
|
|
203
|
+
let trY = pry
|
|
46
204
|
|
|
47
205
|
// Keep track of whether the previous point is a sharp corner
|
|
48
206
|
// ... so that we don't detect the same corner twice
|
|
@@ -55,11 +213,45 @@ export function getStrokeOutlineTracks(
|
|
|
55
213
|
skipping the first and last pointsm, which will get caps later on.
|
|
56
214
|
*/
|
|
57
215
|
|
|
58
|
-
let
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const
|
|
216
|
+
for (let i = 0; i < n; i++) {
|
|
217
|
+
const pointX = sx[i]
|
|
218
|
+
const pointY = sy[i]
|
|
219
|
+
const radius = sr[i]
|
|
220
|
+
const vecX = curVecX
|
|
221
|
+
const vecY = curVecY
|
|
222
|
+
|
|
223
|
+
// Derive the next point's vector (the last point reuses its own), and advance the
|
|
224
|
+
// running vector so the next iteration picks it up regardless of `continue`s below.
|
|
225
|
+
let nextVecX = vecX
|
|
226
|
+
let nextVecY = vecY
|
|
227
|
+
if (i < n - 1) {
|
|
228
|
+
const fromX = i === 0 && n > 2 && hasAnchor ? anchorX : pointX
|
|
229
|
+
const fromY = i === 0 && n > 2 && hasAnchor ? anchorY : pointY
|
|
230
|
+
const dx = fromX - sx[i + 1]
|
|
231
|
+
const dy = fromY - sy[i + 1]
|
|
232
|
+
const l = (dx * dx + dy * dy) ** 0.5
|
|
233
|
+
if (l === 0) {
|
|
234
|
+
nextVecX = dx
|
|
235
|
+
nextVecY = dy
|
|
236
|
+
} else {
|
|
237
|
+
nextVecX = dx / l
|
|
238
|
+
nextVecY = dy / l
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
curVecX = nextVecX
|
|
242
|
+
curVecY = nextVecY
|
|
243
|
+
|
|
244
|
+
// Make sure a corner's worth of points will fit on each side.
|
|
245
|
+
if (
|
|
246
|
+
lc + MAX_ROUNDED_CORNER_STEPS + 1 > trackCapacity ||
|
|
247
|
+
rc + MAX_ROUNDED_CORNER_STEPS + 1 > trackCapacity
|
|
248
|
+
) {
|
|
249
|
+
growTracks()
|
|
250
|
+
lxs = trackLeftX
|
|
251
|
+
lys = trackLeftY
|
|
252
|
+
rxs = trackRightX
|
|
253
|
+
rys = trackRightY
|
|
254
|
+
}
|
|
63
255
|
|
|
64
256
|
/*
|
|
65
257
|
Handle sharp corners
|
|
@@ -69,49 +261,75 @@ export function getStrokeOutlineTracks(
|
|
|
69
261
|
draw a cap at the current point.
|
|
70
262
|
*/
|
|
71
263
|
|
|
72
|
-
const prevDpr =
|
|
73
|
-
const
|
|
74
|
-
const nextDpr = i < strokePoints.length - 1 ? nextVector.dpr(strokePoint.vector) : 1
|
|
264
|
+
const prevDpr = vecX * prevVecX + vecY * prevVecY
|
|
265
|
+
const nextDpr = i < n - 1 ? nextVecX * vecX + nextVecY * vecY : 1
|
|
75
266
|
|
|
76
267
|
const isPointSharpCorner = prevDpr < 0 && !isPrevPointSharpCorner
|
|
77
|
-
const isNextPointSharpCorner = nextDpr
|
|
268
|
+
const isNextPointSharpCorner = nextDpr < 0.2
|
|
78
269
|
|
|
79
270
|
if (isPointSharpCorner || isNextPointSharpCorner) {
|
|
80
271
|
// It's a sharp corner. Draw a rounded cap and move on to the next point
|
|
81
272
|
// Considering saving these and drawing them later? So that we can avoid
|
|
82
273
|
// crossing future points.
|
|
83
274
|
|
|
84
|
-
if (nextDpr >
|
|
275
|
+
if (nextDpr > HARD_CORNER_DPR && totalLength - srl[i] > radius) {
|
|
85
276
|
// Draw a "soft" corner
|
|
86
|
-
const
|
|
87
|
-
const
|
|
277
|
+
const offsetX = prevVecX * radius
|
|
278
|
+
const offsetY = prevVecY * radius
|
|
279
|
+
const cpr = prevVecX * nextVecY - prevVecY * nextVecX
|
|
88
280
|
|
|
89
281
|
if (cpr < 0) {
|
|
90
|
-
|
|
91
|
-
|
|
282
|
+
tlx = pointX + offsetX
|
|
283
|
+
tly = pointY + offsetY
|
|
284
|
+
trx = pointX - offsetX
|
|
285
|
+
trY = pointY - offsetY
|
|
92
286
|
} else {
|
|
93
|
-
|
|
94
|
-
|
|
287
|
+
tlx = pointX - offsetX
|
|
288
|
+
tly = pointY - offsetY
|
|
289
|
+
trx = pointX + offsetX
|
|
290
|
+
trY = pointY + offsetY
|
|
95
291
|
}
|
|
96
292
|
|
|
97
|
-
|
|
98
|
-
|
|
293
|
+
lxs[lc] = tlx
|
|
294
|
+
lys[lc] = tly
|
|
295
|
+
lc++
|
|
296
|
+
rxs[rc] = trx
|
|
297
|
+
rys[rc] = trY
|
|
298
|
+
rc++
|
|
99
299
|
} else {
|
|
100
|
-
// Draw a "sharp" corner
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
300
|
+
// Draw a "sharp" corner: rotate around the input point
|
|
301
|
+
const inX = six[i]
|
|
302
|
+
const inY = siy[i]
|
|
303
|
+
// The arm swept around the point starts perpendicular to the
|
|
304
|
+
// incoming direction, one radius long.
|
|
305
|
+
const dx = -prevVecY * radius
|
|
306
|
+
const dy = prevVecX * radius
|
|
307
|
+
|
|
308
|
+
for (let step = 1 / MAX_ROUNDED_CORNER_STEPS, t = 0; t < 1; t += step) {
|
|
309
|
+
let angle = FIXED_PI * t
|
|
310
|
+
let s = Math.sin(angle)
|
|
311
|
+
let c = Math.cos(angle)
|
|
312
|
+
tlx = inX + (dx * c - dy * s)
|
|
313
|
+
tly = inY + (dx * s + dy * c)
|
|
314
|
+
lxs[lc] = tlx
|
|
315
|
+
lys[lc] = tly
|
|
316
|
+
lc++
|
|
317
|
+
|
|
318
|
+
angle = FIXED_PI + FIXED_PI * -t
|
|
319
|
+
s = Math.sin(angle)
|
|
320
|
+
c = Math.cos(angle)
|
|
321
|
+
trx = inX + (dx * c - dy * s)
|
|
322
|
+
trY = inY + (dx * s + dy * c)
|
|
323
|
+
rxs[rc] = trx
|
|
324
|
+
rys[rc] = trY
|
|
325
|
+
rc++
|
|
110
326
|
}
|
|
111
327
|
}
|
|
112
328
|
|
|
113
|
-
|
|
114
|
-
|
|
329
|
+
plx = tlx
|
|
330
|
+
ply = tly
|
|
331
|
+
prx = trx
|
|
332
|
+
pry = trY
|
|
115
333
|
|
|
116
334
|
if (isNextPointSharpCorner) {
|
|
117
335
|
isPrevPointSharpCorner = true
|
|
@@ -122,10 +340,16 @@ export function getStrokeOutlineTracks(
|
|
|
122
340
|
|
|
123
341
|
isPrevPointSharpCorner = false
|
|
124
342
|
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
343
|
+
if (scap[i]) {
|
|
344
|
+
// Project one radius to each side, perpendicular to the direction of travel.
|
|
345
|
+
const offsetX = vecY * radius
|
|
346
|
+
const offsetY = -vecX * radius
|
|
347
|
+
lxs[lc] = pointX - offsetX
|
|
348
|
+
lys[lc] = pointY - offsetY
|
|
349
|
+
lc++
|
|
350
|
+
rxs[rc] = pointX + offsetX
|
|
351
|
+
rys[rc] = pointY + offsetY
|
|
352
|
+
rc++
|
|
129
353
|
|
|
130
354
|
continue
|
|
131
355
|
}
|
|
@@ -134,125 +358,161 @@ export function getStrokeOutlineTracks(
|
|
|
134
358
|
Add regular points
|
|
135
359
|
|
|
136
360
|
Project points to either side of the current point, using the
|
|
137
|
-
calculated size as a distance. If a point's distance to the
|
|
361
|
+
calculated size as a distance. If a point's distance to the
|
|
138
362
|
previous point on that side greater than the minimum distance
|
|
139
363
|
(or if the corner is kinda sharp), add the points to the side's
|
|
140
364
|
points array.
|
|
141
365
|
*/
|
|
142
366
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
367
|
+
// Project one radius to each side, perpendicular to the direction of
|
|
368
|
+
// travel. The direction blends the current and next vectors, leaning
|
|
369
|
+
// into the next vector as the upcoming turn sharpens.
|
|
370
|
+
const lerpedX = nextVecX + (vecX - nextVecX) * nextDpr
|
|
371
|
+
const lerpedY = nextVecY + (vecY - nextVecY) * nextDpr
|
|
372
|
+
const offsetX = lerpedY * radius
|
|
373
|
+
const offsetY = -lerpedX * radius
|
|
374
|
+
|
|
375
|
+
tlx = pointX - offsetX
|
|
376
|
+
tly = pointY - offsetY
|
|
377
|
+
|
|
378
|
+
if (i <= 1 || (plx - tlx) ** 2 + (ply - tly) ** 2 > minDistance) {
|
|
379
|
+
lxs[lc] = tlx
|
|
380
|
+
lys[lc] = tly
|
|
381
|
+
lc++
|
|
382
|
+
plx = tlx
|
|
383
|
+
ply = tly
|
|
150
384
|
}
|
|
151
385
|
|
|
152
|
-
|
|
386
|
+
trx = pointX + offsetX
|
|
387
|
+
trY = pointY + offsetY
|
|
153
388
|
|
|
154
|
-
if (i <= 1 ||
|
|
155
|
-
|
|
156
|
-
|
|
389
|
+
if (i <= 1 || (prx - trx) ** 2 + (pry - trY) ** 2 > minDistance) {
|
|
390
|
+
rxs[rc] = trx
|
|
391
|
+
rys[rc] = trY
|
|
392
|
+
rc++
|
|
393
|
+
prx = trx
|
|
394
|
+
pry = trY
|
|
157
395
|
}
|
|
158
396
|
|
|
159
397
|
// Set variables for next iteration
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
continue
|
|
398
|
+
prevVecX = vecX
|
|
399
|
+
prevVecY = vecY
|
|
163
400
|
}
|
|
164
401
|
|
|
165
|
-
|
|
166
|
-
Return the points in the correct winding order: begin on the left side, then
|
|
167
|
-
continue around the end cap, then come back along the right side, and finally
|
|
168
|
-
complete the start cap.
|
|
169
|
-
*/
|
|
402
|
+
const tolerance = size * TRACK_TOLERANCE_RATIO
|
|
170
403
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
right: rightPts,
|
|
174
|
-
}
|
|
404
|
+
trackLeftCount = simplifyTrack(trackLeftX, trackLeftY, lc, tolerance)
|
|
405
|
+
trackRightCount = simplifyTrack(trackRightX, trackRightY, rc, tolerance)
|
|
175
406
|
}
|
|
176
407
|
|
|
177
408
|
/**
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* Get an array of points (as `[x, y]`) representing the outline of a stroke.
|
|
409
|
+
* @internal
|
|
181
410
|
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
411
|
+
* `vectorAnchor` is the original predecessor of `strokePoints[1]` when the caller has cut or
|
|
412
|
+
* altered the sequence in front of it (svgInk's elbow partitions): the second point's vector is
|
|
413
|
+
* derived from the anchor rather than from `strokePoints[0]`, preserving the direction it had in
|
|
414
|
+
* the uncut stroke. It only applies when there are more than two points; two-point sequences
|
|
415
|
+
* derive both vectors from each other.
|
|
185
416
|
*/
|
|
186
|
-
export function
|
|
417
|
+
export function getStrokeOutlineTracks(
|
|
187
418
|
strokePoints: StrokePoint[],
|
|
188
|
-
options: StrokeOptions = {}
|
|
189
|
-
|
|
419
|
+
options: StrokeOptions = {},
|
|
420
|
+
vectorAnchor?: VecLike
|
|
421
|
+
): { left: Vec[]; right: Vec[] } {
|
|
422
|
+
loadSrcFromStrokePoints(strokePoints)
|
|
423
|
+
buildTracks(
|
|
424
|
+
options,
|
|
425
|
+
!!vectorAnchor,
|
|
426
|
+
vectorAnchor ? vectorAnchor.x : 0,
|
|
427
|
+
vectorAnchor ? vectorAnchor.y : 0
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
const lxs = trackLeftX
|
|
431
|
+
const lys = trackLeftY
|
|
432
|
+
const rxs = trackRightX
|
|
433
|
+
const rys = trackRightY
|
|
434
|
+
const left: Vec[] = new Array(trackLeftCount)
|
|
435
|
+
for (let i = 0; i < trackLeftCount; i++) {
|
|
436
|
+
left[i] = new Vec(lxs[i], lys[i])
|
|
437
|
+
}
|
|
438
|
+
const right: Vec[] = new Array(trackRightCount)
|
|
439
|
+
for (let i = 0; i < trackRightCount; i++) {
|
|
440
|
+
right[i] = new Vec(rxs[i], rys[i])
|
|
441
|
+
}
|
|
442
|
+
return { left, right }
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/** Pick a step count for a polygonal arc so its chord error stays within `tol`. */
|
|
446
|
+
function arcSteps(radius: number, sweep: number, tol: number, min: number, max: number) {
|
|
447
|
+
if (radius <= tol) return min
|
|
448
|
+
const maxAngle = 2 * Math.acos(1 - tol / radius)
|
|
449
|
+
const steps = Math.ceil(sweep / maxAngle)
|
|
450
|
+
return steps < min ? min : steps > max ? max : steps
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Build the full outline (tracks plus caps) for the stroke points currently loaded in the
|
|
455
|
+
* track-source buffers. This is the shared core of `getStrokeOutlinePoints` and
|
|
456
|
+
* `getStroke`.
|
|
457
|
+
*
|
|
458
|
+
* @internal
|
|
459
|
+
*/
|
|
460
|
+
export function outlineFromSrc(options: StrokeOptions = {}): Vec[] {
|
|
190
461
|
const { size = 16, start = {}, end = {}, last: isComplete = false } = options
|
|
191
462
|
|
|
192
463
|
const { cap: capStart = true } = start
|
|
193
464
|
const { cap: capEnd = true } = end
|
|
194
465
|
|
|
466
|
+
const n = srcCount
|
|
467
|
+
|
|
195
468
|
// We can't do anything with an empty array or a stroke with negative size.
|
|
196
|
-
if (
|
|
469
|
+
if (n === 0 || size <= 0) {
|
|
197
470
|
return []
|
|
198
471
|
}
|
|
199
472
|
|
|
200
|
-
const firstStrokePoint = strokePoints[0]
|
|
201
|
-
const lastStrokePoint = strokePoints[strokePoints.length - 1]
|
|
202
|
-
|
|
203
473
|
// The total length of the line
|
|
204
|
-
const totalLength =
|
|
205
|
-
|
|
206
|
-
const taperStart =
|
|
207
|
-
|
|
208
|
-
? 0
|
|
209
|
-
: start.taper === true
|
|
210
|
-
? Math.max(size, totalLength)
|
|
211
|
-
: (start.taper as number)
|
|
212
|
-
|
|
213
|
-
const taperEnd =
|
|
214
|
-
end.taper === false
|
|
215
|
-
? 0
|
|
216
|
-
: end.taper === true
|
|
217
|
-
? Math.max(size, totalLength)
|
|
218
|
-
: (end.taper as number)
|
|
474
|
+
const totalLength = srcRunningLength[n - 1]
|
|
475
|
+
|
|
476
|
+
const taperStart = resolveTaper(start.taper, size, totalLength)
|
|
477
|
+
const taperEnd = resolveTaper(end.taper, size, totalLength)
|
|
219
478
|
|
|
220
|
-
// The minimum allowed distance between points (squared)
|
|
221
479
|
// Our collected left and right points
|
|
222
|
-
|
|
480
|
+
buildTracks(options, false, 0, 0)
|
|
223
481
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
Now that we have our points on either side of the line, we need to
|
|
228
|
-
draw caps at the start and end. Tapered lines don't have caps, but
|
|
229
|
-
may have dots for very short lines.
|
|
230
|
-
*/
|
|
482
|
+
// Chord tolerance for the polygonal caps below: caps don't need a fixed number of segments,
|
|
483
|
+
// they need enough segments that the polygon is indistinguishable from the arc.
|
|
484
|
+
const capTolerance = Math.max(0.05, size * 0.02)
|
|
231
485
|
|
|
232
|
-
const
|
|
486
|
+
const firstRadius = srcRadius[0]
|
|
487
|
+
const firstPoint = new Vec(srcX[0], srcY[0], srcZ[0])
|
|
233
488
|
|
|
234
489
|
const lastPoint =
|
|
235
|
-
|
|
236
|
-
? strokePoints[strokePoints.length - 1].point
|
|
237
|
-
: Vec.AddXY(firstStrokePoint.point, 1, 1)
|
|
490
|
+
n > 1 ? new Vec(srcX[n - 1], srcY[n - 1], srcZ[n - 1]) : Vec.AddXY(firstPoint, 1, 1)
|
|
238
491
|
|
|
239
492
|
/*
|
|
240
493
|
Draw a dot for very short or completed strokes
|
|
241
|
-
|
|
494
|
+
|
|
242
495
|
If the line is too short to gather left or right points and if the line is
|
|
243
496
|
not tapered on either side, draw a dot. If the line is tapered, then only
|
|
244
497
|
draw a dot if the line is both very short and complete. If we draw a dot,
|
|
245
498
|
we can just return those points.
|
|
246
499
|
*/
|
|
247
500
|
|
|
248
|
-
if (
|
|
501
|
+
if (n === 1) {
|
|
249
502
|
if (!(taperStart || taperEnd) || isComplete) {
|
|
250
503
|
const start = Vec.Add(
|
|
251
504
|
firstPoint,
|
|
252
|
-
Vec.Sub(firstPoint, lastPoint).uni().per().mul(-
|
|
505
|
+
Vec.Sub(firstPoint, lastPoint).uni().per().mul(-firstRadius)
|
|
253
506
|
)
|
|
254
507
|
const dotPts: Vec[] = []
|
|
255
|
-
|
|
508
|
+
const steps = arcSteps(
|
|
509
|
+
firstRadius,
|
|
510
|
+
FIXED_PI * 2,
|
|
511
|
+
capTolerance,
|
|
512
|
+
MIN_ROUNDED_CORNER_STEPS,
|
|
513
|
+
MAX_ROUNDED_CORNER_STEPS
|
|
514
|
+
)
|
|
515
|
+
for (let step = 1 / steps, t = step; t <= 1; t += step) {
|
|
256
516
|
dotPts.push(Vec.RotWith(start, firstPoint, FIXED_PI * 2 * t))
|
|
257
517
|
}
|
|
258
518
|
return dotPts
|
|
@@ -269,17 +529,19 @@ export function getStrokeOutlinePoints(
|
|
|
269
529
|
*/
|
|
270
530
|
|
|
271
531
|
const startCap: Vec[] = []
|
|
272
|
-
if (taperStart || (taperEnd &&
|
|
532
|
+
if (taperStart || (taperEnd && n === 1)) {
|
|
273
533
|
// The start point is tapered, noop
|
|
274
534
|
} else if (capStart) {
|
|
275
|
-
// Draw the round cap -
|
|
276
|
-
|
|
277
|
-
|
|
535
|
+
// Draw the round cap - rotate the right point around the start point to the left point
|
|
536
|
+
const firstRight = new Vec(trackRightX[0], trackRightY[0])
|
|
537
|
+
const steps = arcSteps(firstRadius, FIXED_PI, capTolerance, 4, 8)
|
|
538
|
+
for (let step = 1 / steps, t = step; t <= 1; t += step) {
|
|
539
|
+
const pt = Vec.RotWith(firstRight, firstPoint, FIXED_PI * t)
|
|
278
540
|
startCap.push(pt)
|
|
279
541
|
}
|
|
280
542
|
} else {
|
|
281
543
|
// Draw the flat cap - add a point to the left and right of the start point
|
|
282
|
-
const cornersVector = Vec
|
|
544
|
+
const cornersVector = new Vec(trackLeftX[0] - trackRightX[0], trackLeftY[0] - trackRightY[0])
|
|
283
545
|
const offsetA = Vec.Mul(cornersVector, 0.5)
|
|
284
546
|
const offsetB = Vec.Mul(cornersVector, 0.51)
|
|
285
547
|
|
|
@@ -302,32 +564,82 @@ export function getStrokeOutlinePoints(
|
|
|
302
564
|
*/
|
|
303
565
|
|
|
304
566
|
const endCap: Vec[] = []
|
|
305
|
-
const
|
|
567
|
+
const lastRadius = srcRadius[n - 1]
|
|
568
|
+
|
|
569
|
+
// The exit vector at the last point points back at its predecessor,
|
|
570
|
+
// normalized; a lone point keeps the legacy (1, 1). The cap then starts
|
|
571
|
+
// perpendicular to that vector.
|
|
572
|
+
let lastVecX = 1
|
|
573
|
+
let lastVecY = 1
|
|
574
|
+
if (n > 1) {
|
|
575
|
+
const dx = srcX[n - 2] - srcX[n - 1]
|
|
576
|
+
const dy = srcY[n - 2] - srcY[n - 1]
|
|
577
|
+
const l = (dx * dx + dy * dy) ** 0.5
|
|
578
|
+
if (l === 0) {
|
|
579
|
+
lastVecX = dx
|
|
580
|
+
lastVecY = dy
|
|
581
|
+
} else {
|
|
582
|
+
lastVecX = dx / l
|
|
583
|
+
lastVecY = dy / l
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
const direction = new Vec(-lastVecY, lastVecX)
|
|
306
587
|
|
|
307
|
-
if (taperEnd || (taperStart &&
|
|
588
|
+
if (taperEnd || (taperStart && n === 1)) {
|
|
308
589
|
// Tapered end - push the last point to the line
|
|
309
590
|
endCap.push(lastPoint)
|
|
310
591
|
} else if (capEnd) {
|
|
311
592
|
// Draw the round end cap
|
|
312
|
-
const start = Vec.Add(lastPoint, Vec.Mul(direction,
|
|
313
|
-
|
|
593
|
+
const start = Vec.Add(lastPoint, Vec.Mul(direction, lastRadius))
|
|
594
|
+
const steps = arcSteps(lastRadius, FIXED_PI * 3, capTolerance, MIN_CAP_STEPS, MAX_CAP_STEPS)
|
|
595
|
+
for (let step = 1 / steps, t = step; t < 1; t += step) {
|
|
314
596
|
endCap.push(Vec.RotWith(start, lastPoint, FIXED_PI * 3 * t))
|
|
315
597
|
}
|
|
316
598
|
} else {
|
|
317
599
|
// Draw the flat end cap
|
|
318
600
|
endCap.push(
|
|
319
|
-
Vec.Add(lastPoint, Vec.Mul(direction,
|
|
320
|
-
Vec.Add(lastPoint, Vec.Mul(direction,
|
|
321
|
-
Vec.Sub(lastPoint, Vec.Mul(direction,
|
|
322
|
-
Vec.Sub(lastPoint, Vec.Mul(direction,
|
|
601
|
+
Vec.Add(lastPoint, Vec.Mul(direction, lastRadius)),
|
|
602
|
+
Vec.Add(lastPoint, Vec.Mul(direction, lastRadius * 0.99)),
|
|
603
|
+
Vec.Sub(lastPoint, Vec.Mul(direction, lastRadius * 0.99)),
|
|
604
|
+
Vec.Sub(lastPoint, Vec.Mul(direction, lastRadius))
|
|
323
605
|
)
|
|
324
606
|
}
|
|
325
607
|
|
|
326
608
|
/*
|
|
327
|
-
Return the points in the correct winding order: begin on the left side, then
|
|
328
|
-
continue around the end cap, then come back along the right side, and finally
|
|
609
|
+
Return the points in the correct winding order: begin on the left side, then
|
|
610
|
+
continue around the end cap, then come back along the right side, and finally
|
|
329
611
|
complete the start cap.
|
|
330
612
|
*/
|
|
331
613
|
|
|
332
|
-
|
|
614
|
+
const lxs = trackLeftX
|
|
615
|
+
const lys = trackLeftY
|
|
616
|
+
const rxs = trackRightX
|
|
617
|
+
const rys = trackRightY
|
|
618
|
+
const leftPts: Vec[] = new Array(trackLeftCount)
|
|
619
|
+
for (let i = 0; i < trackLeftCount; i++) {
|
|
620
|
+
leftPts[i] = new Vec(lxs[i], lys[i])
|
|
621
|
+
}
|
|
622
|
+
const rightPtsReversed: Vec[] = new Array(trackRightCount)
|
|
623
|
+
for (let i = 0; i < trackRightCount; i++) {
|
|
624
|
+
rightPtsReversed[i] = new Vec(rxs[trackRightCount - 1 - i], rys[trackRightCount - 1 - i])
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
return leftPts.concat(endCap, rightPtsReversed, startCap)
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* ## getStrokeOutlinePoints
|
|
632
|
+
*
|
|
633
|
+
* Get an array of points (as `[x, y]`) representing the outline of a stroke.
|
|
634
|
+
*
|
|
635
|
+
* @param points - An array of StrokePoints as returned from `getStrokePoints`.
|
|
636
|
+
* @param options - An object with options.
|
|
637
|
+
* @public
|
|
638
|
+
*/
|
|
639
|
+
export function getStrokeOutlinePoints(
|
|
640
|
+
strokePoints: StrokePoint[],
|
|
641
|
+
options: StrokeOptions = {}
|
|
642
|
+
): Vec[] {
|
|
643
|
+
loadSrcFromStrokePoints(strokePoints)
|
|
644
|
+
return outlineFromSrc(options)
|
|
333
645
|
}
|