@tldraw/editor 3.15.0-canary.d251cd98b4e1 → 3.15.0-canary.d48536dd9c3c

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.
Files changed (103) hide show
  1. package/dist-cjs/index.d.ts +10 -4
  2. package/dist-cjs/index.js +3 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/SVGContainer.js +1 -1
  5. package/dist-cjs/lib/components/SVGContainer.js.map +2 -2
  6. package/dist-cjs/lib/components/default-components/DefaultBrush.js +1 -1
  7. package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +2 -2
  8. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +1 -1
  9. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  10. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +1 -1
  11. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +2 -2
  12. package/dist-cjs/lib/components/default-components/DefaultCursor.js +1 -1
  13. package/dist-cjs/lib/components/default-components/DefaultCursor.js.map +2 -2
  14. package/dist-cjs/lib/components/default-components/DefaultGrid.js +1 -1
  15. package/dist-cjs/lib/components/default-components/DefaultGrid.js.map +2 -2
  16. package/dist-cjs/lib/components/default-components/DefaultHandles.js +1 -1
  17. package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +2 -2
  18. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +1 -1
  19. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  20. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +1 -1
  21. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +2 -2
  22. package/dist-cjs/lib/components/default-components/DefaultSpinner.js +27 -15
  23. package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +3 -3
  24. package/dist-cjs/lib/editor/Editor.js +24 -8
  25. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  26. package/dist-cjs/lib/hooks/useEditorComponents.js.map +1 -1
  27. package/dist-cjs/lib/license/Watermark.js +2 -2
  28. package/dist-cjs/lib/license/Watermark.js.map +2 -2
  29. package/dist-cjs/lib/primitives/geometry/Arc2d.js +1 -1
  30. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  31. package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
  32. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  33. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +3 -1
  34. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
  35. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +1 -1
  36. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  37. package/dist-cjs/lib/primitives/geometry/geometry-constants.js +2 -2
  38. package/dist-cjs/lib/primitives/geometry/geometry-constants.js.map +2 -2
  39. package/dist-cjs/version.js +3 -3
  40. package/dist-cjs/version.js.map +1 -1
  41. package/dist-esm/index.d.mts +10 -4
  42. package/dist-esm/index.mjs +3 -1
  43. package/dist-esm/index.mjs.map +2 -2
  44. package/dist-esm/lib/components/SVGContainer.mjs +1 -1
  45. package/dist-esm/lib/components/SVGContainer.mjs.map +2 -2
  46. package/dist-esm/lib/components/default-components/DefaultBrush.mjs +1 -1
  47. package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +2 -2
  48. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +1 -1
  49. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  50. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +1 -1
  51. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +2 -2
  52. package/dist-esm/lib/components/default-components/DefaultCursor.mjs +1 -1
  53. package/dist-esm/lib/components/default-components/DefaultCursor.mjs.map +2 -2
  54. package/dist-esm/lib/components/default-components/DefaultGrid.mjs +1 -1
  55. package/dist-esm/lib/components/default-components/DefaultGrid.mjs.map +2 -2
  56. package/dist-esm/lib/components/default-components/DefaultHandles.mjs +1 -1
  57. package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +2 -2
  58. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +1 -1
  59. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  60. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +1 -1
  61. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +2 -2
  62. package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +17 -15
  63. package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
  64. package/dist-esm/lib/editor/Editor.mjs +24 -8
  65. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  66. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +1 -1
  67. package/dist-esm/lib/license/Watermark.mjs +2 -2
  68. package/dist-esm/lib/license/Watermark.mjs.map +2 -2
  69. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
  70. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  71. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +2 -2
  72. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  73. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +3 -1
  74. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
  75. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +2 -2
  76. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  77. package/dist-esm/lib/primitives/geometry/geometry-constants.mjs +2 -2
  78. package/dist-esm/lib/primitives/geometry/geometry-constants.mjs.map +2 -2
  79. package/dist-esm/version.mjs +3 -3
  80. package/dist-esm/version.mjs.map +1 -1
  81. package/editor.css +17 -4
  82. package/package.json +9 -8
  83. package/src/index.ts +1 -0
  84. package/src/lib/components/SVGContainer.tsx +1 -1
  85. package/src/lib/components/default-components/DefaultBrush.tsx +1 -1
  86. package/src/lib/components/default-components/DefaultCanvas.tsx +1 -1
  87. package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +1 -1
  88. package/src/lib/components/default-components/DefaultCursor.tsx +1 -1
  89. package/src/lib/components/default-components/DefaultGrid.tsx +1 -1
  90. package/src/lib/components/default-components/DefaultHandles.tsx +5 -1
  91. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +1 -1
  92. package/src/lib/components/default-components/DefaultSnapIndictor.tsx +1 -1
  93. package/src/lib/components/default-components/DefaultSpinner.tsx +12 -12
  94. package/src/lib/editor/Editor.test.ts +407 -0
  95. package/src/lib/editor/Editor.ts +35 -9
  96. package/src/lib/hooks/useEditorComponents.tsx +1 -1
  97. package/src/lib/license/Watermark.tsx +2 -2
  98. package/src/lib/primitives/geometry/Arc2d.ts +2 -2
  99. package/src/lib/primitives/geometry/Circle2d.ts +2 -2
  100. package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -1
  101. package/src/lib/primitives/geometry/Ellipse2d.ts +2 -2
  102. package/src/lib/primitives/geometry/geometry-constants.ts +2 -1
  103. package/src/version.ts +3 -3
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/hooks/useEditorComponents.tsx"],
4
- "sourcesContent": ["import { ComponentType, ReactNode, createContext, useContext, useMemo } from 'react'\nimport { DefaultBackground } from '../components/default-components/DefaultBackground'\nimport { DefaultBrush, TLBrushProps } from '../components/default-components/DefaultBrush'\nimport {\n\tDefaultCanvas,\n\tTLCanvasComponentProps,\n} from '../components/default-components/DefaultCanvas'\nimport {\n\tDefaultCollaboratorHint,\n\tTLCollaboratorHintProps,\n} from '../components/default-components/DefaultCollaboratorHint'\nimport { DefaultCursor, TLCursorProps } from '../components/default-components/DefaultCursor'\nimport {\n\tDefaultErrorFallback,\n\tTLErrorFallbackComponent,\n} from '../components/default-components/DefaultErrorFallback'\nimport { DefaultGrid, TLGridProps } from '../components/default-components/DefaultGrid'\nimport { DefaultHandle, TLHandleProps } from '../components/default-components/DefaultHandle'\nimport { DefaultHandles, TLHandlesProps } from '../components/default-components/DefaultHandles'\nimport { DefaultLoadingScreen } from '../components/default-components/DefaultLoadingScreen'\nimport { DefaultScribble, TLScribbleProps } from '../components/default-components/DefaultScribble'\nimport { TLSelectionBackgroundProps } from '../components/default-components/DefaultSelectionBackground'\nimport {\n\tDefaultSelectionForeground,\n\tTLSelectionForegroundProps,\n} from '../components/default-components/DefaultSelectionForeground'\nimport {\n\tDefaultShapeErrorFallback,\n\tTLShapeErrorFallbackComponent,\n} from '../components/default-components/DefaultShapeErrorFallback'\nimport {\n\tDefaultShapeIndicator,\n\tTLShapeIndicatorProps,\n} from '../components/default-components/DefaultShapeIndicator'\nimport {\n\tDefaultShapeIndicatorErrorFallback,\n\tTLShapeIndicatorErrorFallbackComponent,\n} from '../components/default-components/DefaultShapeIndicatorErrorFallback'\nimport { DefaultShapeIndicators } from '../components/default-components/DefaultShapeIndicators'\nimport {\n\tDefaultSnapIndicator,\n\tTLSnapIndicatorProps,\n} from '../components/default-components/DefaultSnapIndictor'\nimport { DefaultSpinner } from '../components/default-components/DefaultSpinner'\nimport { DefaultSvgDefs } from '../components/default-components/DefaultSvgDefs'\nimport { useShallowObjectIdentity } from './useIdentity'\n\n/** @public */\nexport interface TLEditorComponents {\n\tBackground?: ComponentType | null\n\tBrush?: ComponentType<TLBrushProps> | null\n\tCanvas?: ComponentType<TLCanvasComponentProps> | null\n\tCollaboratorBrush?: ComponentType<TLBrushProps> | null\n\tCollaboratorCursor?: ComponentType<TLCursorProps> | null\n\tCollaboratorHint?: ComponentType<TLCollaboratorHintProps> | null\n\tCollaboratorScribble?: ComponentType<TLScribbleProps> | null\n\tCollaboratorShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null\n\tCursor?: ComponentType<TLCursorProps> | null\n\tGrid?: ComponentType<TLGridProps> | null\n\tHandle?: ComponentType<TLHandleProps> | null\n\tHandles?: ComponentType<TLHandlesProps> | null\n\tInFrontOfTheCanvas?: ComponentType | null\n\tLoadingScreen?: ComponentType | null\n\tOnTheCanvas?: ComponentType | null\n\tOverlays?: ComponentType | null\n\tScribble?: ComponentType<TLScribbleProps> | null\n\tSelectionBackground?: ComponentType<TLSelectionBackgroundProps> | null\n\tSelectionForeground?: ComponentType<TLSelectionForegroundProps> | null\n\tShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null\n\tShapeIndicators?: ComponentType | null\n\tSnapIndicator?: ComponentType<TLSnapIndicatorProps> | null\n\tSpinner?: ComponentType | null\n\tSvgDefs?: ComponentType | null\n\tZoomBrush?: ComponentType<TLBrushProps> | null\n\n\t// These will always have defaults\n\tErrorFallback?: TLErrorFallbackComponent\n\tShapeErrorFallback?: TLShapeErrorFallbackComponent\n\tShapeIndicatorErrorFallback?: TLShapeIndicatorErrorFallbackComponent\n}\n\nconst EditorComponentsContext = createContext<null | Required<TLEditorComponents>>(null)\n\ninterface ComponentsContextProviderProps {\n\toverrides?: TLEditorComponents\n\tchildren: ReactNode\n}\n\nexport function EditorComponentsProvider({\n\toverrides = {},\n\tchildren,\n}: ComponentsContextProviderProps) {\n\tconst _overrides = useShallowObjectIdentity(overrides)\n\tconst value = useMemo(\n\t\t(): Required<TLEditorComponents> => ({\n\t\t\tBackground: DefaultBackground,\n\t\t\tBrush: DefaultBrush,\n\t\t\tCanvas: DefaultCanvas,\n\t\t\tCollaboratorBrush: DefaultBrush,\n\t\t\tCollaboratorCursor: DefaultCursor,\n\t\t\tCollaboratorHint: DefaultCollaboratorHint,\n\t\t\tCollaboratorScribble: DefaultScribble,\n\t\t\tCollaboratorShapeIndicator: DefaultShapeIndicator,\n\t\t\tCursor: DefaultCursor,\n\t\t\tGrid: DefaultGrid,\n\t\t\tHandle: DefaultHandle,\n\t\t\tHandles: DefaultHandles,\n\t\t\tInFrontOfTheCanvas: null,\n\t\t\tLoadingScreen: DefaultLoadingScreen,\n\t\t\tOnTheCanvas: null,\n\t\t\tOverlays: null,\n\t\t\tScribble: DefaultScribble,\n\t\t\tSelectionBackground: null,\n\t\t\tSelectionForeground: DefaultSelectionForeground,\n\t\t\tShapeIndicator: DefaultShapeIndicator,\n\t\t\tShapeIndicators: DefaultShapeIndicators,\n\t\t\tSnapIndicator: DefaultSnapIndicator,\n\t\t\tSpinner: DefaultSpinner,\n\t\t\tSvgDefs: DefaultSvgDefs,\n\t\t\tZoomBrush: DefaultBrush,\n\n\t\t\tErrorFallback: DefaultErrorFallback,\n\t\t\tShapeErrorFallback: DefaultShapeErrorFallback,\n\t\t\tShapeIndicatorErrorFallback: DefaultShapeIndicatorErrorFallback,\n\n\t\t\t..._overrides,\n\t\t}),\n\t\t[_overrides]\n\t)\n\n\treturn (\n\t\t<EditorComponentsContext.Provider value={value}>{children}</EditorComponentsContext.Provider>\n\t)\n}\n\n/** @public */\nexport function useEditorComponents() {\n\tconst components = useContext(EditorComponentsContext)\n\tif (!components) {\n\t\tthrow new Error('useEditorComponents must be used inside of <EditorComponentsProvider />')\n\t}\n\treturn components\n}\n"],
4
+ "sourcesContent": ["import { ComponentType, ReactNode, createContext, useContext, useMemo } from 'react'\nimport { DefaultBackground } from '../components/default-components/DefaultBackground'\nimport { DefaultBrush, TLBrushProps } from '../components/default-components/DefaultBrush'\nimport {\n\tDefaultCanvas,\n\tTLCanvasComponentProps,\n} from '../components/default-components/DefaultCanvas'\nimport {\n\tDefaultCollaboratorHint,\n\tTLCollaboratorHintProps,\n} from '../components/default-components/DefaultCollaboratorHint'\nimport { DefaultCursor, TLCursorProps } from '../components/default-components/DefaultCursor'\nimport {\n\tDefaultErrorFallback,\n\tTLErrorFallbackComponent,\n} from '../components/default-components/DefaultErrorFallback'\nimport { DefaultGrid, TLGridProps } from '../components/default-components/DefaultGrid'\nimport { DefaultHandle, TLHandleProps } from '../components/default-components/DefaultHandle'\nimport { DefaultHandles, TLHandlesProps } from '../components/default-components/DefaultHandles'\nimport { DefaultLoadingScreen } from '../components/default-components/DefaultLoadingScreen'\nimport { DefaultScribble, TLScribbleProps } from '../components/default-components/DefaultScribble'\nimport { TLSelectionBackgroundProps } from '../components/default-components/DefaultSelectionBackground'\nimport {\n\tDefaultSelectionForeground,\n\tTLSelectionForegroundProps,\n} from '../components/default-components/DefaultSelectionForeground'\nimport {\n\tDefaultShapeErrorFallback,\n\tTLShapeErrorFallbackComponent,\n} from '../components/default-components/DefaultShapeErrorFallback'\nimport {\n\tDefaultShapeIndicator,\n\tTLShapeIndicatorProps,\n} from '../components/default-components/DefaultShapeIndicator'\nimport {\n\tDefaultShapeIndicatorErrorFallback,\n\tTLShapeIndicatorErrorFallbackComponent,\n} from '../components/default-components/DefaultShapeIndicatorErrorFallback'\nimport { DefaultShapeIndicators } from '../components/default-components/DefaultShapeIndicators'\nimport {\n\tDefaultSnapIndicator,\n\tTLSnapIndicatorProps,\n} from '../components/default-components/DefaultSnapIndictor'\nimport { DefaultSpinner } from '../components/default-components/DefaultSpinner'\nimport { DefaultSvgDefs } from '../components/default-components/DefaultSvgDefs'\nimport { useShallowObjectIdentity } from './useIdentity'\n\n/** @public */\nexport interface TLEditorComponents {\n\tBackground?: ComponentType | null\n\tBrush?: ComponentType<TLBrushProps> | null\n\tCanvas?: ComponentType<TLCanvasComponentProps> | null\n\tCollaboratorBrush?: ComponentType<TLBrushProps> | null\n\tCollaboratorCursor?: ComponentType<TLCursorProps> | null\n\tCollaboratorHint?: ComponentType<TLCollaboratorHintProps> | null\n\tCollaboratorScribble?: ComponentType<TLScribbleProps> | null\n\tCollaboratorShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null\n\tCursor?: ComponentType<TLCursorProps> | null\n\tGrid?: ComponentType<TLGridProps> | null\n\tHandle?: ComponentType<TLHandleProps> | null\n\tHandles?: ComponentType<TLHandlesProps> | null\n\tInFrontOfTheCanvas?: ComponentType | null\n\tLoadingScreen?: ComponentType | null\n\tOnTheCanvas?: ComponentType | null\n\tOverlays?: ComponentType | null\n\tScribble?: ComponentType<TLScribbleProps> | null\n\tSelectionBackground?: ComponentType<TLSelectionBackgroundProps> | null\n\tSelectionForeground?: ComponentType<TLSelectionForegroundProps> | null\n\tShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null\n\tShapeIndicators?: ComponentType | null\n\tSnapIndicator?: ComponentType<TLSnapIndicatorProps> | null\n\tSpinner?: ComponentType<React.SVGProps<SVGSVGElement>> | null\n\tSvgDefs?: ComponentType | null\n\tZoomBrush?: ComponentType<TLBrushProps> | null\n\n\t// These will always have defaults\n\tErrorFallback?: TLErrorFallbackComponent\n\tShapeErrorFallback?: TLShapeErrorFallbackComponent\n\tShapeIndicatorErrorFallback?: TLShapeIndicatorErrorFallbackComponent\n}\n\nconst EditorComponentsContext = createContext<null | Required<TLEditorComponents>>(null)\n\ninterface ComponentsContextProviderProps {\n\toverrides?: TLEditorComponents\n\tchildren: ReactNode\n}\n\nexport function EditorComponentsProvider({\n\toverrides = {},\n\tchildren,\n}: ComponentsContextProviderProps) {\n\tconst _overrides = useShallowObjectIdentity(overrides)\n\tconst value = useMemo(\n\t\t(): Required<TLEditorComponents> => ({\n\t\t\tBackground: DefaultBackground,\n\t\t\tBrush: DefaultBrush,\n\t\t\tCanvas: DefaultCanvas,\n\t\t\tCollaboratorBrush: DefaultBrush,\n\t\t\tCollaboratorCursor: DefaultCursor,\n\t\t\tCollaboratorHint: DefaultCollaboratorHint,\n\t\t\tCollaboratorScribble: DefaultScribble,\n\t\t\tCollaboratorShapeIndicator: DefaultShapeIndicator,\n\t\t\tCursor: DefaultCursor,\n\t\t\tGrid: DefaultGrid,\n\t\t\tHandle: DefaultHandle,\n\t\t\tHandles: DefaultHandles,\n\t\t\tInFrontOfTheCanvas: null,\n\t\t\tLoadingScreen: DefaultLoadingScreen,\n\t\t\tOnTheCanvas: null,\n\t\t\tOverlays: null,\n\t\t\tScribble: DefaultScribble,\n\t\t\tSelectionBackground: null,\n\t\t\tSelectionForeground: DefaultSelectionForeground,\n\t\t\tShapeIndicator: DefaultShapeIndicator,\n\t\t\tShapeIndicators: DefaultShapeIndicators,\n\t\t\tSnapIndicator: DefaultSnapIndicator,\n\t\t\tSpinner: DefaultSpinner,\n\t\t\tSvgDefs: DefaultSvgDefs,\n\t\t\tZoomBrush: DefaultBrush,\n\n\t\t\tErrorFallback: DefaultErrorFallback,\n\t\t\tShapeErrorFallback: DefaultShapeErrorFallback,\n\t\t\tShapeIndicatorErrorFallback: DefaultShapeIndicatorErrorFallback,\n\n\t\t\t..._overrides,\n\t\t}),\n\t\t[_overrides]\n\t)\n\n\treturn (\n\t\t<EditorComponentsContext.Provider value={value}>{children}</EditorComponentsContext.Provider>\n\t)\n}\n\n/** @public */\nexport function useEditorComponents() {\n\tconst components = useContext(EditorComponentsContext)\n\tif (!components) {\n\t\tthrow new Error('useEditorComponents must be used inside of <EditorComponentsProvider />')\n\t}\n\treturn components\n}\n"],
5
5
  "mappings": "AAmIE;AAnIF,SAAmC,eAAe,YAAY,eAAe;AAC7E,SAAS,yBAAyB;AAClC,SAAS,oBAAkC;AAC3C;AAAA,EACC;AAAA,OAEM;AACP;AAAA,EACC;AAAA,OAEM;AACP,SAAS,qBAAoC;AAC7C;AAAA,EACC;AAAA,OAEM;AACP,SAAS,mBAAgC;AACzC,SAAS,qBAAoC;AAC7C,SAAS,sBAAsC;AAC/C,SAAS,4BAA4B;AACrC,SAAS,uBAAwC;AAEjD;AAAA,EACC;AAAA,OAEM;AACP;AAAA,EACC;AAAA,OAEM;AACP;AAAA,EACC;AAAA,OAEM;AACP;AAAA,EACC;AAAA,OAEM;AACP,SAAS,8BAA8B;AACvC;AAAA,EACC;AAAA,OAEM;AACP,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,gCAAgC;AAoCzC,MAAM,0BAA0B,cAAmD,IAAI;AAOhF,SAAS,yBAAyB;AAAA,EACxC,YAAY,CAAC;AAAA,EACb;AACD,GAAmC;AAClC,QAAM,aAAa,yBAAyB,SAAS;AACrD,QAAM,QAAQ;AAAA,IACb,OAAqC;AAAA,MACpC,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB;AAAA,MAClB,sBAAsB;AAAA,MACtB,4BAA4B;AAAA,MAC5B,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,oBAAoB;AAAA,MACpB,eAAe;AAAA,MACf,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,MACV,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,MACrB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,SAAS;AAAA,MACT,SAAS;AAAA,MACT,WAAW;AAAA,MAEX,eAAe;AAAA,MACf,oBAAoB;AAAA,MACpB,6BAA6B;AAAA,MAE7B,GAAG;AAAA,IACJ;AAAA,IACA,CAAC,UAAU;AAAA,EACZ;AAEA,SACC,oBAAC,wBAAwB,UAAxB,EAAiC,OAAe,UAAS;AAE5D;AAGO,SAAS,sBAAsB;AACrC,QAAM,aAAa,WAAW,uBAAuB;AACrD,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI,MAAM,yEAAyE;AAAA,EAC1F;AACA,SAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -133,7 +133,7 @@ To remove the watermark, please purchase a license at tldraw.dev.
