@tldraw/editor 4.5.3 → 4.6.0-canary.00a8c03b5687
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +37 -6
- package/dist-cjs/index.js +6 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +7 -5
- package/dist-cjs/lib/TldrawEditor.js.map +3 -3
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +3 -2
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +8 -5
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/config/TLSessionStateSnapshot.js +8 -5
- package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +2 -2
- package/dist-cjs/lib/config/TLUserPreferences.js +3 -2
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/config/createTLStore.js +1 -0
- package/dist-cjs/lib/config/createTLStore.js.map +2 -2
- package/dist-cjs/lib/config/createTLUser.js.map +1 -1
- package/dist-cjs/lib/editor/Editor.js +511 -366
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +25 -64
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +22 -5
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +4 -3
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +5 -0
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +71 -112
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js +20 -55
- package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +1 -1
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js +11 -52
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +1 -1
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +19 -56
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +2 -2
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +16 -55
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +60 -70
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
- package/dist-cjs/lib/exports/ExportDelay.js +12 -53
- package/dist-cjs/lib/exports/ExportDelay.js.map +1 -1
- package/dist-cjs/lib/exports/FontEmbedder.js +23 -65
- package/dist-cjs/lib/exports/FontEmbedder.js.map +2 -2
- package/dist-cjs/lib/exports/StyleEmbedder.js +27 -15
- package/dist-cjs/lib/exports/StyleEmbedder.js.map +3 -3
- package/dist-cjs/lib/exports/domUtils.js +15 -0
- package/dist-cjs/lib/exports/domUtils.js.map +2 -2
- package/dist-cjs/lib/exports/embedMedia.js +15 -12
- package/dist-cjs/lib/exports/embedMedia.js.map +2 -2
- package/dist-cjs/lib/exports/exportToSvg.js +8 -7
- package/dist-cjs/lib/exports/exportToSvg.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgAsImage.js +181 -29
- package/dist-cjs/lib/exports/getSvgAsImage.js.map +3 -3
- package/dist-cjs/lib/exports/getSvgJsx.js +21 -9
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/globals/environment.js +4 -3
- package/dist-cjs/lib/globals/environment.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +13 -11
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js +3 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useScreenBounds.js +10 -6
- package/dist-cjs/lib/hooks/useScreenBounds.js.map +2 -2
- package/dist-cjs/lib/hooks/useViewportHeight.js +13 -11
- package/dist-cjs/lib/hooks/useViewportHeight.js.map +3 -3
- package/dist-cjs/lib/license/Watermark.js +10 -0
- package/dist-cjs/lib/license/Watermark.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +25 -25
- package/dist-cjs/lib/primitives/Box.js.map +1 -1
- package/dist-cjs/lib/primitives/Vec.js +36 -23
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js +6 -13
- package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Circle2d.js +31 -2
- package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +9 -0
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js +10 -1
- package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Edge2d.js +32 -18
- package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +13 -1
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +6 -6
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +1 -1
- package/dist-cjs/lib/primitives/geometry/Polyline2d.js +52 -13
- package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js +12 -0
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/geometry.bench.js +133 -0
- package/dist-cjs/lib/primitives/geometry/geometry.bench.js.map +7 -0
- package/dist-cjs/lib/primitives/intersect.js +16 -15
- package/dist-cjs/lib/primitives/intersect.js.map +2 -2
- package/dist-cjs/lib/primitives/utils.js +0 -1
- package/dist-cjs/lib/primitives/utils.js.map +2 -2
- package/dist-cjs/lib/utils/SharedStylesMap.js +1 -1
- package/dist-cjs/lib/utils/SharedStylesMap.js.map +1 -1
- package/dist-cjs/lib/utils/browserCanvasMaxSize.js +3 -2
- package/dist-cjs/lib/utils/browserCanvasMaxSize.js.map +2 -2
- package/dist-cjs/lib/utils/dom.js +15 -2
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +2 -1
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +37 -6
- package/dist-esm/index.mjs +8 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +7 -5
- package/dist-esm/lib/TldrawEditor.mjs.map +3 -3
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +2 -1
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +8 -5
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/config/TLSessionStateSnapshot.mjs +8 -5
- package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs +3 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/config/createTLStore.mjs +1 -0
- package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
- package/dist-esm/lib/config/createTLUser.mjs.map +1 -1
- package/dist-esm/lib/editor/Editor.mjs +512 -368
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +25 -64
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +24 -5
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +4 -3
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +5 -0
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +71 -112
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs +20 -55
- package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs +11 -52
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +19 -56
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +2 -2
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +16 -55
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +60 -70
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/exports/ExportDelay.mjs +12 -53
- package/dist-esm/lib/exports/ExportDelay.mjs.map +1 -1
- package/dist-esm/lib/exports/FontEmbedder.mjs +23 -65
- package/dist-esm/lib/exports/FontEmbedder.mjs.map +2 -2
- package/dist-esm/lib/exports/StyleEmbedder.mjs +29 -16
- package/dist-esm/lib/exports/StyleEmbedder.mjs.map +3 -3
- package/dist-esm/lib/exports/domUtils.mjs +15 -0
- package/dist-esm/lib/exports/domUtils.mjs.map +2 -2
- package/dist-esm/lib/exports/embedMedia.mjs +16 -13
- package/dist-esm/lib/exports/embedMedia.mjs.map +2 -2
- package/dist-esm/lib/exports/exportToSvg.mjs +8 -7
- package/dist-esm/lib/exports/exportToSvg.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgAsImage.mjs +181 -29
- package/dist-esm/lib/exports/getSvgAsImage.mjs.map +3 -3
- package/dist-esm/lib/exports/getSvgJsx.mjs +21 -9
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/globals/environment.mjs +4 -3
- package/dist-esm/lib/globals/environment.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +13 -11
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs +3 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useScreenBounds.mjs +10 -6
- package/dist-esm/lib/hooks/useScreenBounds.mjs.map +2 -2
- package/dist-esm/lib/hooks/useViewportHeight.mjs +13 -11
- package/dist-esm/lib/hooks/useViewportHeight.mjs.map +3 -3
- package/dist-esm/lib/license/Watermark.mjs +10 -0
- package/dist-esm/lib/license/Watermark.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +25 -25
- package/dist-esm/lib/primitives/Box.mjs.map +1 -1
- package/dist-esm/lib/primitives/Vec.mjs +36 -23
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs +6 -13
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs +31 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +9 -0
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs +10 -1
- package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs +32 -18
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +14 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +6 -6
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +1 -1
- package/dist-esm/lib/primitives/geometry/Polyline2d.mjs +52 -13
- package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +13 -1
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/geometry.bench.mjs +132 -0
- package/dist-esm/lib/primitives/geometry/geometry.bench.mjs.map +7 -0
- package/dist-esm/lib/primitives/intersect.mjs +17 -16
- package/dist-esm/lib/primitives/intersect.mjs.map +2 -2
- package/dist-esm/lib/primitives/utils.mjs +0 -1
- package/dist-esm/lib/primitives/utils.mjs.map +2 -2
- package/dist-esm/lib/utils/SharedStylesMap.mjs +1 -1
- package/dist-esm/lib/utils/SharedStylesMap.mjs.map +1 -1
- package/dist-esm/lib/utils/browserCanvasMaxSize.mjs +3 -2
- package/dist-esm/lib/utils/browserCanvasMaxSize.mjs.map +2 -2
- package/dist-esm/lib/utils/dom.mjs +15 -2
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +2 -1
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +8 -8
- package/src/index.ts +10 -6
- package/src/lib/TldrawEditor.tsx +7 -5
- package/src/lib/components/default-components/CanvasShapeIndicators.tsx +2 -1
- package/src/lib/components/default-components/DefaultCanvas.tsx +1 -1
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +9 -5
- package/src/lib/config/TLSessionStateSnapshot.ts +8 -5
- package/src/lib/config/TLUserPreferences.ts +3 -2
- package/src/lib/config/createTLStore.ts +3 -0
- package/src/lib/config/createTLUser.ts +3 -3
- package/src/lib/editor/Editor.ts +53 -15
- package/src/lib/editor/managers/ClickManager/ClickManager.ts +1 -1
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +7 -6
- package/src/lib/editor/managers/FocusManager/FocusManager.ts +10 -7
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +1 -0
- package/src/lib/editor/managers/FontManager/FontManager.ts +4 -3
- package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +16 -0
- package/src/lib/editor/managers/HistoryManager/HistoryManager.ts +7 -2
- package/src/lib/editor/managers/InputsManager/InputsManager.ts +30 -30
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +4 -5
- package/src/lib/editor/managers/TextManager/TextManager.ts +2 -2
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +3 -2
- package/src/lib/editor/types/misc-types.ts +8 -2
- package/src/lib/exports/FontEmbedder.ts +10 -9
- package/src/lib/exports/StyleEmbedder.ts +33 -15
- package/src/lib/exports/domUtils.ts +20 -0
- package/src/lib/exports/embedMedia.ts +23 -17
- package/src/lib/exports/exportToSvg.tsx +8 -7
- package/src/lib/exports/getSvgAsImage.ts +292 -32
- package/src/lib/exports/getSvgJsx.test.ts +103 -101
- package/src/lib/exports/getSvgJsx.tsx +33 -10
- package/src/lib/globals/environment.ts +4 -3
- package/src/lib/hooks/useCanvasEvents.ts +2 -3
- package/src/lib/hooks/useDocumentEvents.ts +16 -11
- package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +3 -3
- package/src/lib/hooks/useScreenBounds.ts +10 -6
- package/src/lib/hooks/useViewportHeight.ts +13 -11
- package/src/lib/license/Watermark.tsx +10 -0
- package/src/lib/primitives/Box.ts +25 -25
- package/src/lib/primitives/Vec.ts +52 -25
- package/src/lib/primitives/geometry/Arc2d.ts +10 -15
- package/src/lib/primitives/geometry/Circle2d.ts +40 -2
- package/src/lib/primitives/geometry/CubicBezier2d.ts +10 -0
- package/src/lib/primitives/geometry/CubicSpline2d.ts +11 -1
- package/src/lib/primitives/geometry/Edge2d.ts +41 -18
- package/src/lib/primitives/geometry/Ellipse2d.ts +15 -2
- package/src/lib/primitives/geometry/Geometry2d.ts +6 -6
- package/src/lib/primitives/geometry/Polyline2d.ts +61 -13
- package/src/lib/primitives/geometry/Stadium2d.ts +14 -1
- package/src/lib/primitives/geometry/geometry.bench.ts +179 -0
- package/src/lib/primitives/intersect.ts +27 -27
- package/src/lib/primitives/utils.ts +4 -4
- package/src/lib/test/TestEditor.ts +1 -0
- package/src/lib/utils/SharedStylesMap.ts +1 -1
- package/src/lib/utils/browserCanvasMaxSize.ts +4 -2
- package/src/lib/utils/dom.ts +34 -2
- package/src/lib/utils/sync/TLLocalSyncClient.ts +1 -0
- package/src/version.ts +3 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useLayoutEffect, useState } from 'react'
|
|
2
|
+
import { useMaybeEditor } from './useEditor'
|
|
2
3
|
|
|
3
4
|
/*!
|
|
4
5
|
* BSD License: https://github.com/outline/rich-markdown-editor/blob/main/LICENSE
|
|
@@ -12,26 +13,27 @@ import { useLayoutEffect, useState } from 'react'
|
|
|
12
13
|
*/
|
|
13
14
|
/** @public */
|
|
14
15
|
export function useViewportHeight(): number {
|
|
15
|
-
const
|
|
16
|
+
const editor = useMaybeEditor()
|
|
17
|
+
const win = editor?.getContainerWindow() ?? window
|
|
18
|
+
const vv = win.visualViewport
|
|
16
19
|
const [height, setHeight] = useState<number>(() =>
|
|
17
|
-
|
|
20
|
+
vv ? vv.height + vv.offsetTop : win.innerHeight
|
|
18
21
|
)
|
|
19
22
|
|
|
20
23
|
useLayoutEffect(() => {
|
|
24
|
+
const win = editor?.getContainerWindow() ?? window
|
|
21
25
|
const handleResize = () => {
|
|
22
|
-
const
|
|
23
|
-
setHeight(() =>
|
|
24
|
-
visualViewport ? visualViewport.height + visualViewport.offsetTop : window.innerHeight
|
|
25
|
-
)
|
|
26
|
+
const vv = win.visualViewport
|
|
27
|
+
setHeight(() => (vv ? vv.height + vv.offsetTop : win.innerHeight))
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
win.visualViewport?.addEventListener('resize', handleResize)
|
|
31
|
+
win.visualViewport?.addEventListener('scroll', handleResize)
|
|
30
32
|
|
|
31
33
|
return () => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
win.visualViewport?.removeEventListener('resize', handleResize)
|
|
35
|
+
win.visualViewport?.removeEventListener('scroll', handleResize)
|
|
34
36
|
}
|
|
35
|
-
}, [])
|
|
37
|
+
}, [editor])
|
|
36
38
|
return height
|
|
37
39
|
}
|
|
@@ -191,6 +191,16 @@ To remove the watermark, please purchase a license at tldraw.dev.
|
|
|
191
191
|
height: 32px;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
.tl-container[dir='rtl'] .${className} {
|
|
195
|
+
right: auto;
|
|
196
|
+
left: max(var(--tl-space-2), env(safe-area-inset-left));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.tl-container[dir='rtl'] .${className}[data-mobile='true'] {
|
|
200
|
+
border-radius: 0px 4px 4px 0px;
|
|
201
|
+
left: max(-2px, calc(env(safe-area-inset-left) - 2px));
|
|
202
|
+
}
|
|
203
|
+
|
|
194
204
|
.${className}[data-unlicensed='true'] > button {
|
|
195
205
|
font-size: 100px;
|
|
196
206
|
position: absolute;
|
|
@@ -36,114 +36,114 @@ export class Box {
|
|
|
36
36
|
w = 0
|
|
37
37
|
h = 0
|
|
38
38
|
|
|
39
|
-
// eslint-disable-next-line no-
|
|
39
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
40
40
|
get point() {
|
|
41
41
|
return new Vec(this.x, this.y)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
// eslint-disable-next-line no-
|
|
44
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
45
45
|
set point(val: Vec) {
|
|
46
46
|
this.x = val.x
|
|
47
47
|
this.y = val.y
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
// eslint-disable-next-line no-
|
|
50
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
51
51
|
get minX() {
|
|
52
52
|
return this.x
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
// eslint-disable-next-line no-
|
|
55
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
56
56
|
set minX(n: number) {
|
|
57
57
|
this.x = n
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
// eslint-disable-next-line no-
|
|
60
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
61
61
|
get left() {
|
|
62
62
|
return this.x
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
// eslint-disable-next-line no-
|
|
65
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
66
66
|
get midX() {
|
|
67
67
|
return this.x + this.w / 2
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
// eslint-disable-next-line no-
|
|
70
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
71
71
|
get maxX() {
|
|
72
72
|
return this.x + this.w
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
// eslint-disable-next-line no-
|
|
75
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
76
76
|
get right() {
|
|
77
77
|
return this.x + this.w
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
// eslint-disable-next-line no-
|
|
80
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
81
81
|
get minY() {
|
|
82
82
|
return this.y
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
// eslint-disable-next-line no-
|
|
85
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
86
86
|
set minY(n: number) {
|
|
87
87
|
this.y = n
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
// eslint-disable-next-line no-
|
|
90
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
91
91
|
get top() {
|
|
92
92
|
return this.y
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
// eslint-disable-next-line no-
|
|
95
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
96
96
|
get midY() {
|
|
97
97
|
return this.y + this.h / 2
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
// eslint-disable-next-line no-
|
|
100
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
101
101
|
get maxY() {
|
|
102
102
|
return this.y + this.h
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
// eslint-disable-next-line no-
|
|
105
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
106
106
|
get bottom() {
|
|
107
107
|
return this.y + this.h
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
// eslint-disable-next-line no-
|
|
110
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
111
111
|
get width() {
|
|
112
112
|
return this.w
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
// eslint-disable-next-line no-
|
|
115
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
116
116
|
set width(n: number) {
|
|
117
117
|
this.w = n
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
// eslint-disable-next-line no-
|
|
120
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
121
121
|
get height() {
|
|
122
122
|
return this.h
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
// eslint-disable-next-line no-
|
|
125
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
126
126
|
set height(n: number) {
|
|
127
127
|
this.h = n
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
// eslint-disable-next-line no-
|
|
130
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
131
131
|
get aspectRatio() {
|
|
132
132
|
return this.width / this.height
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
// eslint-disable-next-line no-
|
|
135
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
136
136
|
get center() {
|
|
137
137
|
return new Vec(this.x + this.w / 2, this.y + this.h / 2)
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
// eslint-disable-next-line no-
|
|
140
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
141
141
|
set center(v: Vec) {
|
|
142
142
|
this.x = v.x - this.w / 2
|
|
143
143
|
this.y = v.y - this.h / 2
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
// eslint-disable-next-line no-
|
|
146
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
147
147
|
get corners() {
|
|
148
148
|
return [
|
|
149
149
|
new Vec(this.x, this.y),
|
|
@@ -153,7 +153,7 @@ export class Box {
|
|
|
153
153
|
]
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
// eslint-disable-next-line no-
|
|
156
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
157
157
|
get cornersAndCenter() {
|
|
158
158
|
return [
|
|
159
159
|
new Vec(this.x, this.y),
|
|
@@ -164,7 +164,7 @@ export class Box {
|
|
|
164
164
|
]
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
// eslint-disable-next-line no-
|
|
167
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
168
168
|
get sides(): Array<[Vec, Vec]> {
|
|
169
169
|
const { corners } = this
|
|
170
170
|
return [
|
|
@@ -175,7 +175,7 @@ export class Box {
|
|
|
175
175
|
]
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
// eslint-disable-next-line no-
|
|
178
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
179
179
|
get size(): Vec {
|
|
180
180
|
return new Vec(this.w, this.h)
|
|
181
181
|
}
|
|
@@ -19,7 +19,7 @@ export class Vec {
|
|
|
19
19
|
public z = 1
|
|
20
20
|
) {}
|
|
21
21
|
|
|
22
|
-
// eslint-disable-next-line no-
|
|
22
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
23
23
|
get pressure() {
|
|
24
24
|
return this.z
|
|
25
25
|
}
|
|
@@ -430,32 +430,58 @@ export class Vec {
|
|
|
430
430
|
* @param P - A point not on the line to test.
|
|
431
431
|
*/
|
|
432
432
|
static NearestPointOnLineThroughPoint(A: VecLike, u: VecLike, P: VecLike): Vec {
|
|
433
|
-
|
|
433
|
+
// Inlined: t = Vec.Sub(P, A).pry(u), return Vec.Mul(u, t).add(A)
|
|
434
|
+
const t = (P.x - A.x) * u.x + (P.y - A.y) * u.y
|
|
435
|
+
return new Vec(A.x + u.x * t, A.y + u.y * t)
|
|
434
436
|
}
|
|
435
437
|
|
|
436
438
|
static NearestPointOnLineSegment(A: VecLike, B: VecLike, P: VecLike, clamp = true): Vec {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
+
// Parametric projection of P onto segment AB.
|
|
440
|
+
// Inlined: d = Vec.Sub(B, A); t = Vec.Sub(P, A).pry(d) / d.len(); return Vec.Lrp(A, B, t)
|
|
441
|
+
const dx = B.x - A.x
|
|
442
|
+
const dy = B.y - A.y
|
|
443
|
+
const d2 = dx * dx + dy * dy
|
|
439
444
|
|
|
440
|
-
|
|
441
|
-
|
|
445
|
+
if (d2 === 0) return Vec.From(A)
|
|
446
|
+
|
|
447
|
+
let t = ((P.x - A.x) * dx + (P.y - A.y) * dy) / d2
|
|
442
448
|
|
|
443
449
|
if (clamp) {
|
|
444
|
-
if (
|
|
445
|
-
if (
|
|
446
|
-
if (C.y < Math.min(A.y, B.y)) return Vec.Cast(A.y < B.y ? A : B)
|
|
447
|
-
if (C.y > Math.max(A.y, B.y)) return Vec.Cast(A.y > B.y ? A : B)
|
|
450
|
+
if (t < 0) t = 0
|
|
451
|
+
else if (t > 1) t = 1
|
|
448
452
|
}
|
|
449
453
|
|
|
450
|
-
return
|
|
454
|
+
return new Vec(A.x + t * dx, A.y + t * dy)
|
|
451
455
|
}
|
|
452
456
|
|
|
453
457
|
static DistanceToLineThroughPoint(A: VecLike, u: VecLike, P: VecLike): number {
|
|
454
|
-
|
|
458
|
+
// Inlined: Vec.Dist(P, Vec.NearestPointOnLineThroughPoint(A, u, P))
|
|
459
|
+
// Uses |cross(P-A, u)| which equals the perpendicular distance when u is a unit vector.
|
|
460
|
+
const dx = P.x - A.x
|
|
461
|
+
const dy = P.y - A.y
|
|
462
|
+
return Math.abs(dx * u.y - dy * u.x)
|
|
455
463
|
}
|
|
456
464
|
|
|
457
465
|
static DistanceToLineSegment(A: VecLike, B: VecLike, P: VecLike, clamp = true): number {
|
|
458
|
-
|
|
466
|
+
// Inlined: Vec.Dist(P, Vec.NearestPointOnLineSegment(A, B, P, clamp))
|
|
467
|
+
// Computes the nearest point via parametric t-projection then returns the scalar distance,
|
|
468
|
+
// avoiding the intermediate Vec allocation that NearestPointOnLineSegment would create.
|
|
469
|
+
const dx = B.x - A.x
|
|
470
|
+
const dy = B.y - A.y
|
|
471
|
+
const d2 = dx * dx + dy * dy
|
|
472
|
+
|
|
473
|
+
if (d2 === 0) return Vec.Dist(A, P)
|
|
474
|
+
|
|
475
|
+
let t = ((P.x - A.x) * dx + (P.y - A.y) * dy) / d2
|
|
476
|
+
|
|
477
|
+
if (clamp) {
|
|
478
|
+
if (t < 0) t = 0
|
|
479
|
+
else if (t > 1) t = 1
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
const nx = A.x + t * dx - P.x
|
|
483
|
+
const ny = A.y + t * dy - P.y
|
|
484
|
+
return Math.sqrt(nx * nx + ny * ny)
|
|
459
485
|
}
|
|
460
486
|
|
|
461
487
|
static Snap(A: VecLike, step = 1) {
|
|
@@ -476,6 +502,10 @@ export class Vec {
|
|
|
476
502
|
return isNaN(A.x) || isNaN(A.y)
|
|
477
503
|
}
|
|
478
504
|
|
|
505
|
+
static IsFinite(A: VecLike): boolean {
|
|
506
|
+
return Number.isFinite(A.x) && Number.isFinite(A.y)
|
|
507
|
+
}
|
|
508
|
+
|
|
479
509
|
/**
|
|
480
510
|
* Get the angle from position A to position B.
|
|
481
511
|
*/
|
|
@@ -488,14 +518,11 @@ export class Vec {
|
|
|
488
518
|
* two vectors, between -π and π. The sign indicates direction of angle.
|
|
489
519
|
*/
|
|
490
520
|
static AngleBetween(A: VecLike, B: VecLike): number {
|
|
521
|
+
// p = dot(A, B); n = |A| * |B| (uses x*x instead of Math.pow(x, 2))
|
|
491
522
|
const p = A.x * B.x + A.y * B.y
|
|
492
|
-
const n = Math.sqrt(
|
|
493
|
-
(Math.pow(A.x, 2) + Math.pow(A.y, 2)) * (Math.pow(B.x, 2) + Math.pow(B.y, 2))
|
|
494
|
-
)
|
|
523
|
+
const n = Math.sqrt((A.x * A.x + A.y * A.y) * (B.x * B.x + B.y * B.y))
|
|
495
524
|
const sign = A.x * B.y - A.y * B.x < 0 ? -1 : 1
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
return angle
|
|
525
|
+
return sign * Math.acos(clamp(p / n, -1, 1))
|
|
499
526
|
}
|
|
500
527
|
|
|
501
528
|
/**
|
|
@@ -506,7 +533,8 @@ export class Vec {
|
|
|
506
533
|
* @returns The interpolated point.
|
|
507
534
|
*/
|
|
508
535
|
static Lrp(A: VecLike, B: VecLike, t: number): Vec {
|
|
509
|
-
|
|
536
|
+
// Inlined: Vec.Sub(B, A).mul(t).add(A) — note: only interpolates x/y, not z.
|
|
537
|
+
return new Vec(A.x + (B.x - A.x) * t, A.y + (B.y - A.y) * t)
|
|
510
538
|
}
|
|
511
539
|
|
|
512
540
|
static Med(A: VecLike, B: VecLike): Vec {
|
|
@@ -604,14 +632,15 @@ export class Vec {
|
|
|
604
632
|
* @param A - The first point.
|
|
605
633
|
* @param B - The second point.
|
|
606
634
|
* @param steps - The number of points to return.
|
|
635
|
+
* @param ease - The easing to use.
|
|
607
636
|
*/
|
|
608
|
-
static PointsBetween(A: VecModel, B: VecModel, steps = 6): Vec[] {
|
|
637
|
+
static PointsBetween(A: VecModel, B: VecModel, steps = 6, ease = EASINGS.easeInQuad): Vec[] {
|
|
609
638
|
const results: Vec[] = []
|
|
610
639
|
|
|
611
640
|
for (let i = 0; i < steps; i++) {
|
|
612
|
-
const t =
|
|
641
|
+
const t = ease(i / (steps - 1))
|
|
613
642
|
const point = Vec.Lrp(A, B, t)
|
|
614
|
-
point.z = Math.min(1, 0.5 + Math.abs(0.5 -
|
|
643
|
+
point.z = Math.min(1, 0.5 + Math.abs(0.5 - EASINGS.easeInOutQuad(t)) * 0.65)
|
|
615
644
|
results.push(point)
|
|
616
645
|
}
|
|
617
646
|
|
|
@@ -622,5 +651,3 @@ export class Vec {
|
|
|
622
651
|
return new Vec(Math.round(A.x / gridSize) * gridSize, Math.round(A.y / gridSize) * gridSize)
|
|
623
652
|
}
|
|
624
653
|
}
|
|
625
|
-
|
|
626
|
-
const ease = (t: number) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t)
|
|
@@ -57,21 +57,16 @@ export class Arc2d extends Geometry2d {
|
|
|
57
57
|
if (t <= 0) return A
|
|
58
58
|
if (t >= 1) return B
|
|
59
59
|
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
dist = d
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (!nearest) throw Error('nearest point not found')
|
|
74
|
-
return nearest
|
|
60
|
+
// Inlined: Vec.Sub(point, _center).uni().mul(radius).add(_center)
|
|
61
|
+
// When t is in (0,1), the nearest point is the radial projection of point onto the arc.
|
|
62
|
+
// Previously this also checked min-distance against A and B, but that's unnecessary when
|
|
63
|
+
// t is already in range — the radial projection is always closer.
|
|
64
|
+
const dx = point.x - _center.x
|
|
65
|
+
const dy = point.y - _center.y
|
|
66
|
+
const len = Math.sqrt(dx * dx + dy * dy)
|
|
67
|
+
if (len === 0) return A
|
|
68
|
+
const scale = radius / len
|
|
69
|
+
return new Vec(_center.x + dx * scale, _center.y + dy * scale)
|
|
75
70
|
}
|
|
76
71
|
|
|
77
72
|
hitTestLineSegment(A: VecLike, B: VecLike): boolean {
|
|
@@ -44,9 +44,47 @@ export class Circle2d extends Geometry2d {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
nearestPoint(point: VecLike): Vec {
|
|
47
|
+
// Inlined: Vec.Sub(point, _center).uni().mul(radius).add(_center)
|
|
48
|
+
// Computes direction from center to point, normalizes, scales by radius, offsets by center.
|
|
47
49
|
const { _center, _radius: radius } = this
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
const dx = point.x - _center.x
|
|
51
|
+
const dy = point.y - _center.y
|
|
52
|
+
const len = Math.sqrt(dx * dx + dy * dy)
|
|
53
|
+
if (len === 0) return new Vec(_center.x + radius, _center.y)
|
|
54
|
+
const scale = radius / len
|
|
55
|
+
return new Vec(_center.x + dx * scale, _center.y + dy * scale)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override distanceToPoint(point: VecLike, hitInside = false): number {
|
|
59
|
+
// Inlined: Math.abs(Vec.Dist(point, _center) - radius)
|
|
60
|
+
// Computes distance from point to center, then subtracts radius for edge distance.
|
|
61
|
+
// Returns negative when inside a filled circle to indicate containment.
|
|
62
|
+
const { _center, _radius: radius } = this
|
|
63
|
+
const dx = point.x - _center.x
|
|
64
|
+
const dy = point.y - _center.y
|
|
65
|
+
const dist = Math.sqrt(dx * dx + dy * dy)
|
|
66
|
+
const distToEdge = dist - radius
|
|
67
|
+
if (distToEdge < 0 && (this.isFilled || hitInside)) {
|
|
68
|
+
return distToEdge
|
|
69
|
+
}
|
|
70
|
+
return Math.abs(distToEdge)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
override hitTestPoint(point: VecLike, margin = 0, hitInside = false): boolean {
|
|
74
|
+
// Equivalent to: dist = Vec.Dist(point, _center); return dist within [radius - margin, radius + margin]
|
|
75
|
+
// Uses squared distances throughout to avoid any sqrt calls.
|
|
76
|
+
const { _center, _radius: radius } = this
|
|
77
|
+
const dx = point.x - _center.x
|
|
78
|
+
const dy = point.y - _center.y
|
|
79
|
+
const dist2 = dx * dx + dy * dy
|
|
80
|
+
if ((this.isFilled || hitInside) && dist2 <= radius * radius) {
|
|
81
|
+
return true
|
|
82
|
+
}
|
|
83
|
+
const outerR = radius + margin
|
|
84
|
+
if (dist2 > outerR * outerR) return false
|
|
85
|
+
const innerR = radius - margin
|
|
86
|
+
if (innerR <= 0) return true
|
|
87
|
+
return dist2 >= innerR * innerR
|
|
50
88
|
}
|
|
51
89
|
|
|
52
90
|
hitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {
|
|
@@ -69,6 +69,16 @@ export class CubicBezier2d extends Polyline2d {
|
|
|
69
69
|
return nearest
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
override distanceToPoint(point: VecLike, _hitInside = false): number {
|
|
73
|
+
const { segments } = this
|
|
74
|
+
let minDist = Infinity
|
|
75
|
+
for (let i = 0; i < segments.length; i++) {
|
|
76
|
+
const d = segments[i].distanceToPoint(point)
|
|
77
|
+
if (d < minDist) minDist = d
|
|
78
|
+
}
|
|
79
|
+
return minDist
|
|
80
|
+
}
|
|
81
|
+
|
|
72
82
|
getSvgPathData(first = true) {
|
|
73
83
|
const { _a: a, _b: b, _c: c, _d: d } = this
|
|
74
84
|
return `${first ? `M ${a.toFixed()} ` : ``} C${b.toFixed()} ${c.toFixed()} ${d.toFixed()}`
|
|
@@ -15,7 +15,7 @@ export class CubicSpline2d extends Geometry2d {
|
|
|
15
15
|
|
|
16
16
|
private _segments?: CubicBezier2d[]
|
|
17
17
|
|
|
18
|
-
// eslint-disable-next-line no-
|
|
18
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
19
19
|
get segments() {
|
|
20
20
|
if (!this._segments) {
|
|
21
21
|
this._segments = []
|
|
@@ -75,6 +75,16 @@ export class CubicSpline2d extends Geometry2d {
|
|
|
75
75
|
return nearest
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
override distanceToPoint(point: VecLike, _hitInside = false): number {
|
|
79
|
+
const { segments } = this
|
|
80
|
+
let minDist = Infinity
|
|
81
|
+
for (let i = 0; i < segments.length; i++) {
|
|
82
|
+
const d = segments[i].distanceToPoint(point)
|
|
83
|
+
if (d < minDist) minDist = d
|
|
84
|
+
}
|
|
85
|
+
return minDist
|
|
86
|
+
}
|
|
87
|
+
|
|
78
88
|
hitTestLineSegment(A: VecLike, B: VecLike): boolean {
|
|
79
89
|
return this.segments.some((segment) => segment.hitTestLineSegment(A, B))
|
|
80
90
|
}
|
|
@@ -5,9 +5,9 @@ import { Geometry2d } from './Geometry2d'
|
|
|
5
5
|
export class Edge2d extends Geometry2d {
|
|
6
6
|
private _start: Vec
|
|
7
7
|
private _end: Vec
|
|
8
|
-
private
|
|
9
|
-
private
|
|
10
|
-
private
|
|
8
|
+
private _dx: number
|
|
9
|
+
private _dy: number
|
|
10
|
+
private _len2: number
|
|
11
11
|
|
|
12
12
|
constructor(config: { start: Vec; end: Vec }) {
|
|
13
13
|
super({ ...config, isClosed: false, isFilled: false })
|
|
@@ -16,13 +16,14 @@ export class Edge2d extends Geometry2d {
|
|
|
16
16
|
this._start = start
|
|
17
17
|
this._end = end
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
19
|
+
// Precomputed segment delta and squared length (replaces Vec.Sub(end, start) and Vec.Len2)
|
|
20
|
+
this._dx = end.x - start.x
|
|
21
|
+
this._dy = end.y - start.y
|
|
22
|
+
this._len2 = this._dx * this._dx + this._dy * this._dy
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
override getLength() {
|
|
25
|
-
return this.
|
|
26
|
+
return Math.sqrt(this._len2)
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
override getVertices(): Vec[] {
|
|
@@ -30,17 +31,39 @@ export class Edge2d extends Geometry2d {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
override nearestPoint(point: VecLike): Vec {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
// Inlined: Vec.NearestPointOnLineSegment(start, end, point)
|
|
35
|
+
// Uses precomputed dx/dy/len2 and parametric t-clamping instead of Vec allocations.
|
|
36
|
+
const { _start: start, _end: end, _dx: dx, _dy: dy, _len2: len2 } = this
|
|
37
|
+
if (len2 === 0) return start
|
|
38
|
+
|
|
39
|
+
const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / len2
|
|
40
|
+
if (t <= 0) return start
|
|
41
|
+
if (t >= 1) return end
|
|
42
|
+
return new Vec(start.x + dx * t, start.y + dy * t)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override distanceToPoint(point: VecLike, _hitInside = false): number {
|
|
46
|
+
// Inlined: Vec.Dist(point, this.nearestPoint(point))
|
|
47
|
+
// Finds nearest point via parametric t-projection then returns scalar distance directly,
|
|
48
|
+
// avoiding the Vec allocation that nearestPoint would create.
|
|
49
|
+
const { _start: start, _end: end, _dx: dx, _dy: dy, _len2: len2 } = this
|
|
50
|
+
if (len2 === 0) return Vec.Dist(point, start)
|
|
51
|
+
|
|
52
|
+
const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / len2
|
|
53
|
+
let nx: number, ny: number
|
|
54
|
+
if (t <= 0) {
|
|
55
|
+
nx = start.x
|
|
56
|
+
ny = start.y
|
|
57
|
+
} else if (t >= 1) {
|
|
58
|
+
nx = end.x
|
|
59
|
+
ny = end.y
|
|
60
|
+
} else {
|
|
61
|
+
nx = start.x + dx * t
|
|
62
|
+
ny = start.y + dy * t
|
|
63
|
+
}
|
|
64
|
+
const ex = point.x - nx
|
|
65
|
+
const ey = point.y - ny
|
|
66
|
+
return Math.sqrt(ex * ex + ey * ey)
|
|
44
67
|
}
|
|
45
68
|
|
|
46
69
|
getSvgPathData(first = true) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Box } from '../Box'
|
|
2
2
|
import { Vec, VecLike } from '../Vec'
|
|
3
|
-
import { PI, PI2, clamp, perimeterOfEllipse } from '../utils'
|
|
3
|
+
import { PI, PI2, clamp, perimeterOfEllipse, pointInPolygon } from '../utils'
|
|
4
4
|
import { Edge2d } from './Edge2d'
|
|
5
5
|
import { Geometry2d, Geometry2dOptions } from './Geometry2d'
|
|
6
6
|
import { getVerticesCountForArcLength } from './geometry-constants'
|
|
@@ -23,7 +23,7 @@ export class Ellipse2d extends Geometry2d {
|
|
|
23
23
|
this._h = height
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
// eslint-disable-next-line no-
|
|
26
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
27
27
|
get edges() {
|
|
28
28
|
if (!this._edges) {
|
|
29
29
|
const { vertices } = this
|
|
@@ -89,6 +89,19 @@ export class Ellipse2d extends Geometry2d {
|
|
|
89
89
|
return nearest
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
override distanceToPoint(point: VecLike, hitInside = false): number {
|
|
93
|
+
const { edges } = this
|
|
94
|
+
let minDist = Infinity
|
|
95
|
+
for (let i = 0; i < edges.length; i++) {
|
|
96
|
+
const d = edges[i].distanceToPoint(point)
|
|
97
|
+
if (d < minDist) minDist = d
|
|
98
|
+
}
|
|
99
|
+
if (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {
|
|
100
|
+
return -minDist
|
|
101
|
+
}
|
|
102
|
+
return minDist
|
|
103
|
+
}
|
|
104
|
+
|
|
92
105
|
hitTestLineSegment(A: VecLike, B: VecLike): boolean {
|
|
93
106
|
return this.edges.some((edge) => edge.hitTestLineSegment(A, B))
|
|
94
107
|
}
|
|
@@ -307,7 +307,7 @@ export abstract class Geometry2d {
|
|
|
307
307
|
|
|
308
308
|
private _vertices: Vec[] | undefined
|
|
309
309
|
|
|
310
|
-
// eslint-disable-next-line no-
|
|
310
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
311
311
|
get vertices(): Vec[] {
|
|
312
312
|
if (!this._vertices) {
|
|
313
313
|
this._vertices = this.getVertices(Geometry2dFilters.EXCLUDE_LABELS)
|
|
@@ -323,7 +323,7 @@ export abstract class Geometry2d {
|
|
|
323
323
|
|
|
324
324
|
private _boundsVertices: Vec[] | undefined
|
|
325
325
|
|
|
326
|
-
// eslint-disable-next-line no-
|
|
326
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
327
327
|
get boundsVertices(): Vec[] {
|
|
328
328
|
if (!this._boundsVertices) {
|
|
329
329
|
this._boundsVertices = this.getBoundsVertices()
|
|
@@ -337,7 +337,7 @@ export abstract class Geometry2d {
|
|
|
337
337
|
|
|
338
338
|
private _bounds: Box | undefined
|
|
339
339
|
|
|
340
|
-
// eslint-disable-next-line no-
|
|
340
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
341
341
|
get bounds(): Box {
|
|
342
342
|
if (!this._bounds) {
|
|
343
343
|
this._bounds = this.getBounds()
|
|
@@ -345,14 +345,14 @@ export abstract class Geometry2d {
|
|
|
345
345
|
return this._bounds
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
-
// eslint-disable-next-line no-
|
|
348
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
349
349
|
get center() {
|
|
350
350
|
return this.bounds.center
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
private _area: number | undefined
|
|
354
354
|
|
|
355
|
-
// eslint-disable-next-line no-
|
|
355
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
356
356
|
get area() {
|
|
357
357
|
if (!this._area) {
|
|
358
358
|
this._area = this.getArea()
|
|
@@ -397,7 +397,7 @@ export abstract class Geometry2d {
|
|
|
397
397
|
|
|
398
398
|
private _length?: number
|
|
399
399
|
|
|
400
|
-
// eslint-disable-next-line no-
|
|
400
|
+
// eslint-disable-next-line tldraw/no-setter-getter
|
|
401
401
|
get length() {
|
|
402
402
|
if (this._length) return this._length
|
|
403
403
|
this._length = this.getLength(Geometry2dFilters.EXCLUDE_LABELS)
|