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,125 +1,331 @@
|
|
|
1
1
|
import { Vec } 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.mjs";
|
|
2
15
|
const { PI } = Math;
|
|
3
16
|
const FIXED_PI = PI + 1e-4;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
17
|
+
const TRACK_TOLERANCE_RATIO = 0.05;
|
|
18
|
+
const SIMPLIFY_WINDOW = 8;
|
|
19
|
+
const MIN_ROUNDED_CORNER_STEPS = 8;
|
|
20
|
+
const MAX_ROUNDED_CORNER_STEPS = 13;
|
|
21
|
+
const MIN_CAP_STEPS = 8;
|
|
22
|
+
const MAX_CAP_STEPS = 29;
|
|
23
|
+
const HARD_CORNER_DPR = -0.62;
|
|
24
|
+
let trackCapacity = 1024;
|
|
25
|
+
let trackLeftX = new Float64Array(trackCapacity);
|
|
26
|
+
let trackLeftY = new Float64Array(trackCapacity);
|
|
27
|
+
let trackRightX = new Float64Array(trackCapacity);
|
|
28
|
+
let trackRightY = new Float64Array(trackCapacity);
|
|
29
|
+
let trackLeftCount = 0;
|
|
30
|
+
let trackRightCount = 0;
|
|
31
|
+
function growTracks() {
|
|
32
|
+
trackCapacity *= 2;
|
|
33
|
+
const nlx = new Float64Array(trackCapacity);
|
|
34
|
+
nlx.set(trackLeftX);
|
|
35
|
+
trackLeftX = nlx;
|
|
36
|
+
const nly = new Float64Array(trackCapacity);
|
|
37
|
+
nly.set(trackLeftY);
|
|
38
|
+
trackLeftY = nly;
|
|
39
|
+
const nrx = new Float64Array(trackCapacity);
|
|
40
|
+
nrx.set(trackRightX);
|
|
41
|
+
trackRightX = nrx;
|
|
42
|
+
const nry = new Float64Array(trackCapacity);
|
|
43
|
+
nry.set(trackRightY);
|
|
44
|
+
trackRightY = nry;
|
|
45
|
+
}
|
|
46
|
+
function simplifyTrack(xs, ys, len, tol) {
|
|
47
|
+
if (len <= 2 || tol <= 0) return len;
|
|
48
|
+
const tol2 = tol * tol;
|
|
49
|
+
let out = 1;
|
|
50
|
+
let anchor = 0;
|
|
51
|
+
const lastIdx = len - 1;
|
|
52
|
+
while (anchor < lastIdx) {
|
|
53
|
+
let best = anchor + 1;
|
|
54
|
+
const maxJ = anchor + SIMPLIFY_WINDOW > lastIdx ? lastIdx : anchor + SIMPLIFY_WINDOW;
|
|
55
|
+
const ax = xs[anchor];
|
|
56
|
+
const ay = ys[anchor];
|
|
57
|
+
outer: for (let j = anchor + 2; j <= maxJ; j++) {
|
|
58
|
+
const acx = xs[j] - ax;
|
|
59
|
+
const acy = ys[j] - ay;
|
|
60
|
+
const l2 = acx * acx + acy * acy;
|
|
61
|
+
for (let k = anchor + 1; k < j; k++) {
|
|
62
|
+
let t = l2 === 0 ? 0 : ((xs[k] - ax) * acx + (ys[k] - ay) * acy) / l2;
|
|
63
|
+
t = t < 0 ? 0 : t > 1 ? 1 : t;
|
|
64
|
+
const ex = xs[k] - (ax + acx * t);
|
|
65
|
+
const ey = ys[k] - (ay + acy * t);
|
|
66
|
+
if (ex * ex + ey * ey > tol2) break outer;
|
|
67
|
+
}
|
|
68
|
+
best = j;
|
|
69
|
+
}
|
|
70
|
+
xs[out] = xs[best];
|
|
71
|
+
ys[out] = ys[best];
|
|
72
|
+
out++;
|
|
73
|
+
anchor = best;
|
|
8
74
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
function buildTracks(options, hasAnchor, anchorX, anchorY) {
|
|
78
|
+
const { size = 16, smoothing = 0.5 } = options;
|
|
79
|
+
let lc = 0;
|
|
80
|
+
let rc = 0;
|
|
81
|
+
trackLeftCount = 0;
|
|
82
|
+
trackRightCount = 0;
|
|
83
|
+
const n = srcCount;
|
|
84
|
+
if (n === 0 || size <= 0) return;
|
|
85
|
+
const sx = srcX;
|
|
86
|
+
const sy = srcY;
|
|
87
|
+
const six = srcInputX;
|
|
88
|
+
const siy = srcInputY;
|
|
89
|
+
const sr = srcRadius;
|
|
90
|
+
const srl = srcRunningLength;
|
|
91
|
+
const scap = srcIsCap;
|
|
92
|
+
let lxs = trackLeftX;
|
|
93
|
+
let lys = trackLeftY;
|
|
94
|
+
let rxs = trackRightX;
|
|
95
|
+
let rys = trackRightY;
|
|
96
|
+
const totalLength = srl[n - 1];
|
|
12
97
|
const minDistance = Math.pow(size * smoothing, 2);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
98
|
+
let curVecX = 1;
|
|
99
|
+
let curVecY = 1;
|
|
100
|
+
if (n > 1) {
|
|
101
|
+
const dx = sx[0] - sx[1];
|
|
102
|
+
const dy = sy[0] - sy[1];
|
|
103
|
+
const l = (dx * dx + dy * dy) ** 0.5;
|
|
104
|
+
if (l === 0) {
|
|
105
|
+
curVecX = dx;
|
|
106
|
+
curVecY = dy;
|
|
107
|
+
} else {
|
|
108
|
+
curVecX = dx / l;
|
|
109
|
+
curVecY = dy / l;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
let prevVecX = curVecX;
|
|
113
|
+
let prevVecY = curVecY;
|
|
114
|
+
let plx = sx[0];
|
|
115
|
+
let ply = sy[0];
|
|
116
|
+
let prx = plx;
|
|
117
|
+
let pry = ply;
|
|
118
|
+
let tlx = plx;
|
|
119
|
+
let tly = ply;
|
|
120
|
+
let trx = prx;
|
|
121
|
+
let trY = pry;
|
|
20
122
|
let isPrevPointSharpCorner = false;
|
|
21
|
-
let
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
123
|
+
for (let i = 0; i < n; i++) {
|
|
124
|
+
const pointX = sx[i];
|
|
125
|
+
const pointY = sy[i];
|
|
126
|
+
const radius = sr[i];
|
|
127
|
+
const vecX = curVecX;
|
|
128
|
+
const vecY = curVecY;
|
|
129
|
+
let nextVecX = vecX;
|
|
130
|
+
let nextVecY = vecY;
|
|
131
|
+
if (i < n - 1) {
|
|
132
|
+
const fromX = i === 0 && n > 2 && hasAnchor ? anchorX : pointX;
|
|
133
|
+
const fromY = i === 0 && n > 2 && hasAnchor ? anchorY : pointY;
|
|
134
|
+
const dx = fromX - sx[i + 1];
|
|
135
|
+
const dy = fromY - sy[i + 1];
|
|
136
|
+
const l = (dx * dx + dy * dy) ** 0.5;
|
|
137
|
+
if (l === 0) {
|
|
138
|
+
nextVecX = dx;
|
|
139
|
+
nextVecY = dy;
|
|
140
|
+
} else {
|
|
141
|
+
nextVecX = dx / l;
|
|
142
|
+
nextVecY = dy / l;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
curVecX = nextVecX;
|
|
146
|
+
curVecY = nextVecY;
|
|
147
|
+
if (lc + MAX_ROUNDED_CORNER_STEPS + 1 > trackCapacity || rc + MAX_ROUNDED_CORNER_STEPS + 1 > trackCapacity) {
|
|
148
|
+
growTracks();
|
|
149
|
+
lxs = trackLeftX;
|
|
150
|
+
lys = trackLeftY;
|
|
151
|
+
rxs = trackRightX;
|
|
152
|
+
rys = trackRightY;
|
|
153
|
+
}
|
|
154
|
+
const prevDpr = vecX * prevVecX + vecY * prevVecY;
|
|
155
|
+
const nextDpr = i < n - 1 ? nextVecX * vecX + nextVecY * vecY : 1;
|
|
28
156
|
const isPointSharpCorner = prevDpr < 0 && !isPrevPointSharpCorner;
|
|
29
|
-
const isNextPointSharpCorner = nextDpr
|
|
157
|
+
const isNextPointSharpCorner = nextDpr < 0.2;
|
|
30
158
|
if (isPointSharpCorner || isNextPointSharpCorner) {
|
|
31
|
-
if (nextDpr >
|
|
32
|
-
const
|
|
33
|
-
const
|
|
159
|
+
if (nextDpr > HARD_CORNER_DPR && totalLength - srl[i] > radius) {
|
|
160
|
+
const offsetX2 = prevVecX * radius;
|
|
161
|
+
const offsetY2 = prevVecY * radius;
|
|
162
|
+
const cpr = prevVecX * nextVecY - prevVecY * nextVecX;
|
|
34
163
|
if (cpr < 0) {
|
|
35
|
-
|
|
36
|
-
|
|
164
|
+
tlx = pointX + offsetX2;
|
|
165
|
+
tly = pointY + offsetY2;
|
|
166
|
+
trx = pointX - offsetX2;
|
|
167
|
+
trY = pointY - offsetY2;
|
|
37
168
|
} else {
|
|
38
|
-
|
|
39
|
-
|
|
169
|
+
tlx = pointX - offsetX2;
|
|
170
|
+
tly = pointY - offsetY2;
|
|
171
|
+
trx = pointX + offsetX2;
|
|
172
|
+
trY = pointY + offsetY2;
|
|
40
173
|
}
|
|
41
|
-
|
|
42
|
-
|
|
174
|
+
lxs[lc] = tlx;
|
|
175
|
+
lys[lc] = tly;
|
|
176
|
+
lc++;
|
|
177
|
+
rxs[rc] = trx;
|
|
178
|
+
rys[rc] = trY;
|
|
179
|
+
rc++;
|
|
43
180
|
} else {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
181
|
+
const inX = six[i];
|
|
182
|
+
const inY = siy[i];
|
|
183
|
+
const dx = -prevVecY * radius;
|
|
184
|
+
const dy = prevVecX * radius;
|
|
185
|
+
for (let step = 1 / MAX_ROUNDED_CORNER_STEPS, t = 0; t < 1; t += step) {
|
|
186
|
+
let angle = FIXED_PI * t;
|
|
187
|
+
let s = Math.sin(angle);
|
|
188
|
+
let c = Math.cos(angle);
|
|
189
|
+
tlx = inX + (dx * c - dy * s);
|
|
190
|
+
tly = inY + (dx * s + dy * c);
|
|
191
|
+
lxs[lc] = tlx;
|
|
192
|
+
lys[lc] = tly;
|
|
193
|
+
lc++;
|
|
194
|
+
angle = FIXED_PI + FIXED_PI * -t;
|
|
195
|
+
s = Math.sin(angle);
|
|
196
|
+
c = Math.cos(angle);
|
|
197
|
+
trx = inX + (dx * c - dy * s);
|
|
198
|
+
trY = inY + (dx * s + dy * c);
|
|
199
|
+
rxs[rc] = trx;
|
|
200
|
+
rys[rc] = trY;
|
|
201
|
+
rc++;
|
|
51
202
|
}
|
|
52
203
|
}
|
|
53
|
-
|
|
54
|
-
|
|
204
|
+
plx = tlx;
|
|
205
|
+
ply = tly;
|
|
206
|
+
prx = trx;
|
|
207
|
+
pry = trY;
|
|
55
208
|
if (isNextPointSharpCorner) {
|
|
56
209
|
isPrevPointSharpCorner = true;
|
|
57
210
|
}
|
|
58
211
|
continue;
|
|
59
212
|
}
|
|
60
213
|
isPrevPointSharpCorner = false;
|
|
61
|
-
if (
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
214
|
+
if (scap[i]) {
|
|
215
|
+
const offsetX2 = vecY * radius;
|
|
216
|
+
const offsetY2 = -vecX * radius;
|
|
217
|
+
lxs[lc] = pointX - offsetX2;
|
|
218
|
+
lys[lc] = pointY - offsetY2;
|
|
219
|
+
lc++;
|
|
220
|
+
rxs[rc] = pointX + offsetX2;
|
|
221
|
+
rys[rc] = pointY + offsetY2;
|
|
222
|
+
rc++;
|
|
65
223
|
continue;
|
|
66
224
|
}
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
225
|
+
const lerpedX = nextVecX + (vecX - nextVecX) * nextDpr;
|
|
226
|
+
const lerpedY = nextVecY + (vecY - nextVecY) * nextDpr;
|
|
227
|
+
const offsetX = lerpedY * radius;
|
|
228
|
+
const offsetY = -lerpedX * radius;
|
|
229
|
+
tlx = pointX - offsetX;
|
|
230
|
+
tly = pointY - offsetY;
|
|
231
|
+
if (i <= 1 || (plx - tlx) ** 2 + (ply - tly) ** 2 > minDistance) {
|
|
232
|
+
lxs[lc] = tlx;
|
|
233
|
+
lys[lc] = tly;
|
|
234
|
+
lc++;
|
|
235
|
+
plx = tlx;
|
|
236
|
+
ply = tly;
|
|
72
237
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
238
|
+
trx = pointX + offsetX;
|
|
239
|
+
trY = pointY + offsetY;
|
|
240
|
+
if (i <= 1 || (prx - trx) ** 2 + (pry - trY) ** 2 > minDistance) {
|
|
241
|
+
rxs[rc] = trx;
|
|
242
|
+
rys[rc] = trY;
|
|
243
|
+
rc++;
|
|
244
|
+
prx = trx;
|
|
245
|
+
pry = trY;
|
|
77
246
|
}
|
|
78
|
-
|
|
79
|
-
|
|
247
|
+
prevVecX = vecX;
|
|
248
|
+
prevVecY = vecY;
|
|
80
249
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
};
|
|
250
|
+
const tolerance = size * TRACK_TOLERANCE_RATIO;
|
|
251
|
+
trackLeftCount = simplifyTrack(trackLeftX, trackLeftY, lc, tolerance);
|
|
252
|
+
trackRightCount = simplifyTrack(trackRightX, trackRightY, rc, tolerance);
|
|
85
253
|
}
|
|
86
|
-
function
|
|
254
|
+
function getStrokeOutlineTracks(strokePoints, options = {}, vectorAnchor) {
|
|
255
|
+
loadSrcFromStrokePoints(strokePoints);
|
|
256
|
+
buildTracks(
|
|
257
|
+
options,
|
|
258
|
+
!!vectorAnchor,
|
|
259
|
+
vectorAnchor ? vectorAnchor.x : 0,
|
|
260
|
+
vectorAnchor ? vectorAnchor.y : 0
|
|
261
|
+
);
|
|
262
|
+
const lxs = trackLeftX;
|
|
263
|
+
const lys = trackLeftY;
|
|
264
|
+
const rxs = trackRightX;
|
|
265
|
+
const rys = trackRightY;
|
|
266
|
+
const left = new Array(trackLeftCount);
|
|
267
|
+
for (let i = 0; i < trackLeftCount; i++) {
|
|
268
|
+
left[i] = new Vec(lxs[i], lys[i]);
|
|
269
|
+
}
|
|
270
|
+
const right = new Array(trackRightCount);
|
|
271
|
+
for (let i = 0; i < trackRightCount; i++) {
|
|
272
|
+
right[i] = new Vec(rxs[i], rys[i]);
|
|
273
|
+
}
|
|
274
|
+
return { left, right };
|
|
275
|
+
}
|
|
276
|
+
function arcSteps(radius, sweep, tol, min, max) {
|
|
277
|
+
if (radius <= tol) return min;
|
|
278
|
+
const maxAngle = 2 * Math.acos(1 - tol / radius);
|
|
279
|
+
const steps = Math.ceil(sweep / maxAngle);
|
|
280
|
+
return steps < min ? min : steps > max ? max : steps;
|
|
281
|
+
}
|
|
282
|
+
function outlineFromSrc(options = {}) {
|
|
87
283
|
const { size = 16, start = {}, end = {}, last: isComplete = false } = options;
|
|
88
284
|
const { cap: capStart = true } = start;
|
|
89
285
|
const { cap: capEnd = true } = end;
|
|
90
|
-
|
|
286
|
+
const n = srcCount;
|
|
287
|
+
if (n === 0 || size <= 0) {
|
|
91
288
|
return [];
|
|
92
289
|
}
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
const firstPoint =
|
|
100
|
-
const lastPoint =
|
|
101
|
-
if (
|
|
290
|
+
const totalLength = srcRunningLength[n - 1];
|
|
291
|
+
const taperStart = resolveTaper(start.taper, size, totalLength);
|
|
292
|
+
const taperEnd = resolveTaper(end.taper, size, totalLength);
|
|
293
|
+
buildTracks(options, false, 0, 0);
|
|
294
|
+
const capTolerance = Math.max(0.05, size * 0.02);
|
|
295
|
+
const firstRadius = srcRadius[0];
|
|
296
|
+
const firstPoint = new Vec(srcX[0], srcY[0], srcZ[0]);
|
|
297
|
+
const lastPoint = n > 1 ? new Vec(srcX[n - 1], srcY[n - 1], srcZ[n - 1]) : Vec.AddXY(firstPoint, 1, 1);
|
|
298
|
+
if (n === 1) {
|
|
102
299
|
if (!(taperStart || taperEnd) || isComplete) {
|
|
103
300
|
const start2 = Vec.Add(
|
|
104
301
|
firstPoint,
|
|
105
|
-
Vec.Sub(firstPoint, lastPoint).uni().per().mul(-
|
|
302
|
+
Vec.Sub(firstPoint, lastPoint).uni().per().mul(-firstRadius)
|
|
106
303
|
);
|
|
107
304
|
const dotPts = [];
|
|
108
|
-
|
|
305
|
+
const steps = arcSteps(
|
|
306
|
+
firstRadius,
|
|
307
|
+
FIXED_PI * 2,
|
|
308
|
+
capTolerance,
|
|
309
|
+
MIN_ROUNDED_CORNER_STEPS,
|
|
310
|
+
MAX_ROUNDED_CORNER_STEPS
|
|
311
|
+
);
|
|
312
|
+
for (let step = 1 / steps, t = step; t <= 1; t += step) {
|
|
109
313
|
dotPts.push(Vec.RotWith(start2, firstPoint, FIXED_PI * 2 * t));
|
|
110
314
|
}
|
|
111
315
|
return dotPts;
|
|
112
316
|
}
|
|
113
317
|
}
|
|
114
318
|
const startCap = [];
|
|
115
|
-
if (taperStart || taperEnd &&
|
|
319
|
+
if (taperStart || taperEnd && n === 1) {
|
|
116
320
|
} else if (capStart) {
|
|
117
|
-
|
|
118
|
-
|
|
321
|
+
const firstRight = new Vec(trackRightX[0], trackRightY[0]);
|
|
322
|
+
const steps = arcSteps(firstRadius, FIXED_PI, capTolerance, 4, 8);
|
|
323
|
+
for (let step = 1 / steps, t = step; t <= 1; t += step) {
|
|
324
|
+
const pt = Vec.RotWith(firstRight, firstPoint, FIXED_PI * t);
|
|
119
325
|
startCap.push(pt);
|
|
120
326
|
}
|
|
121
327
|
} else {
|
|
122
|
-
const cornersVector = Vec
|
|
328
|
+
const cornersVector = new Vec(trackLeftX[0] - trackRightX[0], trackLeftY[0] - trackRightY[0]);
|
|
123
329
|
const offsetA = Vec.Mul(cornersVector, 0.5);
|
|
124
330
|
const offsetB = Vec.Mul(cornersVector, 0.51);
|
|
125
331
|
startCap.push(
|
|
@@ -130,26 +336,66 @@ function getStrokeOutlinePoints(strokePoints, options = {}) {
|
|
|
130
336
|
);
|
|
131
337
|
}
|
|
132
338
|
const endCap = [];
|
|
133
|
-
const
|
|
134
|
-
|
|
339
|
+
const lastRadius = srcRadius[n - 1];
|
|
340
|
+
let lastVecX = 1;
|
|
341
|
+
let lastVecY = 1;
|
|
342
|
+
if (n > 1) {
|
|
343
|
+
const dx = srcX[n - 2] - srcX[n - 1];
|
|
344
|
+
const dy = srcY[n - 2] - srcY[n - 1];
|
|
345
|
+
const l = (dx * dx + dy * dy) ** 0.5;
|
|
346
|
+
if (l === 0) {
|
|
347
|
+
lastVecX = dx;
|
|
348
|
+
lastVecY = dy;
|
|
349
|
+
} else {
|
|
350
|
+
lastVecX = dx / l;
|
|
351
|
+
lastVecY = dy / l;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
const direction = new Vec(-lastVecY, lastVecX);
|
|
355
|
+
if (taperEnd || taperStart && n === 1) {
|
|
135
356
|
endCap.push(lastPoint);
|
|
136
357
|
} else if (capEnd) {
|
|
137
|
-
const start2 = Vec.Add(lastPoint, Vec.Mul(direction,
|
|
138
|
-
|
|
358
|
+
const start2 = Vec.Add(lastPoint, Vec.Mul(direction, lastRadius));
|
|
359
|
+
const steps = arcSteps(lastRadius, FIXED_PI * 3, capTolerance, MIN_CAP_STEPS, MAX_CAP_STEPS);
|
|
360
|
+
for (let step = 1 / steps, t = step; t < 1; t += step) {
|
|
139
361
|
endCap.push(Vec.RotWith(start2, lastPoint, FIXED_PI * 3 * t));
|
|
140
362
|
}
|
|
141
363
|
} else {
|
|
142
364
|
endCap.push(
|
|
143
|
-
Vec.Add(lastPoint, Vec.Mul(direction,
|
|
144
|
-
Vec.Add(lastPoint, Vec.Mul(direction,
|
|
145
|
-
Vec.Sub(lastPoint, Vec.Mul(direction,
|
|
146
|
-
Vec.Sub(lastPoint, Vec.Mul(direction,
|
|
365
|
+
Vec.Add(lastPoint, Vec.Mul(direction, lastRadius)),
|
|
366
|
+
Vec.Add(lastPoint, Vec.Mul(direction, lastRadius * 0.99)),
|
|
367
|
+
Vec.Sub(lastPoint, Vec.Mul(direction, lastRadius * 0.99)),
|
|
368
|
+
Vec.Sub(lastPoint, Vec.Mul(direction, lastRadius))
|
|
147
369
|
);
|
|
148
370
|
}
|
|
149
|
-
|
|
371
|
+
const lxs = trackLeftX;
|
|
372
|
+
const lys = trackLeftY;
|
|
373
|
+
const rxs = trackRightX;
|
|
374
|
+
const rys = trackRightY;
|
|
375
|
+
const leftPts = new Array(trackLeftCount);
|
|
376
|
+
for (let i = 0; i < trackLeftCount; i++) {
|
|
377
|
+
leftPts[i] = new Vec(lxs[i], lys[i]);
|
|
378
|
+
}
|
|
379
|
+
const rightPtsReversed = new Array(trackRightCount);
|
|
380
|
+
for (let i = 0; i < trackRightCount; i++) {
|
|
381
|
+
rightPtsReversed[i] = new Vec(rxs[trackRightCount - 1 - i], rys[trackRightCount - 1 - i]);
|
|
382
|
+
}
|
|
383
|
+
return leftPts.concat(endCap, rightPtsReversed, startCap);
|
|
384
|
+
}
|
|
385
|
+
function getStrokeOutlinePoints(strokePoints, options = {}) {
|
|
386
|
+
loadSrcFromStrokePoints(strokePoints);
|
|
387
|
+
return outlineFromSrc(options);
|
|
150
388
|
}
|
|
151
389
|
export {
|
|
390
|
+
buildTracks,
|
|
152
391
|
getStrokeOutlinePoints,
|
|
153
|
-
getStrokeOutlineTracks
|
|
392
|
+
getStrokeOutlineTracks,
|
|
393
|
+
outlineFromSrc,
|
|
394
|
+
trackLeftCount,
|
|
395
|
+
trackLeftX,
|
|
396
|
+
trackLeftY,
|
|
397
|
+
trackRightCount,
|
|
398
|
+
trackRightX,
|
|
399
|
+
trackRightY
|
|
154
400
|
};
|
|
155
401
|
//# sourceMappingURL=getStrokeOutlinePoints.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/lib/shapes/shared/freehand/getStrokeOutlinePoints.ts"],
|
|
4
|
-
"sourcesContent": ["import { Vec } from '@tldraw/editor'\nimport type { StrokeOptions, StrokePoint } from './types'\n\nconst { PI } = Math\n\n// Browser strokes seem to be off if PI is regular, a tiny offset seems to fix it\nconst FIXED_PI = PI + 0.0001\n\n/**\n * @internal\n */\nexport function getStrokeOutlineTracks(\n\tstrokePoints: StrokePoint[],\n\toptions: StrokeOptions = {}\n): { left: Vec[]; right: Vec[] } {\n\tconst { size = 16, smoothing = 0.5 } = options\n\n\t// We can't do anything with an empty array or a stroke with negative size.\n\tif (strokePoints.length === 0 || size <= 0) {\n\t\treturn { left: [], right: [] }\n\t}\n\n\tconst firstStrokePoint = strokePoints[0]\n\tconst lastStrokePoint = strokePoints[strokePoints.length - 1]\n\n\t// The total length of the line\n\tconst totalLength = lastStrokePoint.runningLength\n\n\t// The minimum allowed distance between points (squared)\n\tconst minDistance = Math.pow(size * smoothing, 2)\n\n\t// Our collected left and right points\n\tconst leftPts: Vec[] = []\n\tconst rightPts: Vec[] = []\n\n\t// Previous vector\n\tlet prevVector = strokePoints[0].vector\n\n\t// Previous left and right points\n\tlet pl = strokePoints[0].point\n\tlet pr = pl\n\n\t// Temporary left and right points\n\tlet tl = pl\n\tlet tr = pr\n\n\t// Keep track of whether the previous point is a sharp corner\n\t// ... so that we don't detect the same corner twice\n\tlet isPrevPointSharpCorner = false\n\n\t/*\n Find the outline's left and right points\n\n Iterating through the points and populate the rightPts and leftPts arrays,\n skipping the first and last pointsm, which will get caps later on.\n */\n\n\tlet strokePoint: StrokePoint\n\n\tfor (let i = 0; i < strokePoints.length; i++) {\n\t\tstrokePoint = strokePoints[i]\n\t\tconst { point, vector } = strokePoints[i]\n\n\t\t/*\n Handle sharp corners\n\n Find the difference (dot product) between the current and next vector.\n If the next vector is at more than a right angle to the current vector,\n draw a cap at the current point.\n */\n\n\t\tconst prevDpr = strokePoint.vector.dpr(prevVector)\n\t\tconst nextVector = (i < strokePoints.length - 1 ? strokePoints[i + 1] : strokePoints[i]).vector\n\t\tconst nextDpr = i < strokePoints.length - 1 ? nextVector.dpr(strokePoint.vector) : 1\n\n\t\tconst isPointSharpCorner = prevDpr < 0 && !isPrevPointSharpCorner\n\t\tconst isNextPointSharpCorner = nextDpr !== null && nextDpr < 0.2\n\n\t\tif (isPointSharpCorner || isNextPointSharpCorner) {\n\t\t\t// It's a sharp corner. Draw a rounded cap and move on to the next point\n\t\t\t// Considering saving these and drawing them later? So that we can avoid\n\t\t\t// crossing future points.\n\n\t\t\tif (nextDpr > -0.62 && totalLength - strokePoint.runningLength > strokePoint.radius) {\n\t\t\t\t// Draw a \"soft\" corner\n\t\t\t\tconst offset = prevVector.clone().mul(strokePoint.radius)\n\t\t\t\tconst cpr = prevVector.clone().cpr(nextVector)\n\n\t\t\t\tif (cpr < 0) {\n\t\t\t\t\ttl = Vec.Add(point, offset)\n\t\t\t\t\ttr = Vec.Sub(point, offset)\n\t\t\t\t} else {\n\t\t\t\t\ttl = Vec.Sub(point, offset)\n\t\t\t\t\ttr = Vec.Add(point, offset)\n\t\t\t\t}\n\n\t\t\t\tleftPts.push(tl)\n\t\t\t\trightPts.push(tr)\n\t\t\t} else {\n\t\t\t\t// Draw a \"sharp\" corner\n\t\t\t\tconst offset = prevVector.clone().mul(strokePoint.radius).per()\n\t\t\t\tconst start = Vec.Sub(strokePoint.input, offset)\n\n\t\t\t\tfor (let step = 1 / 13, t = 0; t < 1; t += step) {\n\t\t\t\t\ttl = Vec.RotWith(start, strokePoint.input, FIXED_PI * t)\n\t\t\t\t\tleftPts.push(tl)\n\n\t\t\t\t\ttr = Vec.RotWith(start, strokePoint.input, FIXED_PI + FIXED_PI * -t)\n\t\t\t\t\trightPts.push(tr)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tpl = tl\n\t\t\tpr = tr\n\n\t\t\tif (isNextPointSharpCorner) {\n\t\t\t\tisPrevPointSharpCorner = true\n\t\t\t}\n\n\t\t\tcontinue\n\t\t}\n\n\t\tisPrevPointSharpCorner = false\n\n\t\tif (strokePoint === firstStrokePoint || strokePoint === lastStrokePoint) {\n\t\t\tconst offset = Vec.Per(vector).mul(strokePoint.radius)\n\t\t\tleftPts.push(Vec.Sub(point, offset))\n\t\t\trightPts.push(Vec.Add(point, offset))\n\n\t\t\tcontinue\n\t\t}\n\n\t\t/*\n Add regular points\n\n Project points to either side of the current point, using the\n calculated size as a distance. If a point's distance to the \n previous point on that side greater than the minimum distance\n (or if the corner is kinda sharp), add the points to the side's\n points array.\n */\n\n\t\tconst offset = Vec.Lrp(nextVector, vector, nextDpr).per().mul(strokePoint.radius)\n\n\t\ttl = Vec.Sub(point, offset)\n\n\t\tif (i <= 1 || Vec.Dist2(pl, tl) > minDistance) {\n\t\t\tleftPts.push(tl)\n\t\t\tpl = tl\n\t\t}\n\n\t\ttr = Vec.Add(point, offset)\n\n\t\tif (i <= 1 || Vec.Dist2(pr, tr) > minDistance) {\n\t\t\trightPts.push(tr)\n\t\t\tpr = tr\n\t\t}\n\n\t\t// Set variables for next iteration\n\t\tprevVector = vector\n\n\t\tcontinue\n\t}\n\n\t/*\n Return the points in the correct winding order: begin on the left side, then \n continue around the end cap, then come back along the right side, and finally \n complete the start cap.\n */\n\n\treturn {\n\t\tleft: leftPts,\n\t\tright: rightPts,\n\t}\n}\n\n/**\n * ## getStrokeOutlinePoints\n *\n * Get an array of points (as `[x, y]`) representing the outline of a stroke.\n *\n * @param points - An array of StrokePoints as returned from `getStrokePoints`.\n * @param options - An object with options.\n * @public\n */\nexport function getStrokeOutlinePoints(\n\tstrokePoints: StrokePoint[],\n\toptions: StrokeOptions = {}\n): Vec[] {\n\tconst { size = 16, start = {}, end = {}, last: isComplete = false } = options\n\n\tconst { cap: capStart = true } = start\n\tconst { cap: capEnd = true } = end\n\n\t// We can't do anything with an empty array or a stroke with negative size.\n\tif (strokePoints.length === 0 || size <= 0) {\n\t\treturn []\n\t}\n\n\tconst firstStrokePoint = strokePoints[0]\n\tconst lastStrokePoint = strokePoints[strokePoints.length - 1]\n\n\t// The total length of the line\n\tconst totalLength = lastStrokePoint.runningLength\n\n\tconst taperStart =\n\t\tstart.taper === false\n\t\t\t? 0\n\t\t\t: start.taper === true\n\t\t\t\t? Math.max(size, totalLength)\n\t\t\t\t: (start.taper as number)\n\n\tconst taperEnd =\n\t\tend.taper === false\n\t\t\t? 0\n\t\t\t: end.taper === true\n\t\t\t\t? Math.max(size, totalLength)\n\t\t\t\t: (end.taper as number)\n\n\t// The minimum allowed distance between points (squared)\n\t// Our collected left and right points\n\tconst { left: leftPts, right: rightPts } = getStrokeOutlineTracks(strokePoints, options)\n\n\t/*\n Drawing caps\n \n Now that we have our points on either side of the line, we need to\n draw caps at the start and end. Tapered lines don't have caps, but\n may have dots for very short lines.\n */\n\n\tconst firstPoint = firstStrokePoint.point\n\n\tconst lastPoint =\n\t\tstrokePoints.length > 1\n\t\t\t? strokePoints[strokePoints.length - 1].point\n\t\t\t: Vec.AddXY(firstStrokePoint.point, 1, 1)\n\n\t/*\n Draw a dot for very short or completed strokes\n \n If the line is too short to gather left or right points and if the line is\n not tapered on either side, draw a dot. If the line is tapered, then only\n draw a dot if the line is both very short and complete. If we draw a dot,\n we can just return those points.\n */\n\n\tif (strokePoints.length === 1) {\n\t\tif (!(taperStart || taperEnd) || isComplete) {\n\t\t\tconst start = Vec.Add(\n\t\t\t\tfirstPoint,\n\t\t\t\tVec.Sub(firstPoint, lastPoint).uni().per().mul(-firstStrokePoint.radius)\n\t\t\t)\n\t\t\tconst dotPts: Vec[] = []\n\t\t\tfor (let step = 1 / 13, t = step; t <= 1; t += step) {\n\t\t\t\tdotPts.push(Vec.RotWith(start, firstPoint, FIXED_PI * 2 * t))\n\t\t\t}\n\t\t\treturn dotPts\n\t\t}\n\t}\n\n\t/*\n Draw a start cap\n\n Unless the line has a tapered start, or unless the line has a tapered end\n and the line is very short, draw a start cap around the first point. Use\n the distance between the second left and right point for the cap's radius.\n Finally remove the first left and right points. :psyduck:\n */\n\n\tconst startCap: Vec[] = []\n\tif (taperStart || (taperEnd && strokePoints.length === 1)) {\n\t\t// The start point is tapered, noop\n\t} else if (capStart) {\n\t\t// Draw the round cap - add thirteen points rotating the right point around the start point to the left point\n\t\tfor (let step = 1 / 8, t = step; t <= 1; t += step) {\n\t\t\tconst pt = Vec.RotWith(rightPts[0], firstPoint, FIXED_PI * t)\n\t\t\tstartCap.push(pt)\n\t\t}\n\t} else {\n\t\t// Draw the flat cap - add a point to the left and right of the start point\n\t\tconst cornersVector = Vec.Sub(leftPts[0], rightPts[0])\n\t\tconst offsetA = Vec.Mul(cornersVector, 0.5)\n\t\tconst offsetB = Vec.Mul(cornersVector, 0.51)\n\n\t\tstartCap.push(\n\t\t\tVec.Sub(firstPoint, offsetA),\n\t\t\tVec.Sub(firstPoint, offsetB),\n\t\t\tVec.Add(firstPoint, offsetB),\n\t\t\tVec.Add(firstPoint, offsetA)\n\t\t)\n\t}\n\n\t/*\n Draw an end cap\n\n If the line does not have a tapered end, and unless the line has a tapered\n start and the line is very short, draw a cap around the last point. Finally,\n remove the last left and right points. Otherwise, add the last point. Note\n that This cap is a full-turn-and-a-half: this prevents incorrect caps on\n sharp end turns.\n */\n\n\tconst endCap: Vec[] = []\n\tconst direction = lastStrokePoint.vector.clone().per().neg()\n\n\tif (taperEnd || (taperStart && strokePoints.length === 1)) {\n\t\t// Tapered end - push the last point to the line\n\t\tendCap.push(lastPoint)\n\t} else if (capEnd) {\n\t\t// Draw the round end cap\n\t\tconst start = Vec.Add(lastPoint, Vec.Mul(direction, lastStrokePoint.radius))\n\t\tfor (let step = 1 / 29, t = step; t < 1; t += step) {\n\t\t\tendCap.push(Vec.RotWith(start, lastPoint, FIXED_PI * 3 * t))\n\t\t}\n\t} else {\n\t\t// Draw the flat end cap\n\t\tendCap.push(\n\t\t\tVec.Add(lastPoint, Vec.Mul(direction, lastStrokePoint.radius)),\n\t\t\tVec.Add(lastPoint, Vec.Mul(direction, lastStrokePoint.radius * 0.99)),\n\t\t\tVec.Sub(lastPoint, Vec.Mul(direction, lastStrokePoint.radius * 0.99)),\n\t\t\tVec.Sub(lastPoint, Vec.Mul(direction, lastStrokePoint.radius))\n\t\t)\n\t}\n\n\t/*\n Return the points in the correct winding order: begin on the left side, then \n continue around the end cap, then come back along the right side, and finally \n complete the start cap.\n */\n\n\treturn leftPts.concat(endCap, rightPts.reverse(), startCap)\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["import { Vec, VecLike } from '@tldraw/editor'\nimport {\n\tloadSrcFromStrokePoints,\n\tresolveTaper,\n\tsrcCount,\n\tsrcInputX,\n\tsrcInputY,\n\tsrcIsCap,\n\tsrcRadius,\n\tsrcRunningLength,\n\tsrcX,\n\tsrcY,\n\tsrcZ,\n} from './core'\nimport type { StrokeOptions, StrokePoint } from './types'\n\nconst { PI } = Math\n\n// Browser strokes seem to be off if PI is regular, a tiny offset seems to fix it\nconst FIXED_PI = PI + 0.0001\n\n// How far the simplified outline tracks may deviate from the raw tracks, as a fraction of the\n// stroke size. Well below visible thresholds: the parity harness shows sub-0.1px differences at\n// default stroke sizes.\nconst TRACK_TOLERANCE_RATIO = 0.05\n\n// The maximum number of intermediate points the track simplifier may drop per kept segment.\nconst SIMPLIFY_WINDOW = 8\n\n// How many steps to take when rounding a corner\nconst MIN_ROUNDED_CORNER_STEPS = 8\nconst MAX_ROUNDED_CORNER_STEPS = 13\n\n// How many steps to take when rounding a corner\nconst MIN_CAP_STEPS = 8\nconst MAX_CAP_STEPS = 29\n\n// Dot product threshold for identifying a hard corner\nconst HARD_CORNER_DPR = -0.62\n\n// ---------------------------------------------------------------------------------\n// Track buffers: the left and right outline tracks, written by `buildTracks` and read\n// either by svgInk's path writer or materialized into Vecs by the public functions.\n// Reusable and non-reentrant, like the pipeline buffers in core.ts.\n// ---------------------------------------------------------------------------------\n\nlet trackCapacity = 1024\nexport let trackLeftX = new Float64Array(trackCapacity)\nexport let trackLeftY = new Float64Array(trackCapacity)\nexport let trackRightX = new Float64Array(trackCapacity)\nexport let trackRightY = new Float64Array(trackCapacity)\nexport let trackLeftCount = 0\nexport let trackRightCount = 0\n\n// Tracks grow while being written (corners append a variable number of points), so unlike\n// the other buffers a grow here must copy the points written so far.\nfunction growTracks() {\n\ttrackCapacity *= 2\n\tconst nlx = new Float64Array(trackCapacity)\n\tnlx.set(trackLeftX)\n\ttrackLeftX = nlx\n\tconst nly = new Float64Array(trackCapacity)\n\tnly.set(trackLeftY)\n\ttrackLeftY = nly\n\tconst nrx = new Float64Array(trackCapacity)\n\tnrx.set(trackRightX)\n\ttrackRightX = nrx\n\tconst nry = new Float64Array(trackCapacity)\n\tnry.set(trackRightY)\n\ttrackRightY = nry\n}\n\n/**\n * Drop track points that lie within tolderance (`tol`) of the segment between their kept neighbors.\n * The outline tracks are dense on gentle curves and straight runs where the quadratic smoothing\n * used for rendering needs far fewer points; this keeps the simplified polyline within `tol` of\n * the original one. Works in place: kept points are compacted toward the front of the arrays.\n *\n * @param xs - The x coordinates of the track to simplify\n * @param ys - The y coordinates of the track to simplify\n * @param len - The number of points in the track\n * @param tol - The tolerance\n *\n * @returns The number of points in the simplified track.\n */\nfunction simplifyTrack(xs: Float64Array, ys: Float64Array, len: number, tol: number): number {\n\tif (len <= 2 || tol <= 0) return len\n\tconst tol2 = tol * tol\n\tlet out = 1\n\tlet anchor = 0\n\tconst lastIdx = len - 1\n\twhile (anchor < lastIdx) {\n\t\tlet best = anchor + 1\n\t\tconst maxJ = anchor + SIMPLIFY_WINDOW > lastIdx ? lastIdx : anchor + SIMPLIFY_WINDOW\n\t\tconst ax = xs[anchor]\n\t\tconst ay = ys[anchor]\n\t\touter: for (let j = anchor + 2; j <= maxJ; j++) {\n\t\t\tconst acx = xs[j] - ax\n\t\t\tconst acy = ys[j] - ay\n\t\t\tconst l2 = acx * acx + acy * acy\n\t\t\tfor (let k = anchor + 1; k < j; k++) {\n\t\t\t\tlet t = l2 === 0 ? 0 : ((xs[k] - ax) * acx + (ys[k] - ay) * acy) / l2\n\t\t\t\tt = t < 0 ? 0 : t > 1 ? 1 : t\n\t\t\t\tconst ex = xs[k] - (ax + acx * t)\n\t\t\t\tconst ey = ys[k] - (ay + acy * t)\n\t\t\t\tif (ex * ex + ey * ey > tol2) break outer\n\t\t\t}\n\t\t\tbest = j\n\t\t}\n\t\t// Compaction never overtakes the read cursor: the `out`th kept index is always >= out.\n\t\txs[out] = xs[best]\n\t\tys[out] = ys[best]\n\t\tout++\n\t\tanchor = best\n\t}\n\treturn out\n}\n\n/**\n * Build the left and right outline tracks for the stroke points currently loaded in the\n * track-source buffers, into the track buffers. This is the array core of\n * `getStrokeOutlineTracks`.\n *\n * `hasAnchor`/`anchorX`/`anchorY` carry the original predecessor of point 1 when the\n * caller has cut or altered the sequence in front of it (svgInk's elbow partitions): the\n * second point's vector is derived from the anchor rather than from point 0, preserving\n * the direction it had in the uncut stroke. It only applies when there are more than two\n * points; two-point sequences derive both vectors from each other.\n *\n * @internal\n */\nexport function buildTracks(\n\toptions: StrokeOptions,\n\thasAnchor: boolean,\n\tanchorX: number,\n\tanchorY: number\n): void {\n\tconst { size = 16, smoothing = 0.5 } = options\n\n\tlet lc = 0\n\tlet rc = 0\n\ttrackLeftCount = 0\n\ttrackRightCount = 0\n\n\tconst n = srcCount\n\n\t// We can't do anything with an empty array or a stroke with negative size.\n\tif (n === 0 || size <= 0) return\n\n\t// Local captures of the source buffers, hoisting the binding reads out of the loop.\n\t// The track buffers can grow mid-loop, so those are re-captured after growth.\n\tconst sx = srcX\n\tconst sy = srcY\n\tconst six = srcInputX\n\tconst siy = srcInputY\n\tconst sr = srcRadius\n\tconst srl = srcRunningLength\n\tconst scap = srcIsCap\n\tlet lxs = trackLeftX\n\tlet lys = trackLeftY\n\tlet rxs = trackRightX\n\tlet rys = trackRightY\n\n\t// The total length of the line\n\tconst totalLength = srl[n - 1]\n\n\t// The minimum allowed distance between points (squared)\n\tconst minDistance = Math.pow(size * smoothing, 2)\n\n\t// Stroke point vectors are derived on the fly from consecutive points: a point's vector is\n\t// the unit vector pointing back at its predecessor (matching what getStrokePoints used to\n\t// store). The first point shares the second point's vector; a lone point keeps the legacy\n\t// unnormalized (1, 1).\n\tlet curVecX = 1\n\tlet curVecY = 1\n\tif (n > 1) {\n\t\tconst dx = sx[0] - sx[1]\n\t\tconst dy = sy[0] - sy[1]\n\t\tconst l = (dx * dx + dy * dy) ** 0.5\n\t\tif (l === 0) {\n\t\t\tcurVecX = dx\n\t\t\tcurVecY = dy\n\t\t} else {\n\t\t\tcurVecX = dx / l\n\t\t\tcurVecY = dy / l\n\t\t}\n\t}\n\n\t// Previous vector\n\tlet prevVecX = curVecX\n\tlet prevVecY = curVecY\n\n\t// Previous left and right points\n\tlet plx = sx[0]\n\tlet ply = sy[0]\n\tlet prx = plx\n\tlet pry = ply\n\n\t// Temporary left and right points\n\tlet tlx = plx\n\tlet tly = ply\n\tlet trx = prx\n\tlet trY = pry\n\n\t// Keep track of whether the previous point is a sharp corner\n\t// ... so that we don't detect the same corner twice\n\tlet isPrevPointSharpCorner = false\n\n\t/*\n Find the outline's left and right points\n\n Iterating through the points and populate the rightPts and leftPts arrays,\n skipping the first and last pointsm, which will get caps later on.\n */\n\n\tfor (let i = 0; i < n; i++) {\n\t\tconst pointX = sx[i]\n\t\tconst pointY = sy[i]\n\t\tconst radius = sr[i]\n\t\tconst vecX = curVecX\n\t\tconst vecY = curVecY\n\n\t\t// Derive the next point's vector (the last point reuses its own), and advance the\n\t\t// running vector so the next iteration picks it up regardless of `continue`s below.\n\t\tlet nextVecX = vecX\n\t\tlet nextVecY = vecY\n\t\tif (i < n - 1) {\n\t\t\tconst fromX = i === 0 && n > 2 && hasAnchor ? anchorX : pointX\n\t\t\tconst fromY = i === 0 && n > 2 && hasAnchor ? anchorY : pointY\n\t\t\tconst dx = fromX - sx[i + 1]\n\t\t\tconst dy = fromY - sy[i + 1]\n\t\t\tconst l = (dx * dx + dy * dy) ** 0.5\n\t\t\tif (l === 0) {\n\t\t\t\tnextVecX = dx\n\t\t\t\tnextVecY = dy\n\t\t\t} else {\n\t\t\t\tnextVecX = dx / l\n\t\t\t\tnextVecY = dy / l\n\t\t\t}\n\t\t}\n\t\tcurVecX = nextVecX\n\t\tcurVecY = nextVecY\n\n\t\t// Make sure a corner's worth of points will fit on each side.\n\t\tif (\n\t\t\tlc + MAX_ROUNDED_CORNER_STEPS + 1 > trackCapacity ||\n\t\t\trc + MAX_ROUNDED_CORNER_STEPS + 1 > trackCapacity\n\t\t) {\n\t\t\tgrowTracks()\n\t\t\tlxs = trackLeftX\n\t\t\tlys = trackLeftY\n\t\t\trxs = trackRightX\n\t\t\trys = trackRightY\n\t\t}\n\n\t\t/*\n Handle sharp corners\n\n Find the difference (dot product) between the current and next vector.\n If the next vector is at more than a right angle to the current vector,\n draw a cap at the current point.\n */\n\n\t\tconst prevDpr = vecX * prevVecX + vecY * prevVecY\n\t\tconst nextDpr = i < n - 1 ? nextVecX * vecX + nextVecY * vecY : 1\n\n\t\tconst isPointSharpCorner = prevDpr < 0 && !isPrevPointSharpCorner\n\t\tconst isNextPointSharpCorner = nextDpr < 0.2\n\n\t\tif (isPointSharpCorner || isNextPointSharpCorner) {\n\t\t\t// It's a sharp corner. Draw a rounded cap and move on to the next point\n\t\t\t// Considering saving these and drawing them later? So that we can avoid\n\t\t\t// crossing future points.\n\n\t\t\tif (nextDpr > HARD_CORNER_DPR && totalLength - srl[i] > radius) {\n\t\t\t\t// Draw a \"soft\" corner\n\t\t\t\tconst offsetX = prevVecX * radius\n\t\t\t\tconst offsetY = prevVecY * radius\n\t\t\t\tconst cpr = prevVecX * nextVecY - prevVecY * nextVecX\n\n\t\t\t\tif (cpr < 0) {\n\t\t\t\t\ttlx = pointX + offsetX\n\t\t\t\t\ttly = pointY + offsetY\n\t\t\t\t\ttrx = pointX - offsetX\n\t\t\t\t\ttrY = pointY - offsetY\n\t\t\t\t} else {\n\t\t\t\t\ttlx = pointX - offsetX\n\t\t\t\t\ttly = pointY - offsetY\n\t\t\t\t\ttrx = pointX + offsetX\n\t\t\t\t\ttrY = pointY + offsetY\n\t\t\t\t}\n\n\t\t\t\tlxs[lc] = tlx\n\t\t\t\tlys[lc] = tly\n\t\t\t\tlc++\n\t\t\t\trxs[rc] = trx\n\t\t\t\trys[rc] = trY\n\t\t\t\trc++\n\t\t\t} else {\n\t\t\t\t// Draw a \"sharp\" corner: rotate around the input point\n\t\t\t\tconst inX = six[i]\n\t\t\t\tconst inY = siy[i]\n\t\t\t\t// The arm swept around the point starts perpendicular to the\n\t\t\t\t// incoming direction, one radius long.\n\t\t\t\tconst dx = -prevVecY * radius\n\t\t\t\tconst dy = prevVecX * radius\n\n\t\t\t\tfor (let step = 1 / MAX_ROUNDED_CORNER_STEPS, t = 0; t < 1; t += step) {\n\t\t\t\t\tlet angle = FIXED_PI * t\n\t\t\t\t\tlet s = Math.sin(angle)\n\t\t\t\t\tlet c = Math.cos(angle)\n\t\t\t\t\ttlx = inX + (dx * c - dy * s)\n\t\t\t\t\ttly = inY + (dx * s + dy * c)\n\t\t\t\t\tlxs[lc] = tlx\n\t\t\t\t\tlys[lc] = tly\n\t\t\t\t\tlc++\n\n\t\t\t\t\tangle = FIXED_PI + FIXED_PI * -t\n\t\t\t\t\ts = Math.sin(angle)\n\t\t\t\t\tc = Math.cos(angle)\n\t\t\t\t\ttrx = inX + (dx * c - dy * s)\n\t\t\t\t\ttrY = inY + (dx * s + dy * c)\n\t\t\t\t\trxs[rc] = trx\n\t\t\t\t\trys[rc] = trY\n\t\t\t\t\trc++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tplx = tlx\n\t\t\tply = tly\n\t\t\tprx = trx\n\t\t\tpry = trY\n\n\t\t\tif (isNextPointSharpCorner) {\n\t\t\t\tisPrevPointSharpCorner = true\n\t\t\t}\n\n\t\t\tcontinue\n\t\t}\n\n\t\tisPrevPointSharpCorner = false\n\n\t\tif (scap[i]) {\n\t\t\t// Project one radius to each side, perpendicular to the direction of travel.\n\t\t\tconst offsetX = vecY * radius\n\t\t\tconst offsetY = -vecX * radius\n\t\t\tlxs[lc] = pointX - offsetX\n\t\t\tlys[lc] = pointY - offsetY\n\t\t\tlc++\n\t\t\trxs[rc] = pointX + offsetX\n\t\t\trys[rc] = pointY + offsetY\n\t\t\trc++\n\n\t\t\tcontinue\n\t\t}\n\n\t\t/*\n Add regular points\n\n Project points to either side of the current point, using the\n calculated size as a distance. If a point's distance to the\n previous point on that side greater than the minimum distance\n (or if the corner is kinda sharp), add the points to the side's\n points array.\n */\n\n\t\t// Project one radius to each side, perpendicular to the direction of\n\t\t// travel. The direction blends the current and next vectors, leaning\n\t\t// into the next vector as the upcoming turn sharpens.\n\t\tconst lerpedX = nextVecX + (vecX - nextVecX) * nextDpr\n\t\tconst lerpedY = nextVecY + (vecY - nextVecY) * nextDpr\n\t\tconst offsetX = lerpedY * radius\n\t\tconst offsetY = -lerpedX * radius\n\n\t\ttlx = pointX - offsetX\n\t\ttly = pointY - offsetY\n\n\t\tif (i <= 1 || (plx - tlx) ** 2 + (ply - tly) ** 2 > minDistance) {\n\t\t\tlxs[lc] = tlx\n\t\t\tlys[lc] = tly\n\t\t\tlc++\n\t\t\tplx = tlx\n\t\t\tply = tly\n\t\t}\n\n\t\ttrx = pointX + offsetX\n\t\ttrY = pointY + offsetY\n\n\t\tif (i <= 1 || (prx - trx) ** 2 + (pry - trY) ** 2 > minDistance) {\n\t\t\trxs[rc] = trx\n\t\t\trys[rc] = trY\n\t\t\trc++\n\t\t\tprx = trx\n\t\t\tpry = trY\n\t\t}\n\n\t\t// Set variables for next iteration\n\t\tprevVecX = vecX\n\t\tprevVecY = vecY\n\t}\n\n\tconst tolerance = size * TRACK_TOLERANCE_RATIO\n\n\ttrackLeftCount = simplifyTrack(trackLeftX, trackLeftY, lc, tolerance)\n\ttrackRightCount = simplifyTrack(trackRightX, trackRightY, rc, tolerance)\n}\n\n/**\n * @internal\n *\n * `vectorAnchor` is the original predecessor of `strokePoints[1]` when the caller has cut or\n * altered the sequence in front of it (svgInk's elbow partitions): the second point's vector is\n * derived from the anchor rather than from `strokePoints[0]`, preserving the direction it had in\n * the uncut stroke. It only applies when there are more than two points; two-point sequences\n * derive both vectors from each other.\n */\nexport function getStrokeOutlineTracks(\n\tstrokePoints: StrokePoint[],\n\toptions: StrokeOptions = {},\n\tvectorAnchor?: VecLike\n): { left: Vec[]; right: Vec[] } {\n\tloadSrcFromStrokePoints(strokePoints)\n\tbuildTracks(\n\t\toptions,\n\t\t!!vectorAnchor,\n\t\tvectorAnchor ? vectorAnchor.x : 0,\n\t\tvectorAnchor ? vectorAnchor.y : 0\n\t)\n\n\tconst lxs = trackLeftX\n\tconst lys = trackLeftY\n\tconst rxs = trackRightX\n\tconst rys = trackRightY\n\tconst left: Vec[] = new Array(trackLeftCount)\n\tfor (let i = 0; i < trackLeftCount; i++) {\n\t\tleft[i] = new Vec(lxs[i], lys[i])\n\t}\n\tconst right: Vec[] = new Array(trackRightCount)\n\tfor (let i = 0; i < trackRightCount; i++) {\n\t\tright[i] = new Vec(rxs[i], rys[i])\n\t}\n\treturn { left, right }\n}\n\n/** Pick a step count for a polygonal arc so its chord error stays within `tol`. */\nfunction arcSteps(radius: number, sweep: number, tol: number, min: number, max: number) {\n\tif (radius <= tol) return min\n\tconst maxAngle = 2 * Math.acos(1 - tol / radius)\n\tconst steps = Math.ceil(sweep / maxAngle)\n\treturn steps < min ? min : steps > max ? max : steps\n}\n\n/**\n * Build the full outline (tracks plus caps) for the stroke points currently loaded in the\n * track-source buffers. This is the shared core of `getStrokeOutlinePoints` and\n * `getStroke`.\n *\n * @internal\n */\nexport function outlineFromSrc(options: StrokeOptions = {}): Vec[] {\n\tconst { size = 16, start = {}, end = {}, last: isComplete = false } = options\n\n\tconst { cap: capStart = true } = start\n\tconst { cap: capEnd = true } = end\n\n\tconst n = srcCount\n\n\t// We can't do anything with an empty array or a stroke with negative size.\n\tif (n === 0 || size <= 0) {\n\t\treturn []\n\t}\n\n\t// The total length of the line\n\tconst totalLength = srcRunningLength[n - 1]\n\n\tconst taperStart = resolveTaper(start.taper, size, totalLength)\n\tconst taperEnd = resolveTaper(end.taper, size, totalLength)\n\n\t// Our collected left and right points\n\tbuildTracks(options, false, 0, 0)\n\n\t// Chord tolerance for the polygonal caps below: caps don't need a fixed number of segments,\n\t// they need enough segments that the polygon is indistinguishable from the arc.\n\tconst capTolerance = Math.max(0.05, size * 0.02)\n\n\tconst firstRadius = srcRadius[0]\n\tconst firstPoint = new Vec(srcX[0], srcY[0], srcZ[0])\n\n\tconst lastPoint =\n\t\tn > 1 ? new Vec(srcX[n - 1], srcY[n - 1], srcZ[n - 1]) : Vec.AddXY(firstPoint, 1, 1)\n\n\t/*\n Draw a dot for very short or completed strokes\n\n If the line is too short to gather left or right points and if the line is\n not tapered on either side, draw a dot. If the line is tapered, then only\n draw a dot if the line is both very short and complete. If we draw a dot,\n we can just return those points.\n */\n\n\tif (n === 1) {\n\t\tif (!(taperStart || taperEnd) || isComplete) {\n\t\t\tconst start = Vec.Add(\n\t\t\t\tfirstPoint,\n\t\t\t\tVec.Sub(firstPoint, lastPoint).uni().per().mul(-firstRadius)\n\t\t\t)\n\t\t\tconst dotPts: Vec[] = []\n\t\t\tconst steps = arcSteps(\n\t\t\t\tfirstRadius,\n\t\t\t\tFIXED_PI * 2,\n\t\t\t\tcapTolerance,\n\t\t\t\tMIN_ROUNDED_CORNER_STEPS,\n\t\t\t\tMAX_ROUNDED_CORNER_STEPS\n\t\t\t)\n\t\t\tfor (let step = 1 / steps, t = step; t <= 1; t += step) {\n\t\t\t\tdotPts.push(Vec.RotWith(start, firstPoint, FIXED_PI * 2 * t))\n\t\t\t}\n\t\t\treturn dotPts\n\t\t}\n\t}\n\n\t/*\n Draw a start cap\n\n Unless the line has a tapered start, or unless the line has a tapered end\n and the line is very short, draw a start cap around the first point. Use\n the distance between the second left and right point for the cap's radius.\n Finally remove the first left and right points. :psyduck:\n */\n\n\tconst startCap: Vec[] = []\n\tif (taperStart || (taperEnd && n === 1)) {\n\t\t// The start point is tapered, noop\n\t} else if (capStart) {\n\t\t// Draw the round cap - rotate the right point around the start point to the left point\n\t\tconst firstRight = new Vec(trackRightX[0], trackRightY[0])\n\t\tconst steps = arcSteps(firstRadius, FIXED_PI, capTolerance, 4, 8)\n\t\tfor (let step = 1 / steps, t = step; t <= 1; t += step) {\n\t\t\tconst pt = Vec.RotWith(firstRight, firstPoint, FIXED_PI * t)\n\t\t\tstartCap.push(pt)\n\t\t}\n\t} else {\n\t\t// Draw the flat cap - add a point to the left and right of the start point\n\t\tconst cornersVector = new Vec(trackLeftX[0] - trackRightX[0], trackLeftY[0] - trackRightY[0])\n\t\tconst offsetA = Vec.Mul(cornersVector, 0.5)\n\t\tconst offsetB = Vec.Mul(cornersVector, 0.51)\n\n\t\tstartCap.push(\n\t\t\tVec.Sub(firstPoint, offsetA),\n\t\t\tVec.Sub(firstPoint, offsetB),\n\t\t\tVec.Add(firstPoint, offsetB),\n\t\t\tVec.Add(firstPoint, offsetA)\n\t\t)\n\t}\n\n\t/*\n Draw an end cap\n\n If the line does not have a tapered end, and unless the line has a tapered\n start and the line is very short, draw a cap around the last point. Finally,\n remove the last left and right points. Otherwise, add the last point. Note\n that This cap is a full-turn-and-a-half: this prevents incorrect caps on\n sharp end turns.\n */\n\n\tconst endCap: Vec[] = []\n\tconst lastRadius = srcRadius[n - 1]\n\n\t// The exit vector at the last point points back at its predecessor,\n\t// normalized; a lone point keeps the legacy (1, 1). The cap then starts\n\t// perpendicular to that vector.\n\tlet lastVecX = 1\n\tlet lastVecY = 1\n\tif (n > 1) {\n\t\tconst dx = srcX[n - 2] - srcX[n - 1]\n\t\tconst dy = srcY[n - 2] - srcY[n - 1]\n\t\tconst l = (dx * dx + dy * dy) ** 0.5\n\t\tif (l === 0) {\n\t\t\tlastVecX = dx\n\t\t\tlastVecY = dy\n\t\t} else {\n\t\t\tlastVecX = dx / l\n\t\t\tlastVecY = dy / l\n\t\t}\n\t}\n\tconst direction = new Vec(-lastVecY, lastVecX)\n\n\tif (taperEnd || (taperStart && n === 1)) {\n\t\t// Tapered end - push the last point to the line\n\t\tendCap.push(lastPoint)\n\t} else if (capEnd) {\n\t\t// Draw the round end cap\n\t\tconst start = Vec.Add(lastPoint, Vec.Mul(direction, lastRadius))\n\t\tconst steps = arcSteps(lastRadius, FIXED_PI * 3, capTolerance, MIN_CAP_STEPS, MAX_CAP_STEPS)\n\t\tfor (let step = 1 / steps, t = step; t < 1; t += step) {\n\t\t\tendCap.push(Vec.RotWith(start, lastPoint, FIXED_PI * 3 * t))\n\t\t}\n\t} else {\n\t\t// Draw the flat end cap\n\t\tendCap.push(\n\t\t\tVec.Add(lastPoint, Vec.Mul(direction, lastRadius)),\n\t\t\tVec.Add(lastPoint, Vec.Mul(direction, lastRadius * 0.99)),\n\t\t\tVec.Sub(lastPoint, Vec.Mul(direction, lastRadius * 0.99)),\n\t\t\tVec.Sub(lastPoint, Vec.Mul(direction, lastRadius))\n\t\t)\n\t}\n\n\t/*\n Return the points in the correct winding order: begin on the left side, then\n continue around the end cap, then come back along the right side, and finally\n complete the start cap.\n */\n\n\tconst lxs = trackLeftX\n\tconst lys = trackLeftY\n\tconst rxs = trackRightX\n\tconst rys = trackRightY\n\tconst leftPts: Vec[] = new Array(trackLeftCount)\n\tfor (let i = 0; i < trackLeftCount; i++) {\n\t\tleftPts[i] = new Vec(lxs[i], lys[i])\n\t}\n\tconst rightPtsReversed: Vec[] = new Array(trackRightCount)\n\tfor (let i = 0; i < trackRightCount; i++) {\n\t\trightPtsReversed[i] = new Vec(rxs[trackRightCount - 1 - i], rys[trackRightCount - 1 - i])\n\t}\n\n\treturn leftPts.concat(endCap, rightPtsReversed, startCap)\n}\n\n/**\n * ## getStrokeOutlinePoints\n *\n * Get an array of points (as `[x, y]`) representing the outline of a stroke.\n *\n * @param points - An array of StrokePoints as returned from `getStrokePoints`.\n * @param options - An object with options.\n * @public\n */\nexport function getStrokeOutlinePoints(\n\tstrokePoints: StrokePoint[],\n\toptions: StrokeOptions = {}\n): Vec[] {\n\tloadSrcFromStrokePoints(strokePoints)\n\treturn outlineFromSrc(options)\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,WAAoB;AAC7B;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAGP,MAAM,EAAE,GAAG,IAAI;AAGf,MAAM,WAAW,KAAK;AAKtB,MAAM,wBAAwB;AAG9B,MAAM,kBAAkB;AAGxB,MAAM,2BAA2B;AACjC,MAAM,2BAA2B;AAGjC,MAAM,gBAAgB;AACtB,MAAM,gBAAgB;AAGtB,MAAM,kBAAkB;AAQxB,IAAI,gBAAgB;AACb,IAAI,aAAa,IAAI,aAAa,aAAa;AAC/C,IAAI,aAAa,IAAI,aAAa,aAAa;AAC/C,IAAI,cAAc,IAAI,aAAa,aAAa;AAChD,IAAI,cAAc,IAAI,aAAa,aAAa;AAChD,IAAI,iBAAiB;AACrB,IAAI,kBAAkB;AAI7B,SAAS,aAAa;AACrB,mBAAiB;AACjB,QAAM,MAAM,IAAI,aAAa,aAAa;AAC1C,MAAI,IAAI,UAAU;AAClB,eAAa;AACb,QAAM,MAAM,IAAI,aAAa,aAAa;AAC1C,MAAI,IAAI,UAAU;AAClB,eAAa;AACb,QAAM,MAAM,IAAI,aAAa,aAAa;AAC1C,MAAI,IAAI,WAAW;AACnB,gBAAc;AACd,QAAM,MAAM,IAAI,aAAa,aAAa;AAC1C,MAAI,IAAI,WAAW;AACnB,gBAAc;AACf;AAeA,SAAS,cAAc,IAAkB,IAAkB,KAAa,KAAqB;AAC5F,MAAI,OAAO,KAAK,OAAO,EAAG,QAAO;AACjC,QAAM,OAAO,MAAM;AACnB,MAAI,MAAM;AACV,MAAI,SAAS;AACb,QAAM,UAAU,MAAM;AACtB,SAAO,SAAS,SAAS;AACxB,QAAI,OAAO,SAAS;AACpB,UAAM,OAAO,SAAS,kBAAkB,UAAU,UAAU,SAAS;AACrE,UAAM,KAAK,GAAG,MAAM;AACpB,UAAM,KAAK,GAAG,MAAM;AACpB,UAAO,UAAS,IAAI,SAAS,GAAG,KAAK,MAAM,KAAK;AAC/C,YAAM,MAAM,GAAG,CAAC,IAAI;AACpB,YAAM,MAAM,GAAG,CAAC,IAAI;AACpB,YAAM,KAAK,MAAM,MAAM,MAAM;AAC7B,eAAS,IAAI,SAAS,GAAG,IAAI,GAAG,KAAK;AACpC,YAAI,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,OAAO,GAAG,CAAC,IAAI,MAAM,OAAO;AACnE,YAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAC5B,cAAM,KAAK,GAAG,CAAC,KAAK,KAAK,MAAM;AAC/B,cAAM,KAAK,GAAG,CAAC,KAAK,KAAK,MAAM;AAC/B,YAAI,KAAK,KAAK,KAAK,KAAK,KAAM,OAAM;AAAA,MACrC;AACA,aAAO;AAAA,IACR;AAEA,OAAG,GAAG,IAAI,GAAG,IAAI;AACjB,OAAG,GAAG,IAAI,GAAG,IAAI;AACjB;AACA,aAAS;AAAA,EACV;AACA,SAAO;AACR;AAeO,SAAS,YACf,SACA,WACA,SACA,SACO;AACP,QAAM,EAAE,OAAO,IAAI,YAAY,IAAI,IAAI;AAEvC,MAAI,KAAK;AACT,MAAI,KAAK;AACT,mBAAiB;AACjB,oBAAkB;AAElB,QAAM,IAAI;AAGV,MAAI,MAAM,KAAK,QAAQ,EAAG;AAI1B,QAAM,KAAK;AACX,QAAM,KAAK;AACX,QAAM,MAAM;AACZ,QAAM,MAAM;AACZ,QAAM,KAAK;AACX,QAAM,MAAM;AACZ,QAAM,OAAO;AACb,MAAI,MAAM;AACV,MAAI,MAAM;AACV,MAAI,MAAM;AACV,MAAI,MAAM;AAGV,QAAM,cAAc,IAAI,IAAI,CAAC;AAG7B,QAAM,cAAc,KAAK,IAAI,OAAO,WAAW,CAAC;AAMhD,MAAI,UAAU;AACd,MAAI,UAAU;AACd,MAAI,IAAI,GAAG;AACV,UAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC;AACvB,UAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC;AACvB,UAAM,KAAK,KAAK,KAAK,KAAK,OAAO;AACjC,QAAI,MAAM,GAAG;AACZ,gBAAU;AACV,gBAAU;AAAA,IACX,OAAO;AACN,gBAAU,KAAK;AACf,gBAAU,KAAK;AAAA,IAChB;AAAA,EACD;AAGA,MAAI,WAAW;AACf,MAAI,WAAW;AAGf,MAAI,MAAM,GAAG,CAAC;AACd,MAAI,MAAM,GAAG,CAAC;AACd,MAAI,MAAM;AACV,MAAI,MAAM;AAGV,MAAI,MAAM;AACV,MAAI,MAAM;AACV,MAAI,MAAM;AACV,MAAI,MAAM;AAIV,MAAI,yBAAyB;AAS7B,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,UAAM,SAAS,GAAG,CAAC;AACnB,UAAM,SAAS,GAAG,CAAC;AACnB,UAAM,SAAS,GAAG,CAAC;AACnB,UAAM,OAAO;AACb,UAAM,OAAO;AAIb,QAAI,WAAW;AACf,QAAI,WAAW;AACf,QAAI,IAAI,IAAI,GAAG;AACd,YAAM,QAAQ,MAAM,KAAK,IAAI,KAAK,YAAY,UAAU;AACxD,YAAM,QAAQ,MAAM,KAAK,IAAI,KAAK,YAAY,UAAU;AACxD,YAAM,KAAK,QAAQ,GAAG,IAAI,CAAC;AAC3B,YAAM,KAAK,QAAQ,GAAG,IAAI,CAAC;AAC3B,YAAM,KAAK,KAAK,KAAK,KAAK,OAAO;AACjC,UAAI,MAAM,GAAG;AACZ,mBAAW;AACX,mBAAW;AAAA,MACZ,OAAO;AACN,mBAAW,KAAK;AAChB,mBAAW,KAAK;AAAA,MACjB;AAAA,IACD;AACA,cAAU;AACV,cAAU;AAGV,QACC,KAAK,2BAA2B,IAAI,iBACpC,KAAK,2BAA2B,IAAI,eACnC;AACD,iBAAW;AACX,YAAM;AACN,YAAM;AACN,YAAM;AACN,YAAM;AAAA,IACP;AAUA,UAAM,UAAU,OAAO,WAAW,OAAO;AACzC,UAAM,UAAU,IAAI,IAAI,IAAI,WAAW,OAAO,WAAW,OAAO;AAEhE,UAAM,qBAAqB,UAAU,KAAK,CAAC;AAC3C,UAAM,yBAAyB,UAAU;AAEzC,QAAI,sBAAsB,wBAAwB;AAKjD,UAAI,UAAU,mBAAmB,cAAc,IAAI,CAAC,IAAI,QAAQ;AAE/D,cAAMA,WAAU,WAAW;AAC3B,cAAMC,WAAU,WAAW;AAC3B,cAAM,MAAM,WAAW,WAAW,WAAW;AAE7C,YAAI,MAAM,GAAG;AACZ,gBAAM,SAASD;AACf,gBAAM,SAASC;AACf,gBAAM,SAASD;AACf,gBAAM,SAASC;AAAA,QAChB,OAAO;AACN,gBAAM,SAASD;AACf,gBAAM,SAASC;AACf,gBAAM,SAASD;AACf,gBAAM,SAASC;AAAA,QAChB;AAEA,YAAI,EAAE,IAAI;AACV,YAAI,EAAE,IAAI;AACV;AACA,YAAI,EAAE,IAAI;AACV,YAAI,EAAE,IAAI;AACV;AAAA,MACD,OAAO;AAEN,cAAM,MAAM,IAAI,CAAC;AACjB,cAAM,MAAM,IAAI,CAAC;AAGjB,cAAM,KAAK,CAAC,WAAW;AACvB,cAAM,KAAK,WAAW;AAEtB,iBAAS,OAAO,IAAI,0BAA0B,IAAI,GAAG,IAAI,GAAG,KAAK,MAAM;AACtE,cAAI,QAAQ,WAAW;AACvB,cAAI,IAAI,KAAK,IAAI,KAAK;AACtB,cAAI,IAAI,KAAK,IAAI,KAAK;AACtB,gBAAM,OAAO,KAAK,IAAI,KAAK;AAC3B,gBAAM,OAAO,KAAK,IAAI,KAAK;AAC3B,cAAI,EAAE,IAAI;AACV,cAAI,EAAE,IAAI;AACV;AAEA,kBAAQ,WAAW,WAAW,CAAC;AAC/B,cAAI,KAAK,IAAI,KAAK;AAClB,cAAI,KAAK,IAAI,KAAK;AAClB,gBAAM,OAAO,KAAK,IAAI,KAAK;AAC3B,gBAAM,OAAO,KAAK,IAAI,KAAK;AAC3B,cAAI,EAAE,IAAI;AACV,cAAI,EAAE,IAAI;AACV;AAAA,QACD;AAAA,MACD;AAEA,YAAM;AACN,YAAM;AACN,YAAM;AACN,YAAM;AAEN,UAAI,wBAAwB;AAC3B,iCAAyB;AAAA,MAC1B;AAEA;AAAA,IACD;AAEA,6BAAyB;AAEzB,QAAI,KAAK,CAAC,GAAG;AAEZ,YAAMD,WAAU,OAAO;AACvB,YAAMC,WAAU,CAAC,OAAO;AACxB,UAAI,EAAE,IAAI,SAASD;AACnB,UAAI,EAAE,IAAI,SAASC;AACnB;AACA,UAAI,EAAE,IAAI,SAASD;AACnB,UAAI,EAAE,IAAI,SAASC;AACnB;AAEA;AAAA,IACD;AAeA,UAAM,UAAU,YAAY,OAAO,YAAY;AAC/C,UAAM,UAAU,YAAY,OAAO,YAAY;AAC/C,UAAM,UAAU,UAAU;AAC1B,UAAM,UAAU,CAAC,UAAU;AAE3B,UAAM,SAAS;AACf,UAAM,SAAS;AAEf,QAAI,KAAK,MAAM,MAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI,aAAa;AAChE,UAAI,EAAE,IAAI;AACV,UAAI,EAAE,IAAI;AACV;AACA,YAAM;AACN,YAAM;AAAA,IACP;AAEA,UAAM,SAAS;AACf,UAAM,SAAS;AAEf,QAAI,KAAK,MAAM,MAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI,aAAa;AAChE,UAAI,EAAE,IAAI;AACV,UAAI,EAAE,IAAI;AACV;AACA,YAAM;AACN,YAAM;AAAA,IACP;AAGA,eAAW;AACX,eAAW;AAAA,EACZ;AAEA,QAAM,YAAY,OAAO;AAEzB,mBAAiB,cAAc,YAAY,YAAY,IAAI,SAAS;AACpE,oBAAkB,cAAc,aAAa,aAAa,IAAI,SAAS;AACxE;AAWO,SAAS,uBACf,cACA,UAAyB,CAAC,GAC1B,cACgC;AAChC,0BAAwB,YAAY;AACpC;AAAA,IACC;AAAA,IACA,CAAC,CAAC;AAAA,IACF,eAAe,aAAa,IAAI;AAAA,IAChC,eAAe,aAAa,IAAI;AAAA,EACjC;AAEA,QAAM,MAAM;AACZ,QAAM,MAAM;AACZ,QAAM,MAAM;AACZ,QAAM,MAAM;AACZ,QAAM,OAAc,IAAI,MAAM,cAAc;AAC5C,WAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACxC,SAAK,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAAA,EACjC;AACA,QAAM,QAAe,IAAI,MAAM,eAAe;AAC9C,WAAS,IAAI,GAAG,IAAI,iBAAiB,KAAK;AACzC,UAAM,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAAA,EAClC;AACA,SAAO,EAAE,MAAM,MAAM;AACtB;AAGA,SAAS,SAAS,QAAgB,OAAe,KAAa,KAAa,KAAa;AACvF,MAAI,UAAU,IAAK,QAAO;AAC1B,QAAM,WAAW,IAAI,KAAK,KAAK,IAAI,MAAM,MAAM;AAC/C,QAAM,QAAQ,KAAK,KAAK,QAAQ,QAAQ;AACxC,SAAO,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM;AAChD;AASO,SAAS,eAAe,UAAyB,CAAC,GAAU;AAClE,QAAM,EAAE,OAAO,IAAI,QAAQ,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,aAAa,MAAM,IAAI;AAEtE,QAAM,EAAE,KAAK,WAAW,KAAK,IAAI;AACjC,QAAM,EAAE,KAAK,SAAS,KAAK,IAAI;AAE/B,QAAM,IAAI;AAGV,MAAI,MAAM,KAAK,QAAQ,GAAG;AACzB,WAAO,CAAC;AAAA,EACT;AAGA,QAAM,cAAc,iBAAiB,IAAI,CAAC;AAE1C,QAAM,aAAa,aAAa,MAAM,OAAO,MAAM,WAAW;AAC9D,QAAM,WAAW,aAAa,IAAI,OAAO,MAAM,WAAW;AAG1D,cAAY,SAAS,OAAO,GAAG,CAAC;AAIhC,QAAM,eAAe,KAAK,IAAI,MAAM,OAAO,IAAI;AAE/C,QAAM,cAAc,UAAU,CAAC;AAC/B,QAAM,aAAa,IAAI,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AAEpD,QAAM,YACL,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,IAAI,IAAI,MAAM,YAAY,GAAG,CAAC;AAWpF,MAAI,MAAM,GAAG;AACZ,QAAI,EAAE,cAAc,aAAa,YAAY;AAC5C,YAAMC,SAAQ,IAAI;AAAA,QACjB;AAAA,QACA,IAAI,IAAI,YAAY,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW;AAAA,MAC5D;AACA,YAAM,SAAgB,CAAC;AACvB,YAAM,QAAQ;AAAA,QACb;AAAA,QACA,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,MACD;AACA,eAAS,OAAO,IAAI,OAAO,IAAI,MAAM,KAAK,GAAG,KAAK,MAAM;AACvD,eAAO,KAAK,IAAI,QAAQA,QAAO,YAAY,WAAW,IAAI,CAAC,CAAC;AAAA,MAC7D;AACA,aAAO;AAAA,IACR;AAAA,EACD;AAWA,QAAM,WAAkB,CAAC;AACzB,MAAI,cAAe,YAAY,MAAM,GAAI;AAAA,EAEzC,WAAW,UAAU;AAEpB,UAAM,aAAa,IAAI,IAAI,YAAY,CAAC,GAAG,YAAY,CAAC,CAAC;AACzD,UAAM,QAAQ,SAAS,aAAa,UAAU,cAAc,GAAG,CAAC;AAChE,aAAS,OAAO,IAAI,OAAO,IAAI,MAAM,KAAK,GAAG,KAAK,MAAM;AACvD,YAAM,KAAK,IAAI,QAAQ,YAAY,YAAY,WAAW,CAAC;AAC3D,eAAS,KAAK,EAAE;AAAA,IACjB;AAAA,EACD,OAAO;AAEN,UAAM,gBAAgB,IAAI,IAAI,WAAW,CAAC,IAAI,YAAY,CAAC,GAAG,WAAW,CAAC,IAAI,YAAY,CAAC,CAAC;AAC5F,UAAM,UAAU,IAAI,IAAI,eAAe,GAAG;AAC1C,UAAM,UAAU,IAAI,IAAI,eAAe,IAAI;AAE3C,aAAS;AAAA,MACR,IAAI,IAAI,YAAY,OAAO;AAAA,MAC3B,IAAI,IAAI,YAAY,OAAO;AAAA,MAC3B,IAAI,IAAI,YAAY,OAAO;AAAA,MAC3B,IAAI,IAAI,YAAY,OAAO;AAAA,IAC5B;AAAA,EACD;AAYA,QAAM,SAAgB,CAAC;AACvB,QAAM,aAAa,UAAU,IAAI,CAAC;AAKlC,MAAI,WAAW;AACf,MAAI,WAAW;AACf,MAAI,IAAI,GAAG;AACV,UAAM,KAAK,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC;AACnC,UAAM,KAAK,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC;AACnC,UAAM,KAAK,KAAK,KAAK,KAAK,OAAO;AACjC,QAAI,MAAM,GAAG;AACZ,iBAAW;AACX,iBAAW;AAAA,IACZ,OAAO;AACN,iBAAW,KAAK;AAChB,iBAAW,KAAK;AAAA,IACjB;AAAA,EACD;AACA,QAAM,YAAY,IAAI,IAAI,CAAC,UAAU,QAAQ;AAE7C,MAAI,YAAa,cAAc,MAAM,GAAI;AAExC,WAAO,KAAK,SAAS;AAAA,EACtB,WAAW,QAAQ;AAElB,UAAMA,SAAQ,IAAI,IAAI,WAAW,IAAI,IAAI,WAAW,UAAU,CAAC;AAC/D,UAAM,QAAQ,SAAS,YAAY,WAAW,GAAG,cAAc,eAAe,aAAa;AAC3F,aAAS,OAAO,IAAI,OAAO,IAAI,MAAM,IAAI,GAAG,KAAK,MAAM;AACtD,aAAO,KAAK,IAAI,QAAQA,QAAO,WAAW,WAAW,IAAI,CAAC,CAAC;AAAA,IAC5D;AAAA,EACD,OAAO;AAEN,WAAO;AAAA,MACN,IAAI,IAAI,WAAW,IAAI,IAAI,WAAW,UAAU,CAAC;AAAA,MACjD,IAAI,IAAI,WAAW,IAAI,IAAI,WAAW,aAAa,IAAI,CAAC;AAAA,MACxD,IAAI,IAAI,WAAW,IAAI,IAAI,WAAW,aAAa,IAAI,CAAC;AAAA,MACxD,IAAI,IAAI,WAAW,IAAI,IAAI,WAAW,UAAU,CAAC;AAAA,IAClD;AAAA,EACD;AAQA,QAAM,MAAM;AACZ,QAAM,MAAM;AACZ,QAAM,MAAM;AACZ,QAAM,MAAM;AACZ,QAAM,UAAiB,IAAI,MAAM,cAAc;AAC/C,WAAS,IAAI,GAAG,IAAI,gBAAgB,KAAK;AACxC,YAAQ,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAAA,EACpC;AACA,QAAM,mBAA0B,IAAI,MAAM,eAAe;AACzD,WAAS,IAAI,GAAG,IAAI,iBAAiB,KAAK;AACzC,qBAAiB,CAAC,IAAI,IAAI,IAAI,IAAI,kBAAkB,IAAI,CAAC,GAAG,IAAI,kBAAkB,IAAI,CAAC,CAAC;AAAA,EACzF;AAEA,SAAO,QAAQ,OAAO,QAAQ,kBAAkB,QAAQ;AACzD;AAWO,SAAS,uBACf,cACA,UAAyB,CAAC,GAClB;AACR,0BAAwB,YAAY;AACpC,SAAO,eAAe,OAAO;AAC9B;",
|
|
6
|
+
"names": ["offsetX", "offsetY", "start"]
|
|
7
7
|
}
|