@tldraw/editor 4.3.0-next.f4772c19540d → 4.4.0-canary.1e3b436e33e4
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/README.md +1 -1
- package/dist-cjs/index.d.ts +503 -155
- package/dist-cjs/index.js +8 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/components/ErrorBoundary.js.map +1 -1
- package/dist-cjs/lib/components/GeometryDebuggingView.js +1 -17
- package/dist-cjs/lib/components/GeometryDebuggingView.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +4 -5
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/constants.js +1 -3
- package/dist-cjs/lib/constants.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +346 -291
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +16 -23
- package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +3 -3
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js +12 -3
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +1 -1
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +5 -6
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +591 -0
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +1 -1
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/RBushIndex.js +144 -0
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/RBushIndex.js.map +7 -0
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +181 -0
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +1 -22
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/BaseBoxShapeUtil.js.map +1 -1
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +31 -23
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js +1 -1
- package/dist-cjs/lib/editor/shapes/group/DashedOutlineBox.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.js.map +2 -2
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +3 -3
- package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
- package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/exports/parseCss.js +1 -1
- package/dist-cjs/lib/exports/parseCss.js.map +2 -2
- package/dist-cjs/lib/globals/environment.js +45 -9
- package/dist-cjs/lib/globals/environment.js.map +2 -2
- package/dist-cjs/lib/globals/menus.js +1 -1
- package/dist-cjs/lib/globals/menus.js.map +2 -2
- package/dist-cjs/lib/hooks/useCoarsePointer.js +14 -29
- package/dist-cjs/lib/hooks/useCoarsePointer.js.map +2 -2
- package/dist-cjs/lib/hooks/useEvent.js +1 -1
- package/dist-cjs/lib/hooks/useEvent.js.map +2 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useGestureEvents.js +1 -1
- package/dist-cjs/lib/hooks/useGestureEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughMouseOverEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useScreenBounds.js.map +2 -2
- package/dist-cjs/lib/hooks/useStateAttribute.js +4 -1
- package/dist-cjs/lib/hooks/useStateAttribute.js.map +2 -2
- package/dist-cjs/lib/hooks/useTransform.js.map +1 -1
- package/dist-cjs/lib/hooks/useZoomCss.js +4 -8
- package/dist-cjs/lib/hooks/useZoomCss.js.map +2 -2
- package/dist-cjs/lib/options.js +6 -1
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +3 -0
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +1 -0
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js.map +2 -2
- package/dist-cjs/lib/utils/rotation.js +1 -1
- package/dist-cjs/lib/utils/rotation.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 +503 -155
- package/dist-esm/index.mjs +9 -2
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/components/ErrorBoundary.mjs.map +1 -1
- package/dist-esm/lib/components/GeometryDebuggingView.mjs +1 -17
- package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +4 -5
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/constants.mjs +1 -3
- package/dist-esm/lib/constants.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +347 -294
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +16 -23
- package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +3 -3
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +13 -4
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +5 -6
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +573 -0
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +1 -1
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SpatialIndexManager/RBushIndex.mjs +114 -0
- package/dist-esm/lib/editor/managers/SpatialIndexManager/RBushIndex.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +161 -0
- package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +1 -22
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/BaseBoxShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +31 -23
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs +1 -1
- package/dist-esm/lib/editor/shapes/group/DashedOutlineBox.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +3 -3
- package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/exports/parseCss.mjs +1 -1
- package/dist-esm/lib/exports/parseCss.mjs.map +2 -2
- package/dist-esm/lib/globals/environment.mjs +45 -9
- package/dist-esm/lib/globals/environment.mjs.map +2 -2
- package/dist-esm/lib/globals/menus.mjs +1 -1
- package/dist-esm/lib/globals/menus.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCoarsePointer.mjs +15 -30
- package/dist-esm/lib/hooks/useCoarsePointer.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEvent.mjs +1 -1
- package/dist-esm/lib/hooks/useEvent.mjs.map +2 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useGestureEvents.mjs +1 -1
- package/dist-esm/lib/hooks/useGestureEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughMouseOverEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useScreenBounds.mjs.map +2 -2
- package/dist-esm/lib/hooks/useStateAttribute.mjs +4 -1
- package/dist-esm/lib/hooks/useStateAttribute.mjs.map +2 -2
- package/dist-esm/lib/hooks/useTransform.mjs.map +1 -1
- package/dist-esm/lib/hooks/useZoomCss.mjs +4 -8
- package/dist-esm/lib/hooks/useZoomCss.mjs.map +2 -2
- package/dist-esm/lib/options.mjs +6 -1
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +3 -0
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +1 -0
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/lib/utils/rotation.mjs +1 -1
- package/dist-esm/lib/utils/rotation.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +14 -12
- package/package.json +21 -17
- package/src/index.ts +5 -1
- package/src/lib/components/ErrorBoundary.tsx +1 -1
- package/src/lib/components/GeometryDebuggingView.tsx +1 -19
- package/src/lib/components/default-components/DefaultCanvas.tsx +5 -8
- package/src/lib/config/TLUserPreferences.test.ts +40 -0
- package/src/lib/constants.ts +0 -2
- package/src/lib/editor/Editor.test.ts +150 -10
- package/src/lib/editor/Editor.ts +533 -384
- package/src/lib/editor/bindings/BindingUtil.ts +15 -9
- package/src/lib/editor/derivations/bindingsIndex.ts +2 -2
- package/src/lib/editor/derivations/notVisibleShapes.ts +21 -33
- package/src/lib/editor/derivations/parentsToChildren.ts +18 -7
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +17 -31
- package/src/lib/editor/managers/ClickManager/ClickManager.ts +1 -1
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +129 -79
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts +10 -6
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +14 -4
- package/src/lib/editor/managers/InputsManager/InputsManager.ts +566 -0
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +0 -4
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +12 -0
- package/src/lib/editor/managers/SnapManager/SnapManager.ts +4 -4
- package/src/lib/editor/managers/SpatialIndexManager/RBushIndex.ts +144 -0
- package/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts +215 -0
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +40 -107
- package/src/lib/editor/managers/TickManager/TickManager.ts +2 -32
- package/src/lib/editor/shapes/BaseBoxShapeUtil.tsx +2 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +72 -32
- package/src/lib/editor/shapes/group/DashedOutlineBox.tsx +1 -1
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -3
- package/src/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.ts +2 -1
- package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +6 -6
- package/src/lib/editor/types/emit-types.ts +3 -1
- package/src/lib/exports/getSvgJsx.test.ts +10 -19
- package/src/lib/exports/getSvgJsx.tsx +2 -5
- package/src/lib/exports/parseCss.test.ts +1 -0
- package/src/lib/exports/parseCss.ts +1 -1
- package/src/lib/globals/environment.ts +65 -10
- package/src/lib/globals/menus.ts +1 -1
- package/src/lib/hooks/useCoarsePointer.ts +16 -59
- package/src/lib/hooks/useEvent.tsx +1 -1
- package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +1 -1
- package/src/lib/hooks/useGestureEvents.ts +2 -2
- package/src/lib/hooks/usePassThroughMouseOverEvents.ts +1 -1
- package/src/lib/hooks/usePassThroughWheelEvents.ts +1 -1
- package/src/lib/hooks/useScreenBounds.ts +1 -1
- package/src/lib/hooks/useStateAttribute.ts +4 -1
- package/src/lib/hooks/useTransform.ts +1 -1
- package/src/lib/hooks/useZoomCss.ts +3 -8
- package/src/lib/options.ts +32 -0
- package/src/lib/primitives/Box.ts +9 -0
- package/src/lib/primitives/geometry/Geometry2d.ts +1 -0
- package/src/lib/utils/reparenting.ts +5 -5
- package/src/lib/utils/rotation.ts +1 -1
- package/src/version.ts +3 -3
|
@@ -18,8 +18,56 @@ describe('EdgeScrollManager', () => {
|
|
|
18
18
|
}
|
|
19
19
|
>
|
|
20
20
|
let edgeScrollManager: EdgeScrollManager
|
|
21
|
+
let mockInputs: {
|
|
22
|
+
_currentScreenPoint: Vec
|
|
23
|
+
currentScreenPoint: Vec
|
|
24
|
+
getCurrentScreenPoint(): Vec
|
|
25
|
+
setCurrentScreenPoint(value: Vec): void
|
|
26
|
+
_isDragging: boolean
|
|
27
|
+
isDragging: boolean
|
|
28
|
+
getIsDragging(): boolean
|
|
29
|
+
setIsDragging(value: boolean): void
|
|
30
|
+
_isPanning: boolean
|
|
31
|
+
isPanning: boolean
|
|
32
|
+
getIsPanning(): boolean
|
|
33
|
+
setIsPanning(value: boolean): void
|
|
34
|
+
}
|
|
21
35
|
|
|
22
36
|
beforeEach(() => {
|
|
37
|
+
// Create a mock inputs object with writable properties and getters
|
|
38
|
+
mockInputs = {
|
|
39
|
+
_currentScreenPoint: new Vec(500, 300),
|
|
40
|
+
get currentScreenPoint() {
|
|
41
|
+
return this._currentScreenPoint
|
|
42
|
+
},
|
|
43
|
+
getCurrentScreenPoint() {
|
|
44
|
+
return this._currentScreenPoint
|
|
45
|
+
},
|
|
46
|
+
setCurrentScreenPoint(value: Vec) {
|
|
47
|
+
this._currentScreenPoint = value
|
|
48
|
+
},
|
|
49
|
+
_isDragging: true,
|
|
50
|
+
get isDragging() {
|
|
51
|
+
return this._isDragging
|
|
52
|
+
},
|
|
53
|
+
getIsDragging() {
|
|
54
|
+
return this._isDragging
|
|
55
|
+
},
|
|
56
|
+
setIsDragging(value: boolean) {
|
|
57
|
+
this._isDragging = value
|
|
58
|
+
},
|
|
59
|
+
_isPanning: false,
|
|
60
|
+
get isPanning() {
|
|
61
|
+
return this._isPanning
|
|
62
|
+
},
|
|
63
|
+
getIsPanning() {
|
|
64
|
+
return this._isPanning
|
|
65
|
+
},
|
|
66
|
+
setIsPanning(value: boolean) {
|
|
67
|
+
this._isPanning = value
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
|
|
23
71
|
editor = {
|
|
24
72
|
options: {
|
|
25
73
|
edgeScrollDelay: 200,
|
|
@@ -28,22 +76,15 @@ describe('EdgeScrollManager', () => {
|
|
|
28
76
|
edgeScrollDistance: 8,
|
|
29
77
|
coarsePointerWidth: 12,
|
|
30
78
|
},
|
|
31
|
-
inputs:
|
|
32
|
-
currentScreenPoint: new Vec(500, 300),
|
|
33
|
-
isDragging: true,
|
|
34
|
-
isPanning: false,
|
|
35
|
-
},
|
|
79
|
+
inputs: mockInputs as unknown as Editor['inputs'],
|
|
36
80
|
user: {
|
|
37
81
|
getEdgeScrollSpeed: vi.fn(() => 1),
|
|
38
82
|
},
|
|
39
83
|
getViewportScreenBounds: vi.fn(() => new Box(0, 0, 1000, 600)),
|
|
40
|
-
getInstanceState: vi.fn(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
insets: [false, false, false, false], // [top, right, bottom, left]
|
|
45
|
-
}) as any
|
|
46
|
-
),
|
|
84
|
+
getInstanceState: vi.fn(() => ({
|
|
85
|
+
isCoarsePointer: false,
|
|
86
|
+
insets: [false, false, false, false], // [top, right, bottom, left]
|
|
87
|
+
})),
|
|
47
88
|
getCameraOptions: vi.fn(() => ({
|
|
48
89
|
isLocked: false,
|
|
49
90
|
panSpeed: 1,
|
|
@@ -54,9 +95,17 @@ describe('EdgeScrollManager', () => {
|
|
|
54
95
|
getZoomLevel: vi.fn(() => 1),
|
|
55
96
|
getCamera: vi.fn(() => new Vec(0, 0, 1)),
|
|
56
97
|
setCamera: vi.fn(),
|
|
57
|
-
} as
|
|
98
|
+
} as unknown as Mocked<
|
|
99
|
+
Editor & {
|
|
100
|
+
user: { getEdgeScrollSpeed: Mock }
|
|
101
|
+
getCamera: Mock
|
|
102
|
+
getCameraOptions: Mock
|
|
103
|
+
getZoomLevel: Mock
|
|
104
|
+
getViewportScreenBounds: Mock
|
|
105
|
+
}
|
|
106
|
+
>
|
|
58
107
|
|
|
59
|
-
edgeScrollManager = new EdgeScrollManager(editor
|
|
108
|
+
edgeScrollManager = new EdgeScrollManager(editor)
|
|
60
109
|
})
|
|
61
110
|
|
|
62
111
|
afterEach(() => {
|
|
@@ -67,49 +116,45 @@ describe('EdgeScrollManager', () => {
|
|
|
67
116
|
it('should initialize with editor reference', () => {
|
|
68
117
|
expect(edgeScrollManager.editor).toBe(editor)
|
|
69
118
|
})
|
|
70
|
-
|
|
71
|
-
it('should initialize edge scrolling state as false', () => {
|
|
72
|
-
// Access private properties for testing
|
|
73
|
-
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
74
|
-
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(-1)
|
|
75
|
-
})
|
|
76
119
|
})
|
|
77
120
|
|
|
78
121
|
describe('basic edge scrolling behavior', () => {
|
|
79
122
|
it('should not trigger edge scrolling when pointer is in center', () => {
|
|
80
|
-
|
|
123
|
+
mockInputs.setCurrentScreenPoint(new Vec(500, 300))
|
|
81
124
|
|
|
82
125
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
83
126
|
|
|
84
|
-
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
85
127
|
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
86
128
|
})
|
|
87
129
|
|
|
88
130
|
it('should start edge scrolling when pointer is near edge', () => {
|
|
89
|
-
|
|
131
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
90
132
|
|
|
133
|
+
// Should not scroll immediately due to delay
|
|
91
134
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
135
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
92
136
|
|
|
93
|
-
|
|
94
|
-
|
|
137
|
+
// Should scroll after delay
|
|
138
|
+
edgeScrollManager.updateEdgeScrolling(200)
|
|
139
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
95
140
|
})
|
|
96
141
|
|
|
97
142
|
it('should stop edge scrolling when pointer moves away from edge', () => {
|
|
98
|
-
// Start edge scrolling
|
|
99
|
-
|
|
100
|
-
edgeScrollManager.updateEdgeScrolling(
|
|
101
|
-
expect(
|
|
143
|
+
// Start edge scrolling near edge
|
|
144
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
145
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
146
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
102
147
|
|
|
103
|
-
// Move pointer to center
|
|
104
|
-
editor.
|
|
148
|
+
// Move pointer to center - should stop scrolling
|
|
149
|
+
editor.setCamera.mockClear()
|
|
150
|
+
mockInputs.setCurrentScreenPoint(new Vec(500, 300))
|
|
105
151
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
106
152
|
|
|
107
|
-
expect(
|
|
108
|
-
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(0)
|
|
153
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
109
154
|
})
|
|
110
155
|
|
|
111
156
|
it('should respect edge scroll delay', () => {
|
|
112
|
-
|
|
157
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
113
158
|
|
|
114
159
|
// First update - should not scroll yet due to delay
|
|
115
160
|
edgeScrollManager.updateEdgeScrolling(100)
|
|
@@ -123,7 +168,7 @@ describe('EdgeScrollManager', () => {
|
|
|
123
168
|
|
|
124
169
|
describe('edge proximity detection', () => {
|
|
125
170
|
it('should detect left edge proximity', () => {
|
|
126
|
-
|
|
171
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
127
172
|
edgeScrollManager.updateEdgeScrolling(300) // Enough to trigger after delay
|
|
128
173
|
|
|
129
174
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -132,7 +177,7 @@ describe('EdgeScrollManager', () => {
|
|
|
132
177
|
})
|
|
133
178
|
|
|
134
179
|
it('should detect right edge proximity', () => {
|
|
135
|
-
|
|
180
|
+
mockInputs.setCurrentScreenPoint(new Vec(995, 300))
|
|
136
181
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
137
182
|
|
|
138
183
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -141,7 +186,7 @@ describe('EdgeScrollManager', () => {
|
|
|
141
186
|
})
|
|
142
187
|
|
|
143
188
|
it('should detect top edge proximity', () => {
|
|
144
|
-
|
|
189
|
+
mockInputs.setCurrentScreenPoint(new Vec(500, 5))
|
|
145
190
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
146
191
|
|
|
147
192
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -150,7 +195,7 @@ describe('EdgeScrollManager', () => {
|
|
|
150
195
|
})
|
|
151
196
|
|
|
152
197
|
it('should detect bottom edge proximity', () => {
|
|
153
|
-
|
|
198
|
+
mockInputs.setCurrentScreenPoint(new Vec(500, 595))
|
|
154
199
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
155
200
|
|
|
156
201
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -159,7 +204,7 @@ describe('EdgeScrollManager', () => {
|
|
|
159
204
|
})
|
|
160
205
|
|
|
161
206
|
it('should handle corner proximity (both x and y)', () => {
|
|
162
|
-
|
|
207
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 5))
|
|
163
208
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
164
209
|
|
|
165
210
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -172,11 +217,11 @@ describe('EdgeScrollManager', () => {
|
|
|
172
217
|
describe('coarse pointer handling', () => {
|
|
173
218
|
it('should account for coarse pointer width', () => {
|
|
174
219
|
editor.getInstanceState.mockReturnValue({
|
|
220
|
+
...editor.getInstanceState(),
|
|
175
221
|
isCoarsePointer: true,
|
|
176
222
|
insets: [false, false, false, false],
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
editor.inputs.currentScreenPoint = new Vec(15, 300)
|
|
223
|
+
})
|
|
224
|
+
mockInputs.setCurrentScreenPoint(new Vec(15, 300))
|
|
180
225
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
181
226
|
|
|
182
227
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -184,11 +229,11 @@ describe('EdgeScrollManager', () => {
|
|
|
184
229
|
|
|
185
230
|
it('should not trigger edge scrolling for fine pointer at same position', () => {
|
|
186
231
|
editor.getInstanceState.mockReturnValue({
|
|
232
|
+
...editor.getInstanceState(),
|
|
187
233
|
isCoarsePointer: false,
|
|
188
234
|
insets: [false, false, false, false],
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
editor.inputs.currentScreenPoint = new Vec(15, 300)
|
|
235
|
+
})
|
|
236
|
+
mockInputs.setCurrentScreenPoint(new Vec(15, 300))
|
|
192
237
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
193
238
|
|
|
194
239
|
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
@@ -197,8 +242,8 @@ describe('EdgeScrollManager', () => {
|
|
|
197
242
|
|
|
198
243
|
describe('camera movement conditions', () => {
|
|
199
244
|
it('should not move camera when not dragging', () => {
|
|
200
|
-
editor.inputs.
|
|
201
|
-
|
|
245
|
+
editor.inputs.setIsDragging(false)
|
|
246
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
202
247
|
|
|
203
248
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
204
249
|
|
|
@@ -206,8 +251,8 @@ describe('EdgeScrollManager', () => {
|
|
|
206
251
|
})
|
|
207
252
|
|
|
208
253
|
it('should not move camera when panning', () => {
|
|
209
|
-
editor.inputs.
|
|
210
|
-
|
|
254
|
+
editor.inputs.setIsPanning(true)
|
|
255
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
211
256
|
|
|
212
257
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
213
258
|
|
|
@@ -222,7 +267,7 @@ describe('EdgeScrollManager', () => {
|
|
|
222
267
|
zoomSteps: [1],
|
|
223
268
|
wheelBehavior: 'pan' as const,
|
|
224
269
|
})
|
|
225
|
-
|
|
270
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
226
271
|
|
|
227
272
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
228
273
|
|
|
@@ -233,7 +278,7 @@ describe('EdgeScrollManager', () => {
|
|
|
233
278
|
describe('camera movement calculation', () => {
|
|
234
279
|
it('should calculate scroll speed based on user preference', () => {
|
|
235
280
|
editor.user.getEdgeScrollSpeed.mockReturnValue(2)
|
|
236
|
-
|
|
281
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
237
282
|
|
|
238
283
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
239
284
|
|
|
@@ -244,7 +289,7 @@ describe('EdgeScrollManager', () => {
|
|
|
244
289
|
|
|
245
290
|
it('should apply screen size factor for small screens', () => {
|
|
246
291
|
editor.getViewportScreenBounds.mockReturnValue(new Box(0, 0, 800, 600))
|
|
247
|
-
|
|
292
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
248
293
|
|
|
249
294
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
250
295
|
|
|
@@ -253,7 +298,7 @@ describe('EdgeScrollManager', () => {
|
|
|
253
298
|
|
|
254
299
|
it('should adjust scroll speed based on zoom level', () => {
|
|
255
300
|
editor.getZoomLevel.mockReturnValue(2)
|
|
256
|
-
|
|
301
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
257
302
|
|
|
258
303
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
259
304
|
|
|
@@ -266,7 +311,7 @@ describe('EdgeScrollManager', () => {
|
|
|
266
311
|
it('should add scroll delta to current camera position', () => {
|
|
267
312
|
const currentCamera = new Vec(100, 200, 1)
|
|
268
313
|
editor.getCamera.mockReturnValue(currentCamera)
|
|
269
|
-
|
|
314
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 5))
|
|
270
315
|
|
|
271
316
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
272
317
|
|
|
@@ -280,14 +325,14 @@ describe('EdgeScrollManager', () => {
|
|
|
280
325
|
|
|
281
326
|
describe('proximity factor calculation', () => {
|
|
282
327
|
it('should return 0 when not near any edge', () => {
|
|
283
|
-
|
|
328
|
+
mockInputs.setCurrentScreenPoint(new Vec(500, 300))
|
|
284
329
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
285
330
|
|
|
286
331
|
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
287
332
|
})
|
|
288
333
|
|
|
289
334
|
it('should cap proximity factor at 1', () => {
|
|
290
|
-
|
|
335
|
+
mockInputs.setCurrentScreenPoint(new Vec(0, 300))
|
|
291
336
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
292
337
|
|
|
293
338
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
@@ -297,20 +342,20 @@ describe('EdgeScrollManager', () => {
|
|
|
297
342
|
|
|
298
343
|
describe('edge cases and error handling', () => {
|
|
299
344
|
it('should handle negative elapsed time', () => {
|
|
300
|
-
|
|
345
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
301
346
|
|
|
302
347
|
expect(() => edgeScrollManager.updateEdgeScrolling(-16)).not.toThrow()
|
|
303
348
|
})
|
|
304
349
|
|
|
305
350
|
it('should handle very large elapsed time', () => {
|
|
306
|
-
|
|
351
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
307
352
|
|
|
308
353
|
expect(() => edgeScrollManager.updateEdgeScrolling(100000)).not.toThrow()
|
|
309
354
|
})
|
|
310
355
|
|
|
311
356
|
it('should handle zero user edge scroll speed', () => {
|
|
312
357
|
editor.user.getEdgeScrollSpeed.mockReturnValue(0)
|
|
313
|
-
|
|
358
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
314
359
|
|
|
315
360
|
edgeScrollManager.updateEdgeScrolling(300)
|
|
316
361
|
|
|
@@ -322,7 +367,7 @@ describe('EdgeScrollManager', () => {
|
|
|
322
367
|
})
|
|
323
368
|
|
|
324
369
|
it('should handle extreme zoom levels', () => {
|
|
325
|
-
|
|
370
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
326
371
|
|
|
327
372
|
editor.getZoomLevel.mockReturnValue(0.01) // Very zoomed out
|
|
328
373
|
expect(() => edgeScrollManager.updateEdgeScrolling(300)).not.toThrow()
|
|
@@ -335,41 +380,46 @@ describe('EdgeScrollManager', () => {
|
|
|
335
380
|
describe('state transitions', () => {
|
|
336
381
|
it('should properly transition from not scrolling to scrolling', () => {
|
|
337
382
|
// Start with no edge scrolling
|
|
338
|
-
|
|
383
|
+
mockInputs.setCurrentScreenPoint(new Vec(500, 300))
|
|
339
384
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
340
|
-
expect(
|
|
385
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
341
386
|
|
|
342
|
-
// Move to edge
|
|
343
|
-
|
|
387
|
+
// Move to edge - should start scrolling after delay
|
|
388
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
344
389
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
345
|
-
expect(
|
|
346
|
-
|
|
390
|
+
expect(editor.setCamera).not.toHaveBeenCalled() // Not yet, due to delay
|
|
391
|
+
|
|
392
|
+
edgeScrollManager.updateEdgeScrolling(200)
|
|
393
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
347
394
|
})
|
|
348
395
|
|
|
349
396
|
it('should accumulate edge scroll duration over multiple updates', () => {
|
|
350
|
-
|
|
397
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
351
398
|
|
|
399
|
+
// First update - not enough time
|
|
352
400
|
edgeScrollManager.updateEdgeScrolling(50)
|
|
353
|
-
expect(
|
|
401
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
354
402
|
|
|
355
|
-
|
|
356
|
-
|
|
403
|
+
// Second update - still not enough
|
|
404
|
+
edgeScrollManager.updateEdgeScrolling(50)
|
|
405
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
357
406
|
|
|
358
|
-
|
|
359
|
-
|
|
407
|
+
// Third update - now should trigger (50 + 50 + 101 = 201ms > 200ms delay)
|
|
408
|
+
edgeScrollManager.updateEdgeScrolling(101)
|
|
409
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
360
410
|
})
|
|
361
411
|
|
|
362
412
|
it('should reset duration when stopping edge scroll', () => {
|
|
363
413
|
// Start edge scrolling
|
|
364
|
-
|
|
365
|
-
edgeScrollManager.updateEdgeScrolling(
|
|
366
|
-
expect(
|
|
414
|
+
mockInputs.setCurrentScreenPoint(new Vec(5, 300))
|
|
415
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
416
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
367
417
|
|
|
368
|
-
// Stop edge scrolling
|
|
369
|
-
editor.
|
|
418
|
+
// Stop edge scrolling - move away
|
|
419
|
+
editor.setCamera.mockClear()
|
|
420
|
+
mockInputs.setCurrentScreenPoint(new Vec(500, 300))
|
|
370
421
|
edgeScrollManager.updateEdgeScrolling(16)
|
|
371
|
-
expect(
|
|
372
|
-
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(0)
|
|
422
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
373
423
|
})
|
|
374
424
|
})
|
|
375
425
|
})
|
|
@@ -9,6 +9,10 @@ export class EdgeScrollManager {
|
|
|
9
9
|
private _isEdgeScrolling = false
|
|
10
10
|
private _edgeScrollDuration = -1
|
|
11
11
|
|
|
12
|
+
getIsEdgeScrolling() {
|
|
13
|
+
return this._isEdgeScrolling
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
/**
|
|
13
17
|
* Update the camera position when the mouse is close to the edge of the screen.
|
|
14
18
|
* Run this on every tick when in a state where edge scrolling is enabled.
|
|
@@ -81,11 +85,7 @@ export class EdgeScrollManager {
|
|
|
81
85
|
|
|
82
86
|
private getEdgeScroll() {
|
|
83
87
|
const { editor } = this
|
|
84
|
-
const {
|
|
85
|
-
inputs: {
|
|
86
|
-
currentScreenPoint: { x, y },
|
|
87
|
-
},
|
|
88
|
-
} = editor
|
|
88
|
+
const { x, y } = editor.inputs.getCurrentScreenPoint()
|
|
89
89
|
const screenBounds = editor.getViewportScreenBounds()
|
|
90
90
|
|
|
91
91
|
const {
|
|
@@ -107,7 +107,11 @@ export class EdgeScrollManager {
|
|
|
107
107
|
*/
|
|
108
108
|
private moveCameraWhenCloseToEdge(proximityFactor: { x: number; y: number }) {
|
|
109
109
|
const { editor } = this
|
|
110
|
-
if (
|
|
110
|
+
if (
|
|
111
|
+
!editor.inputs.getIsDragging() ||
|
|
112
|
+
editor.inputs.getIsPanning() ||
|
|
113
|
+
editor.getCameraOptions().isLocked
|
|
114
|
+
)
|
|
111
115
|
return
|
|
112
116
|
|
|
113
117
|
if (proximityFactor.x === 0 && proximityFactor.y === 0) return
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { TLShape, TLShapeId, createShapeId } from '@tldraw/tlschema'
|
|
1
|
+
import { TLParentId, TLShape, TLShapeId, createShapeId, toRichText } from '@tldraw/tlschema'
|
|
2
|
+
import { IndexKey } from '@tldraw/utils'
|
|
2
3
|
import { Mock, Mocked, vi } from 'vitest'
|
|
3
4
|
import { Editor } from '../../Editor'
|
|
4
5
|
import { FontManager, TLFontFace } from './FontManager'
|
|
@@ -41,12 +42,21 @@ describe('FontManager', () => {
|
|
|
41
42
|
x: 0,
|
|
42
43
|
y: 0,
|
|
43
44
|
rotation: 0,
|
|
44
|
-
index: 'a1' as
|
|
45
|
-
parentId: 'page:page' as
|
|
45
|
+
index: 'a1' as IndexKey,
|
|
46
|
+
parentId: 'page:page' as TLParentId,
|
|
46
47
|
opacity: 1,
|
|
47
48
|
isLocked: false,
|
|
48
49
|
meta: {},
|
|
49
|
-
props: {
|
|
50
|
+
props: {
|
|
51
|
+
color: 'black',
|
|
52
|
+
size: 'xl',
|
|
53
|
+
font: 'serif',
|
|
54
|
+
textAlign: 'middle',
|
|
55
|
+
w: 100,
|
|
56
|
+
richText: toRichText('❤️'),
|
|
57
|
+
scale: 2,
|
|
58
|
+
autoSize: true,
|
|
59
|
+
},
|
|
50
60
|
typeName: 'shape' as const,
|
|
51
61
|
})
|
|
52
62
|
|