133
133
  }
134
134
 
135
135
  .${className}:hover > button {
136
- animation: delayed_link 0.2s forwards ease-in-out;
136
+ animation: ${className}_delayed_link 0.2s forwards ease-in-out;
137
137
  animation-delay: 0.32s;
138
138
  }
139
139
 
@@ -143,7 +143,7 @@ To remove the watermark, please purchase a license at tldraw.dev.
143
143
  }
144
144
 
145
145
 
146
- @keyframes delayed_link {
146
+ @keyframes ${className}_delayed_link {
147
147
  0% {
148
148
  cursor: inherit;
149
149
  opacity: .38;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/license/Watermark.tsx"],
4
- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { memo, useRef } from 'react'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { usePassThroughWheelEvents } from '../hooks/usePassThroughWheelEvents'\nimport { preventDefault, stopEventPropagation } from '../utils/dom'\nimport { runtime } from '../utils/runtime'\nimport { watermarkDesktopSvg, watermarkMobileSvg } from '../watermarks'\nimport { LicenseManager } from './LicenseManager'\nimport { useLicenseContext } from './LicenseProvider'\nimport { useLicenseManagerState } from './useLicenseManagerState'\n\nconst WATERMARK_DESKTOP_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkDesktopSvg)}`\nconst WATERMARK_MOBILE_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkMobileSvg)}`\n\n/** @internal */\nexport const Watermark = memo(function Watermark() {\n\tconst licenseManager = useLicenseContext()\n\tconst editor = useEditor()\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\n\tconst licenseManagerState = useLicenseManagerState(licenseManager)\n\n\tif (!['licensed-with-watermark', 'unlicensed'].includes(licenseManagerState)) return null\n\n\treturn (\n\t\t<>\n\t\t\t<LicenseStyles />\n\t\t\t<WatermarkInner src={isMobile ? WATERMARK_MOBILE_LOCAL_SRC : WATERMARK_DESKTOP_LOCAL_SRC} />\n\t\t</>\n\t)\n})\n\nconst WatermarkInner = memo(function WatermarkInner({ src }: { src: string }) {\n\tconst editor = useEditor()\n\tconst isDebugMode = useValue('debug mode', () => editor.getInstanceState().isDebugMode, [editor])\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\tconst events = useCanvasEvents()\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst maskCss = `url('${src}') center 100% / 100% no-repeat`\n\tconst url = 'https://tldraw.dev/?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark'\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName={LicenseManager.className}\n\t\t\tdata-debug={isDebugMode}\n\t\t\tdata-mobile={isMobile}\n\t\t\tdraggable={false}\n\t\t\t{...events}\n\t\t>\n\t\t\t<button\n\t\t\t\tdraggable={false}\n\t\t\t\trole=\"button\"\n\t\t\t\tonPointerDown={(e) => {\n\t\t\t\t\tstopEventPropagation(e)\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}}\n\t\t\t\ttitle=\"made with tldraw\"\n\t\t\t\tonClick={() => runtime.openWindow(url, '_blank')}\n\t\t\t\tstyle={{ mask: maskCss, WebkitMask: maskCss }}\n\t\t\t/>\n\t\t</div>\n\t)\n})\n\nconst LicenseStyles = memo(function LicenseStyles() {\n\tconst editor = useEditor()\n\tconst className = LicenseManager.className\n\n\tconst CSS = `/* ------------------- SEE LICENSE -------------------\nThe tldraw watermark is part of tldraw's license. It is shown for unlicensed\nor \"licensed-with-watermark\" users. By using this library, you agree to\npreserve the watermark's behavior, keeping it visible, unobscured, and\navailable to user-interaction.\n\nTo remove the watermark, please purchase a license at tldraw.dev.\n*/\n\n\t.${className} {\n\t\tposition: absolute;\n\t\tbottom: var(--space-2);\n\t\tright: var(--space-2);\n\t\twidth: 96px;\n\t\theight: 32px;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tz-index: var(--layer-watermark) !important;\n\t\tbackground-color: color-mix(in srgb, var(--color-background) 62%, transparent);\n\t\topacity: 1;\n\t\tborder-radius: 5px;\n\t\tpointer-events: all;\n\t\tpadding: 2px;\n\t\tbox-sizing: content-box;\n\t}\n\n\t.${className} > button {\n\t\tposition: absolute;\n\t\twidth: 96px;\n\t\theight: 32px;\n\t\tpointer-events: all;\n\t\tcursor: inherit;\n\t\tcolor: var(--color-text);\n\t\topacity: .38;\n\t\tborder: 0;\n\t\tpadding: 0;\n\t\tbackground-color: currentColor;\n\t}\n\n\t.${className}[data-debug='true'] {\n\t\tbottom: 46px;\n\t}\n\n\t.${className}[data-mobile='true'] {\n\t\tborder-radius: 4px 0px 0px 4px;\n\t\tright: -2px;\n\t\twidth: 8px;\n\t\theight: 48px;\n\t}\n\n\t.${className}[data-mobile='true'] > button {\n\t\twidth: 8px;\n\t\theight: 32px;\n\t}\n\n\t@media (hover: hover) {\n\t\t.${className} > button {\n\t\t\tpointer-events: none;\n\t\t}\n\n\t\t.${className}:hover {\n\t\t\tbackground-color: var(--color-background);\n\t\t\ttransition: background-color 0.2s ease-in-out;\n\t\t\ttransition-delay: 0.32s;\n\t\t}\n\n\t\t.${className}:hover > button {\n\t\t\tanimation: delayed_link 0.2s forwards ease-in-out;\n\t\t\tanimation-delay: 0.32s;\n\t\t}\n\n\t\t.${className} > button:focus-visible {\n\t\t\topacity: 1;\n\t\t}\n\t}\n\n\n\t@keyframes delayed_link {\n\t\t0% {\n\t\t\tcursor: inherit;\n\t\t\topacity: .38;\n\t\t\tpointer-events: none;\n\t\t}\n\t\t100% {\n\t\t\tcursor: pointer;\n\t\t\topacity: 1;\n\t\t\tpointer-events: all;\n\t\t}\n\t}`\n\n\treturn <style nonce={editor.options.nonce}>{CSS}</style>\n})\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { memo, useRef } from 'react'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { usePassThroughWheelEvents } from '../hooks/usePassThroughWheelEvents'\nimport { preventDefault, stopEventPropagation } from '../utils/dom'\nimport { runtime } from '../utils/runtime'\nimport { watermarkDesktopSvg, watermarkMobileSvg } from '../watermarks'\nimport { LicenseManager } from './LicenseManager'\nimport { useLicenseContext } from './LicenseProvider'\nimport { useLicenseManagerState } from './useLicenseManagerState'\n\nconst WATERMARK_DESKTOP_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkDesktopSvg)}`\nconst WATERMARK_MOBILE_LOCAL_SRC = `data:image/svg+xml;utf8,${encodeURIComponent(watermarkMobileSvg)}`\n\n/** @internal */\nexport const Watermark = memo(function Watermark() {\n\tconst licenseManager = useLicenseContext()\n\tconst editor = useEditor()\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\n\tconst licenseManagerState = useLicenseManagerState(licenseManager)\n\n\tif (!['licensed-with-watermark', 'unlicensed'].includes(licenseManagerState)) return null\n\n\treturn (\n\t\t<>\n\t\t\t<LicenseStyles />\n\t\t\t<WatermarkInner src={isMobile ? WATERMARK_MOBILE_LOCAL_SRC : WATERMARK_DESKTOP_LOCAL_SRC} />\n\t\t</>\n\t)\n})\n\nconst WatermarkInner = memo(function WatermarkInner({ src }: { src: string }) {\n\tconst editor = useEditor()\n\tconst isDebugMode = useValue('debug mode', () => editor.getInstanceState().isDebugMode, [editor])\n\tconst isMobile = useValue('is mobile', () => editor.getViewportScreenBounds().width < 700, [\n\t\teditor,\n\t])\n\tconst events = useCanvasEvents()\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\tconst maskCss = `url('${src}') center 100% / 100% no-repeat`\n\tconst url = 'https://tldraw.dev/?utm_source=dotcom&utm_medium=organic&utm_campaign=watermark'\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName={LicenseManager.className}\n\t\t\tdata-debug={isDebugMode}\n\t\t\tdata-mobile={isMobile}\n\t\t\tdraggable={false}\n\t\t\t{...events}\n\t\t>\n\t\t\t<button\n\t\t\t\tdraggable={false}\n\t\t\t\trole=\"button\"\n\t\t\t\tonPointerDown={(e) => {\n\t\t\t\t\tstopEventPropagation(e)\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}}\n\t\t\t\ttitle=\"made with tldraw\"\n\t\t\t\tonClick={() => runtime.openWindow(url, '_blank')}\n\t\t\t\tstyle={{ mask: maskCss, WebkitMask: maskCss }}\n\t\t\t/>\n\t\t</div>\n\t)\n})\n\nconst LicenseStyles = memo(function LicenseStyles() {\n\tconst editor = useEditor()\n\tconst className = LicenseManager.className\n\n\tconst CSS = `/* ------------------- SEE LICENSE -------------------\nThe tldraw watermark is part of tldraw's license. It is shown for unlicensed\nor \"licensed-with-watermark\" users. By using this library, you agree to\npreserve the watermark's behavior, keeping it visible, unobscured, and\navailable to user-interaction.\n\nTo remove the watermark, please purchase a license at tldraw.dev.\n*/\n\n\t.${className} {\n\t\tposition: absolute;\n\t\tbottom: var(--space-2);\n\t\tright: var(--space-2);\n\t\twidth: 96px;\n\t\theight: 32px;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tz-index: var(--layer-watermark) !important;\n\t\tbackground-color: color-mix(in srgb, var(--color-background) 62%, transparent);\n\t\topacity: 1;\n\t\tborder-radius: 5px;\n\t\tpointer-events: all;\n\t\tpadding: 2px;\n\t\tbox-sizing: content-box;\n\t}\n\n\t.${className} > button {\n\t\tposition: absolute;\n\t\twidth: 96px;\n\t\theight: 32px;\n\t\tpointer-events: all;\n\t\tcursor: inherit;\n\t\tcolor: var(--color-text);\n\t\topacity: .38;\n\t\tborder: 0;\n\t\tpadding: 0;\n\t\tbackground-color: currentColor;\n\t}\n\n\t.${className}[data-debug='true'] {\n\t\tbottom: 46px;\n\t}\n\n\t.${className}[data-mobile='true'] {\n\t\tborder-radius: 4px 0px 0px 4px;\n\t\tright: -2px;\n\t\twidth: 8px;\n\t\theight: 48px;\n\t}\n\n\t.${className}[data-mobile='true'] > button {\n\t\twidth: 8px;\n\t\theight: 32px;\n\t}\n\n\t@media (hover: hover) {\n\t\t.${className} > button {\n\t\t\tpointer-events: none;\n\t\t}\n\n\t\t.${className}:hover {\n\t\t\tbackground-color: var(--color-background);\n\t\t\ttransition: background-color 0.2s ease-in-out;\n\t\t\ttransition-delay: 0.32s;\n\t\t}\n\n\t\t.${className}:hover > button {\n\t\t\tanimation: ${className}_delayed_link 0.2s forwards ease-in-out;\n\t\t\tanimation-delay: 0.32s;\n\t\t}\n\n\t\t.${className} > button:focus-visible {\n\t\t\topacity: 1;\n\t\t}\n\t}\n\n\n\t@keyframes ${className}_delayed_link {\n\t\t0% {\n\t\t\tcursor: inherit;\n\t\t\topacity: .38;\n\t\t\tpointer-events: none;\n\t\t}\n\t\t100% {\n\t\t\tcursor: pointer;\n\t\t\topacity: 1;\n\t\t\tpointer-events: all;\n\t\t}\n\t}`\n\n\treturn <style nonce={editor.options.nonce}>{CSS}</style>\n})\n"],
5
+ "mappings": "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",
6
6
  "names": ["Watermark", "WatermarkInner", "LicenseStyles"]
7
7
  }
@@ -2,7 +2,7 @@ import { Vec } from "../Vec.mjs";
2
2
  import { intersectLineSegmentCircle } from "../intersect.mjs";
3
3
  import { getArcMeasure, getPointInArcT, getPointOnCircle } from "../utils.mjs";
4
4
  import { Geometry2d } from "./Geometry2d.mjs";
5
- import { getVerticesCountForLength } from "./geometry-constants.mjs";
5
+ import { getVerticesCountForArcLength } from "./geometry-constants.mjs";
6
6
  class Arc2d extends Geometry2d {
7
7
  _center;
8
8
  _radius;
@@ -72,7 +72,7 @@ class Arc2d extends Geometry2d {
72
72
  getVertices() {
73
73
  const { _center, _measure: measure, length, _radius: radius, _angleStart: angleStart } = this;
74
74
  const vertices = [];
75
- for (let i = 0, n = getVerticesCountForLength(Math.abs(length)); i < n + 1; i++) {
75
+ for (let i = 0, n = getVerticesCountForArcLength(Math.abs(length)); i < n + 1; i++) {
76
76
  const t = i / n * measure;
77
77
  const angle = angleStart + t;
78
78
  vertices.push(getPointOnCircle(_center, radius, angle));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Arc2d.ts"],
4
- "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { getArcMeasure, getPointInArcT, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForLength } from './geometry-constants'\n\n/** @public */\nexport class Arc2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _start: Vec\n\tprivate _end: Vec\n\tprivate _largeArcFlag: number\n\tprivate _sweepFlag: number\n\tprivate _measure: number\n\tprivate _angleStart: number\n\tprivate _angleEnd: number\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tcenter: Vec\n\t\t\tstart: Vec\n\t\t\tend: Vec\n\t\t\tsweepFlag: number\n\t\t\tlargeArcFlag: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isFilled: false, isClosed: false })\n\t\tconst { center, sweepFlag, largeArcFlag, start, end } = config\n\t\tif (start.equals(end)) throw Error(`Arc must have different start and end points.`)\n\n\t\t// ensure that the start and end are clockwise\n\t\tthis._angleStart = Vec.Angle(center, start)\n\t\tthis._angleEnd = Vec.Angle(center, end)\n\t\tthis._radius = Vec.Dist(center, start)\n\t\tthis._measure = getArcMeasure(this._angleStart, this._angleEnd, sweepFlag, largeArcFlag)\n\n\t\tthis._start = start\n\t\tthis._end = end\n\n\t\tthis._sweepFlag = sweepFlag\n\t\tthis._largeArcFlag = largeArcFlag\n\t\tthis._center = center\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_measure: measure,\n\t\t\t_radius: radius,\n\t\t\t_angleEnd: angleEnd,\n\t\t\t_angleStart: angleStart,\n\t\t\t_start: A,\n\t\t\t_end: B,\n\t\t} = this\n\t\tconst t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point))\n\t\tif (t <= 0) return A\n\t\tif (t >= 1) return B\n\n\t\t// Get the point (P) on the arc, then pick the nearest of A, B, and P\n\t\tconst P = Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tfor (const p of [A, B, P]) {\n\t\t\td = Vec.Dist2(point, p)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_radius: radius,\n\t\t\t_measure: measure,\n\t\t\t_angleStart: angleStart,\n\t\t\t_angleEnd: angleEnd,\n\t\t} = this\n\t\tconst intersection = intersectLineSegmentCircle(A, B, _center, radius)\n\t\tif (intersection === null) return false\n\n\t\treturn intersection.some((p) => {\n\t\t\tconst result = getPointInArcT(measure, angleStart, angleEnd, _center.angle(p))\n\t\t\treturn result >= 0 && result <= 1\n\t\t})\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _measure: measure, length, _radius: radius, _angleStart: angleStart } = this\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForLength(Math.abs(length)); i < n + 1; i++) {\n\t\t\tconst t = (i / n) * measure\n\t\t\tconst angle = angleStart + t\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst {\n\t\t\t_start: start,\n\t\t\t_end: end,\n\t\t\t_radius: radius,\n\t\t\t_largeArcFlag: largeArcFlag,\n\t\t\t_sweepFlag: sweepFlag,\n\t\t} = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.toFixed()}`\n\t}\n\n\toverride getLength() {\n\t\treturn Math.abs(this._measure * this._radius)\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { getArcMeasure, getPointInArcT, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\n\n/** @public */\nexport class Arc2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _start: Vec\n\tprivate _end: Vec\n\tprivate _largeArcFlag: number\n\tprivate _sweepFlag: number\n\tprivate _measure: number\n\tprivate _angleStart: number\n\tprivate _angleEnd: number\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tcenter: Vec\n\t\t\tstart: Vec\n\t\t\tend: Vec\n\t\t\tsweepFlag: number\n\t\t\tlargeArcFlag: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isFilled: false, isClosed: false })\n\t\tconst { center, sweepFlag, largeArcFlag, start, end } = config\n\t\tif (start.equals(end)) throw Error(`Arc must have different start and end points.`)\n\n\t\t// ensure that the start and end are clockwise\n\t\tthis._angleStart = Vec.Angle(center, start)\n\t\tthis._angleEnd = Vec.Angle(center, end)\n\t\tthis._radius = Vec.Dist(center, start)\n\t\tthis._measure = getArcMeasure(this._angleStart, this._angleEnd, sweepFlag, largeArcFlag)\n\n\t\tthis._start = start\n\t\tthis._end = end\n\n\t\tthis._sweepFlag = sweepFlag\n\t\tthis._largeArcFlag = largeArcFlag\n\t\tthis._center = center\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_measure: measure,\n\t\t\t_radius: radius,\n\t\t\t_angleEnd: angleEnd,\n\t\t\t_angleStart: angleStart,\n\t\t\t_start: A,\n\t\t\t_end: B,\n\t\t} = this\n\t\tconst t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point))\n\t\tif (t <= 0) return A\n\t\tif (t >= 1) return B\n\n\t\t// Get the point (P) on the arc, then pick the nearest of A, B, and P\n\t\tconst P = Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tfor (const p of [A, B, P]) {\n\t\t\td = Vec.Dist2(point, p)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_radius: radius,\n\t\t\t_measure: measure,\n\t\t\t_angleStart: angleStart,\n\t\t\t_angleEnd: angleEnd,\n\t\t} = this\n\t\tconst intersection = intersectLineSegmentCircle(A, B, _center, radius)\n\t\tif (intersection === null) return false\n\n\t\treturn intersection.some((p) => {\n\t\t\tconst result = getPointInArcT(measure, angleStart, angleEnd, _center.angle(p))\n\t\t\treturn result >= 0 && result <= 1\n\t\t})\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _measure: measure, length, _radius: radius, _angleStart: angleStart } = this\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForArcLength(Math.abs(length)); i < n + 1; i++) {\n\t\t\tconst t = (i / n) * measure\n\t\t\tconst angle = angleStart + t\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst {\n\t\t\t_start: start,\n\t\t\t_end: end,\n\t\t\t_radius: radius,\n\t\t\t_largeArcFlag: largeArcFlag,\n\t\t\t_sweepFlag: sweepFlag,\n\t\t} = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.toFixed()}`\n\t}\n\n\toverride getLength() {\n\t\treturn Math.abs(this._measure * this._radius)\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,7 @@ import { Vec } from "../Vec.mjs";
3
3
  import { intersectLineSegmentCircle } from "../intersect.mjs";
4
4
  import { PI2, getPointOnCircle } from "../utils.mjs";
5
5
  import { Geometry2d } from "./Geometry2d.mjs";
6
- import { getVerticesCountForLength } from "./geometry-constants.mjs";
6
+ import { getVerticesCountForArcLength } from "./geometry-constants.mjs";
7
7
  class Circle2d extends Geometry2d {
8
8
  constructor(config) {
9
9
  super({ isClosed: true, ...config });
@@ -25,7 +25,7 @@ class Circle2d extends Geometry2d {
25
25
  const { _center, _radius: radius } = this;
26
26
  const perimeter = PI2 * radius;
27
27
  const vertices = [];
28
- for (let i = 0, n = getVerticesCountForLength(perimeter); i < n; i++) {
28
+ for (let i = 0, n = getVerticesCountForArcLength(perimeter); i < n; i++) {
29
29
  const angle = i / n * PI2;
30
30
  vertices.push(getPointOnCircle(_center, radius, angle));
31
31
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Circle2d.ts"],
4
- "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { PI2, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForLength } from './geometry-constants'\n\n/** @public */\nexport class Circle2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _x: number\n\tprivate _y: number\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\tx?: number\n\t\t\ty?: number\n\t\t\tradius: number\n\t\t\tisFilled: boolean\n\t\t}\n\t) {\n\t\tsuper({ isClosed: true, ...config })\n\t\tconst { x = 0, y = 0, radius } = config\n\t\tthis._x = x\n\t\tthis._y = y\n\t\tthis._center = new Vec(radius + x, radius + y)\n\t\tthis._radius = radius\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(this._x, this._y, this._radius * 2, this._radius * 2)\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _radius: radius } = this\n\t\tconst perimeter = PI2 * radius\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForLength(perimeter); i < n; i++) {\n\t\t\tconst angle = (i / n) * PI2\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst { _center, _radius: radius } = this\n\t\tif (_center.equals(point)) return Vec.AddXY(_center, radius, 0)\n\t\treturn Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn intersectLineSegmentCircle(A, B, _center, radius + distance) !== null\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`\n\t}\n}\n"],
5
- "mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,WAAoB;AAC7B,SAAS,kCAAkC;AAC3C,SAAS,KAAK,wBAAwB;AACtC,SAAS,kBAAqC;AAC9C,SAAS,iCAAiC;AAGnC,MAAM,iBAAiB,WAAW;AAAA,EAMxC,YACQ,QAMN;AACD,UAAM,EAAE,UAAU,MAAM,GAAG,OAAO,CAAC;AAP5B;AAQP,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,IAAI;AACjC,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,UAAU,IAAI,IAAI,SAAS,GAAG,SAAS,CAAC;AAC7C,SAAK,UAAU;AAAA,EAChB;AAAA,EAnBQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAkBR,YAAY;AACX,WAAO,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,UAAU,GAAG,KAAK,UAAU,CAAC;AAAA,EACpE;AAAA,EAEA,cAAqB;AACpB,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,UAAM,YAAY,MAAM;AACxB,UAAM,WAAkB,CAAC;AACzB,aAAS,IAAI,GAAG,IAAI,0BAA0B,SAAS,GAAG,IAAI,GAAG,KAAK;AACrE,YAAM,QAAS,IAAI,IAAK;AACxB,eAAS,KAAK,iBAAiB,SAAS,QAAQ,KAAK,CAAC;AAAA,IACvD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,OAAqB;AACjC,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,QAAI,QAAQ,OAAO,KAAK,EAAG,QAAO,IAAI,MAAM,SAAS,QAAQ,CAAC;AAC9D,WAAO,IAAI,IAAI,OAAO,OAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,IAAI,OAAO;AAAA,EAC7D;AAAA,EAEA,mBAAmB,GAAY,GAAY,WAAW,GAAY;AACjE,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,WAAO,2BAA2B,GAAG,GAAG,SAAS,SAAS,QAAQ,MAAM;AAAA,EACzE;AAAA,EAEA,iBAAyB;AACxB,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,WAAO,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,CAAC,KAAK,MAAM,IAAI,MAAM,UAAU,SAAS,CAAC,MAAM,MAAM,IAAI,MAAM,WAAW,SAAS,CAAC;AAAA,EAC/H;AACD;",
4
+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { PI2, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\n\n/** @public */\nexport class Circle2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _x: number\n\tprivate _y: number\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\tx?: number\n\t\t\ty?: number\n\t\t\tradius: number\n\t\t\tisFilled: boolean\n\t\t}\n\t) {\n\t\tsuper({ isClosed: true, ...config })\n\t\tconst { x = 0, y = 0, radius } = config\n\t\tthis._x = x\n\t\tthis._y = y\n\t\tthis._center = new Vec(radius + x, radius + y)\n\t\tthis._radius = radius\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(this._x, this._y, this._radius * 2, this._radius * 2)\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _radius: radius } = this\n\t\tconst perimeter = PI2 * radius\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForArcLength(perimeter); i < n; i++) {\n\t\t\tconst angle = (i / n) * PI2\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst { _center, _radius: radius } = this\n\t\tif (_center.equals(point)) return Vec.AddXY(_center, radius, 0)\n\t\treturn Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn intersectLineSegmentCircle(A, B, _center, radius + distance) !== null\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`\n\t}\n}\n"],
5
+ "mappings": "AAAA,SAAS,WAAW;AACpB,SAAS,WAAoB;AAC7B,SAAS,kCAAkC;AAC3C,SAAS,KAAK,wBAAwB;AACtC,SAAS,kBAAqC;AAC9C,SAAS,oCAAoC;AAGtC,MAAM,iBAAiB,WAAW;AAAA,EAMxC,YACQ,QAMN;AACD,UAAM,EAAE,UAAU,MAAM,GAAG,OAAO,CAAC;AAP5B;AAQP,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,IAAI;AACjC,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,UAAU,IAAI,IAAI,SAAS,GAAG,SAAS,CAAC;AAC7C,SAAK,UAAU;AAAA,EAChB;AAAA,EAnBQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAkBR,YAAY;AACX,WAAO,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,UAAU,GAAG,KAAK,UAAU,CAAC;AAAA,EACpE;AAAA,EAEA,cAAqB;AACpB,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,UAAM,YAAY,MAAM;AACxB,UAAM,WAAkB,CAAC;AACzB,aAAS,IAAI,GAAG,IAAI,6BAA6B,SAAS,GAAG,IAAI,GAAG,KAAK;AACxE,YAAM,QAAS,IAAI,IAAK;AACxB,eAAS,KAAK,iBAAiB,SAAS,QAAQ,KAAK,CAAC;AAAA,IACvD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,OAAqB;AACjC,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,QAAI,QAAQ,OAAO,KAAK,EAAG,QAAO,IAAI,MAAM,SAAS,QAAQ,CAAC;AAC9D,WAAO,IAAI,IAAI,OAAO,OAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,IAAI,OAAO;AAAA,EAC7D;AAAA,EAEA,mBAAmB,GAAY,GAAY,WAAW,GAAY;AACjE,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,WAAO,2BAA2B,GAAG,GAAG,SAAS,SAAS,QAAQ,MAAM;AAAA,EACzE;AAAA,EAEA,iBAAyB;AACxB,UAAM,EAAE,SAAS,SAAS,OAAO,IAAI;AACrC,WAAO,IAAI,QAAQ,IAAI,MAAM,IAAI,QAAQ,CAAC,KAAK,MAAM,IAAI,MAAM,UAAU,SAAS,CAAC,MAAM,MAAM,IAAI,MAAM,WAAW,SAAS,CAAC;AAAA,EAC/H;AACD;",
6
6
  "names": []
7
7
  }
@@ -5,6 +5,7 @@ class CubicBezier2d extends Polyline2d {
5
5
  _b;
6
6
  _c;
7
7
  _d;
8
+ _resolution;
8
9
  constructor(config) {
9
10
  const { start: a, cp1: b, cp2: c, end: d } = config;
10
11
  super({ ...config, points: [a, d] });
@@ -12,11 +13,12 @@ class CubicBezier2d extends Polyline2d {
12
13
  this._b = b;
13
14
  this._c = c;
14
15
  this._d = d;
16
+ this._resolution = config.resolution ?? 10;
15
17
  }
16
18
  getVertices() {
17
19
  const vertices = [];
18
20
  const { _a: a, _b: b, _c: c, _d: d } = this;
19
- for (let i = 0, n = 10; i <= n; i++) {
21
+ for (let i = 0, n = this._resolution; i <= n; i++) {
20
22
  const t = i / n;
21
23
  vertices.push(
22
24
  new Vec(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/CubicBezier2d.ts"],
4
- "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { Geometry2dFilters, Geometry2dOptions } from './Geometry2d'\nimport { Polyline2d } from './Polyline2d'\n\n/** @public */\nexport class CubicBezier2d extends Polyline2d {\n\tprivate _a: Vec\n\tprivate _b: Vec\n\tprivate _c: Vec\n\tprivate _d: Vec\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tstart: Vec\n\t\t\tcp1: Vec\n\t\t\tcp2: Vec\n\t\t\tend: Vec\n\t\t}\n\t) {\n\t\tconst { start: a, cp1: b, cp2: c, end: d } = config\n\t\tsuper({ ...config, points: [a, d] })\n\n\t\tthis._a = a\n\t\tthis._b = b\n\t\tthis._c = c\n\t\tthis._d = d\n\t}\n\n\toverride getVertices() {\n\t\tconst vertices = [] as Vec[]\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\t// we'll always use ten vertices for each bezier curve\n\t\tfor (let i = 0, n = 10; i <= n; i++) {\n\t\t\tconst t = i / n\n\t\t\tvertices.push(\n\t\t\t\tnew Vec(\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\t\t\tt * t * t * d.x,\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\t\t\tt * t * t * d.y\n\t\t\t\t)\n\t\t\t)\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.segments) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn `${first ? `M ${a.toFixed()} ` : ``} C${b.toFixed()} ${c.toFixed()} ${d.toFixed()}`\n\t}\n\n\tstatic GetAtT(segment: CubicBezier2d, t: number) {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = segment\n\t\treturn new Vec(\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\tt * t * t * d.x,\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\tt * t * t * d.y\n\t\t)\n\t}\n\n\toverride getLength(_filters?: Geometry2dFilters, precision = 32) {\n\t\tlet n1: Vec,\n\t\t\tp1 = this._a,\n\t\t\tlength = 0\n\t\tfor (let i = 1; i <= precision; i++) {\n\t\t\tn1 = CubicBezier2d.GetAtT(this, i / precision)\n\t\t\tlength += Vec.Dist(p1, n1)\n\t\t\tp1 = n1\n\t\t}\n\t\treturn length\n\t}\n}\n"],
5
- "mappings": "AAAA,SAAS,WAAoB;AAE7B,SAAS,kBAAkB;AAGpB,MAAM,sBAAsB,WAAW;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACC,QAMC;AACD,UAAM,EAAE,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI;AAC7C,UAAM,EAAE,GAAG,QAAQ,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;AAEnC,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,KAAK;AACV,SAAK,KAAK;AAAA,EACX;AAAA,EAES,cAAc;AACtB,UAAM,WAAW,CAAC;AAClB,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI;AAEvC,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG,KAAK;AACpC,YAAM,IAAI,IAAI;AACd,eAAS;AAAA,QACR,IAAI;AAAA,WACF,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,WACd,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,QAChB;AAAA,MACD;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,GAAiB;AAC7B,QAAI;AACJ,QAAI,OAAO;AACX,QAAI;AACJ,QAAI;AACJ,eAAW,QAAQ,KAAK,UAAU;AACjC,UAAI,KAAK,aAAa,CAAC;AACvB,UAAI,IAAI,MAAM,GAAG,CAAC;AAClB,UAAI,IAAI,MAAM;AACb,kBAAU;AACV,eAAO;AAAA,MACR;AAAA,IACD;AAEA,QAAI,CAAC,QAAS,OAAM,MAAM,yBAAyB;AACnD,WAAO;AAAA,EACR;AAAA,EAEA,eAAe,QAAQ,MAAM;AAC5B,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI;AACvC,WAAO,GAAG,QAAQ,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;AAAA,EACzF;AAAA,EAEA,OAAO,OAAO,SAAwB,GAAW;AAChD,UAAM,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,IAAI;AACvC,WAAO,IAAI;AAAA,OACT,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,OACd,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,IAC/B,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,EAAE,IAChC,KAAK,IAAI,MAAM,IAAI,KAAK,EAAE,IAC1B,IAAI,IAAI,IAAI,EAAE;AAAA,IAChB;AAAA,EACD;AAAA,EAES,UAAU,UAA8B,YAAY,IAAI;AAChE,QAAI,IACH,KAAK,KAAK,IACV,SAAS;AACV,aAAS,IAAI,GAAG,KAAK,WAAW,KAAK;AACpC,WAAK,cAAc,OAAO,MAAM,IAAI,SAAS;AAC7C,gBAAU,IAAI,KAAK,IAAI,EAAE;AACzB,WAAK;AAAA,IACN;AACA,WAAO;AAAA,EACR;AACD;",
4
+ "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { Geometry2dFilters, Geometry2dOptions } from './Geometry2d'\nimport { Polyline2d } from './Polyline2d'\n\n/** @public */\nexport class CubicBezier2d extends Polyline2d {\n\tprivate _a: Vec\n\tprivate _b: Vec\n\tprivate _c: Vec\n\tprivate _d: Vec\n\tprivate _resolution: number\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tstart: Vec\n\t\t\tcp1: Vec\n\t\t\tcp2: Vec\n\t\t\tend: Vec\n\t\t\tresolution?: number\n\t\t}\n\t) {\n\t\tconst { start: a, cp1: b, cp2: c, end: d } = config\n\t\tsuper({ ...config, points: [a, d] })\n\n\t\tthis._a = a\n\t\tthis._b = b\n\t\tthis._c = c\n\t\tthis._d = d\n\t\tthis._resolution = config.resolution ?? 10\n\t}\n\n\toverride getVertices() {\n\t\tconst vertices = [] as Vec[]\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\t// we'll always use ten vertices for each bezier curve\n\t\tfor (let i = 0, n = this._resolution; i <= n; i++) {\n\t\t\tconst t = i / n\n\t\t\tvertices.push(\n\t\t\t\tnew Vec(\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\t\t\tt * t * t * d.x,\n\t\t\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\t\t\tt * t * t * d.y\n\t\t\t\t)\n\t\t\t)\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.segments) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn `${first ? `M ${a.toFixed()} ` : ``} C${b.toFixed()} ${c.toFixed()} ${d.toFixed()}`\n\t}\n\n\tstatic GetAtT(segment: CubicBezier2d, t: number) {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = segment\n\t\treturn new Vec(\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.x +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.x +\n\t\t\t\t3 * (1 - t) * (t * t) * c.x +\n\t\t\t\tt * t * t * d.x,\n\t\t\t(1 - t) * (1 - t) * (1 - t) * a.y +\n\t\t\t\t3 * ((1 - t) * (1 - t)) * t * b.y +\n\t\t\t\t3 * (1 - t) * (t * t) * c.y +\n\t\t\t\tt * t * t * d.y\n\t\t)\n\t}\n\n\toverride getLength(_filters?: Geometry2dFilters, precision = 32) {\n\t\tlet n1: Vec,\n\t\t\tp1 = this._a,\n\t\t\tlength = 0\n\t\tfor (let i = 1; i <= precision; i++) {\n\t\t\tn1 = CubicBezier2d.GetAtT(this, i / precision)\n\t\t\tlength += Vec.Dist(p1, n1)\n\t\t\tp1 = n1\n\t\t}\n\t\treturn length\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,7 @@ import { Vec } from "../Vec.mjs";
3
3
  import { PI, PI2, clamp, perimeterOfEllipse } from "../utils.mjs";
4
4
  import { Edge2d } from "./Edge2d.mjs";
5
5
  import { Geometry2d } from "./Geometry2d.mjs";
6
- import { getVerticesCountForLength } from "./geometry-constants.mjs";
6
+ import { getVerticesCountForArcLength } from "./geometry-constants.mjs";
7
7
  class Ellipse2d extends Geometry2d {
8
8
  constructor(config) {
9
9
  super({ ...config, isClosed: true });
@@ -35,7 +35,7 @@ class Ellipse2d extends Geometry2d {
35
35
  const cy = h / 2;
36
36
  const q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2);
37
37
  const p = PI * (cx + cy) * (1 + 3 * q / (10 + Math.sqrt(4 - 3 * q)));
38
- const len = getVerticesCountForLength(p);
38
+ const len = getVerticesCountForArcLength(p);
39
39
  const step = PI2 / len;
40
40
  const a = Math.cos(step);
41
41
  const b = Math.sin(step);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Ellipse2d.ts"],
4
- "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { PI, PI2, clamp, perimeterOfEllipse } from '../utils'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForLength } from './geometry-constants'\n\n/** @public */\nexport class Ellipse2d extends Geometry2d {\n\tprivate _w: number\n\tprivate _h: number\n\tprivate _edges?: Edge2d[]\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width, height } = config\n\t\tthis._w = width\n\t\tthis._h = height\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget edges() {\n\t\tif (!this._edges) {\n\t\t\tconst { vertices } = this\n\t\t\tthis._edges = []\n\t\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[(i + 1) % n]\n\t\t\t\tthis._edges.push(new Edge2d({ start, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._edges\n\t}\n\n\tgetVertices() {\n\t\t// Perimeter of the ellipse\n\t\tconst w = Math.max(1, this._w)\n\t\tconst h = Math.max(1, this._h)\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2)\n\t\tconst p = PI * (cx + cy) * (1 + (3 * q) / (10 + Math.sqrt(4 - 3 * q)))\n\t\t// Number of points\n\t\tconst len = getVerticesCountForLength(p)\n\t\t// Size of step\n\t\tconst step = PI2 / len\n\n\t\tconst a = Math.cos(step)\n\t\tconst b = Math.sin(step)\n\n\t\tlet sin = 0\n\t\tlet cos = 1\n\t\tlet ts = 0\n\t\tlet tc = 1\n\n\t\tconst vertices = Array(len)\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tvertices[i] = new Vec(clamp(cx + cx * cos, 0, w), clamp(cy + cy * sin, 0, h))\n\t\t\tts = b * cos + a * sin\n\t\t\ttc = a * cos - b * sin\n\t\t\tsin = ts\n\t\t\tcos = tc\n\t\t}\n\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.edges) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\treturn this.edges.some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this._w, this._h)\n\t}\n\n\tgetLength(): number {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn perimeterOfEllipse(rx, ry)\n\t}\n\n\tgetSvgPathData(first = false) {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn `${first ? `M${cx - rx},${cy}` : ``} a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { PI, PI2, clamp, perimeterOfEllipse } from '../utils'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\n\n/** @public */\nexport class Ellipse2d extends Geometry2d {\n\tprivate _w: number\n\tprivate _h: number\n\tprivate _edges?: Edge2d[]\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width, height } = config\n\t\tthis._w = width\n\t\tthis._h = height\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget edges() {\n\t\tif (!this._edges) {\n\t\t\tconst { vertices } = this\n\t\t\tthis._edges = []\n\t\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[(i + 1) % n]\n\t\t\t\tthis._edges.push(new Edge2d({ start, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._edges\n\t}\n\n\tgetVertices() {\n\t\t// Perimeter of the ellipse\n\t\tconst w = Math.max(1, this._w)\n\t\tconst h = Math.max(1, this._h)\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2)\n\t\tconst p = PI * (cx + cy) * (1 + (3 * q) / (10 + Math.sqrt(4 - 3 * q)))\n\t\t// Number of points\n\t\tconst len = getVerticesCountForArcLength(p)\n\t\t// Size of step\n\t\tconst step = PI2 / len\n\n\t\tconst a = Math.cos(step)\n\t\tconst b = Math.sin(step)\n\n\t\tlet sin = 0\n\t\tlet cos = 1\n\t\tlet ts = 0\n\t\tlet tc = 1\n\n\t\tconst vertices = Array(len)\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tvertices[i] = new Vec(clamp(cx + cx * cos, 0, w), clamp(cy + cy * sin, 0, h))\n\t\t\tts = b * cos + a * sin\n\t\t\ttc = a * cos - b * sin\n\t\t\tsin = ts\n\t\t\tcos = tc\n\t\t}\n\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.edges) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\treturn this.edges.some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this._w, this._h)\n\t}\n\n\tgetLength(): number {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn perimeterOfEllipse(rx, ry)\n\t}\n\n\tgetSvgPathData(first = false) {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn `${first ? `M${cx - rx},${cy}` : ``} a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,9 +1,9 @@
1
1
  const SPACING = 20;
2
2
  const MIN_COUNT = 8;
3
- function getVerticesCountForLength(length, spacing = SPACING) {
3
+ function getVerticesCountForArcLength(length, spacing = SPACING) {
4
4
  return Math.max(MIN_COUNT, Math.ceil(length / spacing));
5
5
  }
6
6
  export {
7
- getVerticesCountForLength
7
+ getVerticesCountForArcLength
8
8
  };
9
9
  //# sourceMappingURL=geometry-constants.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/geometry-constants.ts"],
4
- "sourcesContent": ["const SPACING = 20\nconst MIN_COUNT = 8\n\nexport function getVerticesCountForLength(length: number, spacing = SPACING) {\n\treturn Math.max(MIN_COUNT, Math.ceil(length / spacing))\n}\n"],
5
- "mappings": "AAAA,MAAM,UAAU;AAChB,MAAM,YAAY;AAEX,SAAS,0BAA0B,QAAgB,UAAU,SAAS;AAC5E,SAAO,KAAK,IAAI,WAAW,KAAK,KAAK,SAAS,OAAO,CAAC;AACvD;",
4
+ "sourcesContent": ["const SPACING = 20\nconst MIN_COUNT = 8\n\n/** @internal */\nexport function getVerticesCountForArcLength(length: number, spacing = SPACING) {\n\treturn Math.max(MIN_COUNT, Math.ceil(length / spacing))\n}\n"],
5
+ "mappings": "AAAA,MAAM,UAAU;AAChB,MAAM,YAAY;AAGX,SAAS,6BAA6B,QAAgB,UAAU,SAAS;AAC/E,SAAO,KAAK,IAAI,WAAW,KAAK,KAAK,SAAS,OAAO,CAAC;AACvD;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "3.15.0-canary.d251cd98b4e1";
1
+ const version = "3.15.0-canary.d48536dd9c3c";
2
2
  const publishDates = {
3
3
  major: "2024-09-13T14:36:29.063Z",
4
- minor: "2025-07-09T14:00:46.148Z",
5
- patch: "2025-07-09T14:00:46.148Z"
4
+ minor: "2025-07-16T14:24:26.375Z",
5
+ patch: "2025-07-16T14:24:26.375Z"
6
6
  };
7
7
  export {
8
8
  publishDates,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.15.0-canary.d251cd98b4e1'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-07-09T14:00:46.148Z',\n\tpatch: '2025-07-09T14:00:46.148Z',\n}\n"],
4
+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.15.0-canary.d48536dd9c3c'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-07-16T14:24:26.375Z',\n\tpatch: '2025-07-16T14:24:26.375Z',\n}\n"],
5
5
  "mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
package/editor.css CHANGED
@@ -167,7 +167,7 @@
167
167
  --color-text: hsl(0, 0%, 0%);
168
168
  --color-text-0: hsl(0, 0%, 11%);
169
169
  --color-text-1: hsl(0, 0%, 18%);
170
- --color-text-3: hsl(220, 2%, 65%);
170
+ --color-text-3: hsl(204, 4%, 45%);
171
171
  --color-text-shadow: hsl(0, 0%, 100%);
172
172
  --color-text-highlight: hsl(52, 100%, 50%);
173
173
  --color-text-highlight-p3: color(display-p3 0.972 0.8205 0.05);
@@ -222,7 +222,7 @@
222
222
  --color-text: hsl(210, 17%, 98%);
223
223
  --color-text-0: hsl(0, 9%, 94%);
224
224
  --color-text-1: hsl(0, 0%, 85%);
225
- --color-text-3: hsl(210, 6%, 45%);
225
+ --color-text-3: hsl(204, 4%, 75%);
226
226
  --color-text-shadow: hsl(210, 13%, 18%);
227
227
  --color-text-highlight: hsl(52, 100%, 41%);
228
228
  --color-text-highlight-p3: color(display-p3 0.8078 0.6225 0.0312);
@@ -968,14 +968,14 @@ input,
968
968
  font-size: 14px;
969
969
  font-weight: 500;
970
970
  opacity: 0;
971
- animation: fade-in 0.2s ease-in-out forwards;
971
+ animation: tl-fade-in 0.2s ease-in-out forwards;
972
972
  animation-delay: 0.2s;
973
973
  position: absolute;
974
974
  inset: 0px;
975
975
  z-index: var(--layer-canvas-blocker);
976
976
  }
977
977
 
978
- @keyframes fade-in {
978
+ @keyframes tl-fade-in {
979
979
  0% {
980
980
  opacity: 0;
981
981
  }
@@ -984,6 +984,19 @@ input,
984
984
  }
985
985
  }
986
986
 
987
+ .tl-spinner {
988
+ animation: tl-spin 1s linear infinite;
989
+ }
990
+
991
+ @keyframes tl-spin {
992
+ 0% {
993
+ transform: rotate(0deg);
994
+ }
995
+ 100% {
996
+ transform: rotate(360deg);
997
+ }
998
+ }
999
+
987
1000
  /* ---------------------- Brush --------------------- */
988
1001
 
989
1002
  .tl-brush {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tldraw/editor",
3
- "description": "A tiny little drawing app (editor).",
4
- "version": "3.15.0-canary.d251cd98b4e1",
3
+ "description": "tldraw infinite canvas SDK (editor).",
4
+ "version": "3.15.0-canary.d48536dd9c3c",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -17,6 +17,7 @@
17
17
  },
18
18
  "keywords": [
19
19
  "tldraw",
20
+ "sdk",
20
21
  "drawing",
21
22
  "app",
22
23
  "development",
@@ -48,12 +49,12 @@
48
49
  "@tiptap/core": "^2.9.1",
49
50
  "@tiptap/pm": "^2.9.1",
50
51
  "@tiptap/react": "^2.9.1",
51
- "@tldraw/state": "3.15.0-canary.d251cd98b4e1",
52
- "@tldraw/state-react": "3.15.0-canary.d251cd98b4e1",
53
- "@tldraw/store": "3.15.0-canary.d251cd98b4e1",
54
- "@tldraw/tlschema": "3.15.0-canary.d251cd98b4e1",
55
- "@tldraw/utils": "3.15.0-canary.d251cd98b4e1",
56
- "@tldraw/validate": "3.15.0-canary.d251cd98b4e1",
52
+ "@tldraw/state": "3.15.0-canary.d48536dd9c3c",
53
+ "@tldraw/state-react": "3.15.0-canary.d48536dd9c3c",
54
+ "@tldraw/store": "3.15.0-canary.d48536dd9c3c",
55
+ "@tldraw/tlschema": "3.15.0-canary.d48536dd9c3c",
56
+ "@tldraw/utils": "3.15.0-canary.d48536dd9c3c",
57
+ "@tldraw/validate": "3.15.0-canary.d48536dd9c3c",
57
58
  "@types/core-js": "^2.5.8",
58
59
  "@use-gesture/react": "^10.3.1",
59
60
  "classnames": "^2.5.1",
package/src/index.ts CHANGED
@@ -346,6 +346,7 @@ export { CubicBezier2d } from './lib/primitives/geometry/CubicBezier2d'
346
346
  export { CubicSpline2d } from './lib/primitives/geometry/CubicSpline2d'
347
347
  export { Edge2d } from './lib/primitives/geometry/Edge2d'
348
348
  export { Ellipse2d } from './lib/primitives/geometry/Ellipse2d'
349
+ export { getVerticesCountForArcLength } from './lib/primitives/geometry/geometry-constants'
349
350
  export {
350
351
  Geometry2d,
351
352
  Geometry2dFilters,
@@ -7,7 +7,7 @@ export type SVGContainerProps = React.ComponentProps<'svg'>
7
7
  /** @public @react */
8
8
  export function SVGContainer({ children, className = '', ...rest }: SVGContainerProps) {
9
9
  return (
10
- <svg {...rest} className={classNames('tl-svg-container', className)}>
10
+ <svg {...rest} className={classNames('tl-svg-container', className)} aria-hidden="true">
11
11
  {children}
12
12
  </svg>
13
13
  )
@@ -21,7 +21,7 @@ export const DefaultBrush = ({ brush, color, opacity, className }: TLBrushProps)
21
21
  const h = toDomPrecision(Math.max(1, brush.h))
22
22
 
23
23
  return (
24
- <svg className="tl-overlays__item" ref={rSvg}>
24
+ <svg className="tl-overlays__item" ref={rSvg} aria-hidden="true">
25
25
  {color ? (
26
26
  <g className="tl-brush" opacity={opacity}>
27
27
  <rect width={w} height={h} fill={color} opacity={0.75} />
@@ -139,7 +139,7 @@ export function DefaultCanvas({ className }: TLCanvasComponentProps) {
139
139
  data-testid="canvas"
140
140
  {...events}
141
141
  >
142
- <svg className="tl-svg-context">
142
+ <svg className="tl-svg-context" aria-hidden="true">
143
143
  <defs>
144
144
  {shapeSvgDefs}
145
145
  <CursorDef />
@@ -39,7 +39,7 @@ export function DefaultCollaboratorHint({
39
39
  const cursorHintId = useSharedSafeId('cursor_hint')
40
40
 
41
41
  return (
42
- <svg ref={rSvg} className={classNames('tl-overlays__item', className)}>
42
+ <svg ref={rSvg} className={classNames('tl-overlays__item', className)} aria-hidden="true">
43
43
  <use
44
44
  href={`#${cursorHintId}`}
45
45
  color={color}
@@ -33,7 +33,7 @@ export const DefaultCursor = memo(function DefaultCursor({
33
33
 
34
34
  return (
35
35
  <div ref={rCursor} className={classNames('tl-overlays__item', className)}>
36
- <svg className="tl-cursor">
36
+ <svg className="tl-cursor" aria-hidden="true">
37
37
  <use href={`#${cursorId}`} color={color} />
38
38
  </svg>
39
39
  {chatMessage ? (
@@ -16,7 +16,7 @@ export function DefaultGrid({ x, y, z, size }: TLGridProps) {
16
16
  const editor = useEditor()
17
17
  const { gridSteps } = editor.options
18
18
  return (
19
- <svg className="tl-grid" version="1.1" xmlns="http://www.w3.org/2000/svg">
19
+ <svg className="tl-grid" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
20
20
  <defs>
21
21
  {gridSteps.map(({ min, mid, step }, i) => {
22
22
  const s = step * size * z
@@ -7,5 +7,9 @@ export interface TLHandlesProps {
7
7
 
8
8
  /** @public @react */
9
9
  export const DefaultHandles = ({ children }: TLHandlesProps) => {
10
- return <svg className="tl-user-handles tl-overlays__item">{children}</svg>
10
+ return (
11
+ <svg className="tl-user-handles tl-overlays__item" aria-hidden="true">
12
+ {children}
13
+ </svg>
14
+ )
11
15
  }
@@ -86,7 +86,7 @@ export const DefaultShapeIndicator = memo(function DefaultShapeIndicator({
86
86
  }, [hidden])
87
87
 
88
88
  return (
89
- <svg ref={rIndicator} className={classNames('tl-overlays__item', className)}>
89
+ <svg ref={rIndicator} className={classNames('tl-overlays__item', className)} aria-hidden="true">
90
90
  <g className="tl-shape-indicator" stroke={color ?? 'var(--color-selected)'} opacity={opacity}>
91
91
  <InnerIndicator editor={editor} id={shapeId} />
92
92
  </g>
@@ -163,7 +163,7 @@ export interface TLSnapIndicatorProps {
163
163
  /** @public @react */
164
164
  export function DefaultSnapIndicator({ className, line, zoom }: TLSnapIndicatorProps) {
165
165
  return (
166
- <svg className={classNames('tl-overlays__item', className)}>
166
+ <svg className={classNames('tl-overlays__item', className)} aria-hidden="true">
167
167
  {line.type === 'points' ? (
168
168
  <PointsSnapIndicator {...line} zoom={zoom} />
169
169
  ) : line.type === 'gaps' ? (
@@ -1,19 +1,19 @@
1
+ import classNames from 'classnames'
2
+
1
3
  /** @public @react */
2
- export function DefaultSpinner() {
4
+ export function DefaultSpinner(props: React.SVGProps<SVGSVGElement>) {
3
5
  return (
4
- <svg width={16} height={16} viewBox="0 0 16 16" aria-hidden="false">
6
+ <svg
7
+ width={16}
8
+ height={16}
9
+ viewBox="0 0 16 16"
10
+ aria-hidden="false"
11
+ {...props}
12
+ className={classNames('tl-spinner', props.className)}
13
+ >
5
14
  <g strokeWidth={2} fill="none" fillRule="evenodd">
6
15
  <circle strokeOpacity={0.25} cx={8} cy={8} r={7} stroke="currentColor" />
7
- <path strokeLinecap="round" d="M15 8c0-4.5-4.5-7-7-7" stroke="currentColor">
8
- <animateTransform
9
- attributeName="transform"
10
- type="rotate"
11
- from="0 8 8"
12
- to="360 8 8"
13
- dur="1s"
14
- repeatCount="indefinite"
15
- />
16
- </path>
16
+ <path strokeLinecap="round" d="M15 8c0-4.5-4.5-7-7-7" stroke="currentColor" />
17
17
  </g>
18
18
  </svg>
19
19
  )