@tldraw/editor 3.14.0-canary.dbe17bbcfb3d → 3.14.0-canary.dd6c729c17b0
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 +114 -104
- package/dist-cjs/index.js +8 -8
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/config/TLSessionStateSnapshot.js +1 -12
- package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +3 -3
- package/dist-cjs/lib/editor/Editor.js +75 -76
- 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 +22 -22
- package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js +16 -16
- package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
- package/dist-cjs/lib/editor/managers/{ClickManager.js → ClickManager/ClickManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{EdgeScrollManager.js → EdgeScrollManager/EdgeScrollManager.js} +2 -2
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{FontManager.js → FontManager/FontManager.js} +4 -1
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{HistoryManager.js → HistoryManager/HistoryManager.js} +64 -6
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{ScribbleManager.js → ScribbleManager/ScribbleManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{TextManager.js → TextManager/TextManager.js} +72 -42
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{TickManager.js → TickManager/TickManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/{UserPreferencesManager.js → UserPreferencesManager/UserPreferencesManager.js} +1 -1
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +7 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +1 -1
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +1 -1
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +1 -1
- package/dist-cjs/lib/editor/tools/StateNode.js +3 -3
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js.map +1 -1
- package/dist-cjs/lib/hooks/useCanvasEvents.js +1 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/primitives/Box.js +33 -33
- package/dist-cjs/lib/primitives/Box.js.map +2 -2
- package/dist-cjs/lib/primitives/Vec.js +13 -8
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js +41 -21
- package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Circle2d.js +11 -11
- package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +13 -16
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js +4 -4
- package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Edge2d.js +14 -17
- package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +10 -10
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Point2d.js +6 -6
- package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Polygon2d.js +3 -0
- package/dist-cjs/lib/primitives/geometry/Polygon2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Polyline2d.js +8 -5
- package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Rectangle2d.js +22 -11
- package/dist-cjs/lib/primitives/geometry/Rectangle2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js +22 -22
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
- package/dist-cjs/lib/utils/reorderShapes.js +11 -10
- package/dist-cjs/lib/utils/reorderShapes.js.map +2 -2
- package/dist-cjs/lib/utils/richText.js +7 -2
- package/dist-cjs/lib/utils/richText.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 +114 -104
- package/dist-esm/index.mjs +12 -8
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/config/TLSessionStateSnapshot.mjs +1 -1
- package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +75 -76
- 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 +22 -22
- package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +16 -16
- package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/{ClickManager.mjs → ClickManager/ClickManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{EdgeScrollManager.mjs → EdgeScrollManager/EdgeScrollManager.mjs} +2 -2
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{FontManager.mjs → FontManager/FontManager.mjs} +4 -1
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{HistoryManager.mjs → HistoryManager/HistoryManager.mjs} +60 -2
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{ScribbleManager.mjs → ScribbleManager/ScribbleManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{TextManager.mjs → TextManager/TextManager.mjs} +72 -42
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{TickManager.mjs → TickManager/TickManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/{UserPreferencesManager.mjs → UserPreferencesManager/UserPreferencesManager.mjs} +1 -1
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +7 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +1 -1
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/tools/StateNode.mjs +3 -3
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +1 -1
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +1 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/primitives/Box.mjs +33 -33
- package/dist-esm/lib/primitives/Box.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +13 -8
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs +41 -21
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs +11 -11
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +13 -16
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs +4 -4
- package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs +14 -17
- package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +11 -11
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Point2d.mjs +6 -6
- package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Polygon2d.mjs +3 -0
- package/dist-esm/lib/primitives/geometry/Polygon2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Polyline2d.mjs +8 -5
- package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Rectangle2d.mjs +22 -11
- package/dist-esm/lib/primitives/geometry/Rectangle2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +22 -22
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
- package/dist-esm/lib/utils/reorderShapes.mjs +11 -10
- package/dist-esm/lib/utils/reorderShapes.mjs.map +2 -2
- package/dist-esm/lib/utils/richText.mjs +8 -3
- package/dist-esm/lib/utils/richText.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +433 -482
- package/package.json +8 -9
- package/src/index.ts +15 -7
- package/src/lib/config/TLSessionStateSnapshot.ts +1 -1
- package/src/lib/editor/Editor.test.ts +252 -3
- package/src/lib/editor/Editor.ts +76 -74
- package/src/lib/editor/bindings/BindingUtil.ts +6 -0
- package/src/lib/editor/derivations/bindingsIndex.ts +27 -26
- package/src/lib/editor/derivations/parentsToChildren.ts +28 -25
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +442 -0
- package/src/lib/editor/managers/{ClickManager.ts → ClickManager/ClickManager.ts} +3 -3
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +374 -0
- package/src/lib/editor/managers/{EdgeScrollManager.ts → EdgeScrollManager/EdgeScrollManager.ts} +3 -3
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +455 -0
- package/src/lib/editor/managers/{FocusManager.ts → FocusManager/FocusManager.ts} +1 -1
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +263 -0
- package/src/lib/editor/managers/{FontManager.ts → FontManager/FontManager.ts} +5 -2
- package/src/lib/editor/managers/{HistoryManager.test.ts → HistoryManager/HistoryManager.test.ts} +388 -1
- package/src/lib/editor/managers/{HistoryManager.ts → HistoryManager/HistoryManager.ts} +73 -2
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +624 -0
- package/src/lib/editor/managers/{ScribbleManager.ts → ScribbleManager/ScribbleManager.ts} +2 -2
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +485 -0
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +407 -0
- package/src/lib/editor/managers/{TextManager.ts → TextManager/TextManager.ts} +117 -87
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +314 -0
- package/src/lib/editor/managers/{TickManager.ts → TickManager/TickManager.ts} +2 -2
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +591 -0
- package/src/lib/editor/managers/{UserPreferencesManager.ts → UserPreferencesManager/UserPreferencesManager.ts} +2 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +1 -1
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
- package/src/lib/editor/tools/StateNode.ts +3 -3
- package/src/lib/editor/types/external-content.ts +11 -2
- package/src/lib/exports/getSvgJsx.tsx +1 -1
- package/src/lib/hooks/useCanvasEvents.ts +0 -1
- package/src/lib/primitives/Box.test.ts +588 -7
- package/src/lib/primitives/Box.ts +33 -33
- package/src/lib/primitives/Vec.test.ts +2 -2
- package/src/lib/primitives/Vec.ts +13 -8
- package/src/lib/primitives/geometry/Arc2d.ts +42 -23
- package/src/lib/primitives/geometry/Circle2d.ts +12 -12
- package/src/lib/primitives/geometry/CubicBezier2d.test.ts +5 -0
- package/src/lib/primitives/geometry/CubicBezier2d.ts +13 -17
- package/src/lib/primitives/geometry/CubicSpline2d.ts +5 -5
- package/src/lib/primitives/geometry/Edge2d.ts +14 -18
- package/src/lib/primitives/geometry/Ellipse2d.ts +12 -13
- package/src/lib/primitives/geometry/Point2d.ts +6 -6
- package/src/lib/primitives/geometry/Polygon2d.ts +4 -0
- package/src/lib/primitives/geometry/Polyline2d.ts +10 -7
- package/src/lib/primitives/geometry/Rectangle2d.ts +24 -11
- package/src/lib/primitives/geometry/Stadium2d.ts +22 -23
- package/src/lib/utils/reorderShapes.ts +10 -13
- package/src/lib/utils/richText.ts +10 -4
- package/src/version.ts +3 -3
- package/dist-cjs/lib/editor/managers/ClickManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/EdgeScrollManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/FocusManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/FontManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/HistoryManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/ScribbleManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/Stack.js +0 -82
- package/dist-cjs/lib/editor/managers/Stack.js.map +0 -7
- package/dist-cjs/lib/editor/managers/TextManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/TickManager.js.map +0 -7
- package/dist-cjs/lib/editor/managers/UserPreferencesManager.js.map +0 -7
- package/dist-esm/lib/editor/managers/ClickManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/EdgeScrollManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/FocusManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/FontManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/HistoryManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/ScribbleManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/Stack.mjs +0 -62
- package/dist-esm/lib/editor/managers/Stack.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/TextManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/TickManager.mjs.map +0 -7
- package/dist-esm/lib/editor/managers/UserPreferencesManager.mjs.map +0 -7
- package/src/lib/editor/managers/ScribbleManager.test.ts +0 -32
- package/src/lib/editor/managers/Stack.ts +0 -71
- /package/dist-cjs/lib/editor/managers/{FocusManager.js → FocusManager/FocusManager.js} +0 -0
- /package/dist-esm/lib/editor/managers/{FocusManager.mjs → FocusManager/FocusManager.mjs} +0 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { Box } from '../../../primitives/Box'
|
|
2
|
+
import { Vec } from '../../../primitives/Vec'
|
|
3
|
+
import { Editor } from '../../Editor'
|
|
4
|
+
import { EdgeScrollManager } from './EdgeScrollManager'
|
|
5
|
+
|
|
6
|
+
// Mock the Editor class
|
|
7
|
+
jest.mock('../../Editor')
|
|
8
|
+
|
|
9
|
+
describe('EdgeScrollManager', () => {
|
|
10
|
+
let editor: jest.Mocked<
|
|
11
|
+
Editor & {
|
|
12
|
+
user: { getEdgeScrollSpeed: jest.Mock }
|
|
13
|
+
getCamera: jest.Mock
|
|
14
|
+
getCameraOptions: jest.Mock
|
|
15
|
+
getZoomLevel: jest.Mock
|
|
16
|
+
getViewportScreenBounds: jest.Mock
|
|
17
|
+
}
|
|
18
|
+
>
|
|
19
|
+
let edgeScrollManager: EdgeScrollManager
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
editor = {
|
|
23
|
+
options: {
|
|
24
|
+
edgeScrollDelay: 200,
|
|
25
|
+
edgeScrollEaseDuration: 200,
|
|
26
|
+
edgeScrollSpeed: 25,
|
|
27
|
+
edgeScrollDistance: 8,
|
|
28
|
+
coarsePointerWidth: 12,
|
|
29
|
+
},
|
|
30
|
+
inputs: {
|
|
31
|
+
currentScreenPoint: new Vec(500, 300),
|
|
32
|
+
isDragging: true,
|
|
33
|
+
isPanning: false,
|
|
34
|
+
},
|
|
35
|
+
user: {
|
|
36
|
+
getEdgeScrollSpeed: jest.fn(() => 1),
|
|
37
|
+
},
|
|
38
|
+
getViewportScreenBounds: jest.fn(() => new Box(0, 0, 1000, 600)),
|
|
39
|
+
getInstanceState: jest.fn(
|
|
40
|
+
() =>
|
|
41
|
+
({
|
|
42
|
+
isCoarsePointer: false,
|
|
43
|
+
insets: [false, false, false, false], // [top, right, bottom, left]
|
|
44
|
+
}) as any
|
|
45
|
+
),
|
|
46
|
+
getCameraOptions: jest.fn(() => ({
|
|
47
|
+
isLocked: false,
|
|
48
|
+
panSpeed: 1,
|
|
49
|
+
zoomSpeed: 1,
|
|
50
|
+
zoomSteps: [1],
|
|
51
|
+
wheelBehavior: 'pan' as const,
|
|
52
|
+
})),
|
|
53
|
+
getZoomLevel: jest.fn(() => 1),
|
|
54
|
+
getCamera: jest.fn(() => new Vec(0, 0, 1)),
|
|
55
|
+
setCamera: jest.fn(),
|
|
56
|
+
} as any
|
|
57
|
+
|
|
58
|
+
edgeScrollManager = new EdgeScrollManager(editor as any)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
afterEach(() => {
|
|
62
|
+
jest.clearAllMocks()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
describe('constructor and initialization', () => {
|
|
66
|
+
it('should initialize with editor reference', () => {
|
|
67
|
+
expect(edgeScrollManager.editor).toBe(editor)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('should initialize edge scrolling state as false', () => {
|
|
71
|
+
// Access private properties for testing
|
|
72
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
73
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(-1)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
describe('basic edge scrolling behavior', () => {
|
|
78
|
+
it('should not trigger edge scrolling when pointer is in center', () => {
|
|
79
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
80
|
+
|
|
81
|
+
edgeScrollManager.updateEdgeScrolling(16)
|
|
82
|
+
|
|
83
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
84
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('should start edge scrolling when pointer is near edge', () => {
|
|
88
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
89
|
+
|
|
90
|
+
edgeScrollManager.updateEdgeScrolling(16)
|
|
91
|
+
|
|
92
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(true)
|
|
93
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(16)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('should stop edge scrolling when pointer moves away from edge', () => {
|
|
97
|
+
// Start edge scrolling
|
|
98
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
99
|
+
edgeScrollManager.updateEdgeScrolling(16)
|
|
100
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(true)
|
|
101
|
+
|
|
102
|
+
// Move pointer to center
|
|
103
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
104
|
+
edgeScrollManager.updateEdgeScrolling(16)
|
|
105
|
+
|
|
106
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
107
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(0)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('should respect edge scroll delay', () => {
|
|
111
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
112
|
+
|
|
113
|
+
// First update - should not scroll yet due to delay
|
|
114
|
+
edgeScrollManager.updateEdgeScrolling(100)
|
|
115
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
116
|
+
|
|
117
|
+
// Second update - should trigger scrolling after delay
|
|
118
|
+
edgeScrollManager.updateEdgeScrolling(150)
|
|
119
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
describe('edge proximity detection', () => {
|
|
124
|
+
it('should detect left edge proximity', () => {
|
|
125
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
126
|
+
edgeScrollManager.updateEdgeScrolling(300) // Enough to trigger after delay
|
|
127
|
+
|
|
128
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
129
|
+
const callArgs = editor.setCamera.mock.calls[0][0] as Vec
|
|
130
|
+
expect(callArgs.x).toBeGreaterThan(0) // Should scroll right when near left edge
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('should detect right edge proximity', () => {
|
|
134
|
+
editor.inputs.currentScreenPoint = new Vec(995, 300)
|
|
135
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
136
|
+
|
|
137
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
138
|
+
const callArgs = editor.setCamera.mock.calls[0][0] as Vec
|
|
139
|
+
expect(callArgs.x).toBeLessThan(0) // Should scroll left when near right edge
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
it('should detect top edge proximity', () => {
|
|
143
|
+
editor.inputs.currentScreenPoint = new Vec(500, 5)
|
|
144
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
145
|
+
|
|
146
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
147
|
+
const callArgs = editor.setCamera.mock.calls[0][0] as Vec
|
|
148
|
+
expect(callArgs.y).toBeGreaterThan(0) // Should scroll down when near top edge
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('should detect bottom edge proximity', () => {
|
|
152
|
+
editor.inputs.currentScreenPoint = new Vec(500, 595)
|
|
153
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
154
|
+
|
|
155
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
156
|
+
const callArgs = editor.setCamera.mock.calls[0][0] as Vec
|
|
157
|
+
expect(callArgs.y).toBeLessThan(0) // Should scroll up when near bottom edge
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('should handle corner proximity (both x and y)', () => {
|
|
161
|
+
editor.inputs.currentScreenPoint = new Vec(5, 5)
|
|
162
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
163
|
+
|
|
164
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
165
|
+
const callArgs = editor.setCamera.mock.calls[0][0] as Vec
|
|
166
|
+
expect(callArgs.x).toBeGreaterThan(0) // Should scroll right
|
|
167
|
+
expect(callArgs.y).toBeGreaterThan(0) // Should scroll down
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
describe('coarse pointer handling', () => {
|
|
172
|
+
it('should account for coarse pointer width', () => {
|
|
173
|
+
editor.getInstanceState.mockReturnValue({
|
|
174
|
+
isCoarsePointer: true,
|
|
175
|
+
insets: [false, false, false, false],
|
|
176
|
+
} as any)
|
|
177
|
+
|
|
178
|
+
editor.inputs.currentScreenPoint = new Vec(15, 300)
|
|
179
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
180
|
+
|
|
181
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it('should not trigger edge scrolling for fine pointer at same position', () => {
|
|
185
|
+
editor.getInstanceState.mockReturnValue({
|
|
186
|
+
isCoarsePointer: false,
|
|
187
|
+
insets: [false, false, false, false],
|
|
188
|
+
} as any)
|
|
189
|
+
|
|
190
|
+
editor.inputs.currentScreenPoint = new Vec(15, 300)
|
|
191
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
192
|
+
|
|
193
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
194
|
+
})
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
describe('camera movement conditions', () => {
|
|
198
|
+
it('should not move camera when not dragging', () => {
|
|
199
|
+
editor.inputs.isDragging = false
|
|
200
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
201
|
+
|
|
202
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
203
|
+
|
|
204
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it('should not move camera when panning', () => {
|
|
208
|
+
editor.inputs.isPanning = true
|
|
209
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
210
|
+
|
|
211
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
212
|
+
|
|
213
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
it('should not move camera when camera is locked', () => {
|
|
217
|
+
editor.getCameraOptions.mockReturnValue({
|
|
218
|
+
isLocked: true,
|
|
219
|
+
panSpeed: 1,
|
|
220
|
+
zoomSpeed: 1,
|
|
221
|
+
zoomSteps: [1],
|
|
222
|
+
wheelBehavior: 'pan' as const,
|
|
223
|
+
})
|
|
224
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
225
|
+
|
|
226
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
227
|
+
|
|
228
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
describe('camera movement calculation', () => {
|
|
233
|
+
it('should calculate scroll speed based on user preference', () => {
|
|
234
|
+
editor.user.getEdgeScrollSpeed.mockReturnValue(2)
|
|
235
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
236
|
+
|
|
237
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
238
|
+
|
|
239
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
240
|
+
const callArgs = editor.setCamera.mock.calls[0][0] as Vec
|
|
241
|
+
expect(callArgs.x).toBeGreaterThan(0) // Should scroll when user speed is > 0
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('should apply screen size factor for small screens', () => {
|
|
245
|
+
editor.getViewportScreenBounds.mockReturnValue(new Box(0, 0, 800, 600))
|
|
246
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
247
|
+
|
|
248
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
249
|
+
|
|
250
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
it('should adjust scroll speed based on zoom level', () => {
|
|
254
|
+
editor.getZoomLevel.mockReturnValue(2)
|
|
255
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
256
|
+
|
|
257
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
258
|
+
|
|
259
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
260
|
+
const callArgs = editor.setCamera.mock.calls[0][0] as Vec
|
|
261
|
+
// Higher zoom should result in smaller camera movement
|
|
262
|
+
expect(Math.abs(callArgs.x)).toBeLessThan(25)
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
it('should add scroll delta to current camera position', () => {
|
|
266
|
+
const currentCamera = new Vec(100, 200, 1)
|
|
267
|
+
editor.getCamera.mockReturnValue(currentCamera)
|
|
268
|
+
editor.inputs.currentScreenPoint = new Vec(5, 5)
|
|
269
|
+
|
|
270
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
271
|
+
|
|
272
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
273
|
+
const callArgs = editor.setCamera.mock.calls[0][0] as Vec
|
|
274
|
+
expect(callArgs.x).toBeGreaterThan(100) // Should be added to current position
|
|
275
|
+
expect(callArgs.y).toBeGreaterThan(200) // Should be added to current position
|
|
276
|
+
expect(callArgs.z).toBe(1) // Z should remain unchanged
|
|
277
|
+
})
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
describe('proximity factor calculation', () => {
|
|
281
|
+
it('should return 0 when not near any edge', () => {
|
|
282
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
283
|
+
edgeScrollManager.updateEdgeScrolling(16)
|
|
284
|
+
|
|
285
|
+
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
it('should cap proximity factor at 1', () => {
|
|
289
|
+
editor.inputs.currentScreenPoint = new Vec(0, 300)
|
|
290
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
291
|
+
|
|
292
|
+
expect(editor.setCamera).toHaveBeenCalled()
|
|
293
|
+
// The proximity factor should be capped, so movement shouldn't be infinite
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
describe('edge cases and error handling', () => {
|
|
298
|
+
it('should handle negative elapsed time', () => {
|
|
299
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
300
|
+
|
|
301
|
+
expect(() => edgeScrollManager.updateEdgeScrolling(-16)).not.toThrow()
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
it('should handle very large elapsed time', () => {
|
|
305
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
306
|
+
|
|
307
|
+
expect(() => edgeScrollManager.updateEdgeScrolling(100000)).not.toThrow()
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
it('should handle zero user edge scroll speed', () => {
|
|
311
|
+
editor.user.getEdgeScrollSpeed.mockReturnValue(0)
|
|
312
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
313
|
+
|
|
314
|
+
edgeScrollManager.updateEdgeScrolling(300)
|
|
315
|
+
|
|
316
|
+
if (editor.setCamera.mock.calls.length > 0) {
|
|
317
|
+
const callArgs = editor.setCamera.mock.calls[0][0] as Vec
|
|
318
|
+
expect(callArgs.x).toBe(0)
|
|
319
|
+
expect(callArgs.y).toBe(0)
|
|
320
|
+
}
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
it('should handle extreme zoom levels', () => {
|
|
324
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
325
|
+
|
|
326
|
+
editor.getZoomLevel.mockReturnValue(0.01) // Very zoomed out
|
|
327
|
+
expect(() => edgeScrollManager.updateEdgeScrolling(300)).not.toThrow()
|
|
328
|
+
|
|
329
|
+
editor.getZoomLevel.mockReturnValue(100) // Very zoomed in
|
|
330
|
+
expect(() => edgeScrollManager.updateEdgeScrolling(300)).not.toThrow()
|
|
331
|
+
})
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
describe('state transitions', () => {
|
|
335
|
+
it('should properly transition from not scrolling to scrolling', () => {
|
|
336
|
+
// Start with no edge scrolling
|
|
337
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
338
|
+
edgeScrollManager.updateEdgeScrolling(16)
|
|
339
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
340
|
+
|
|
341
|
+
// Move to edge
|
|
342
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
343
|
+
edgeScrollManager.updateEdgeScrolling(16)
|
|
344
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(true)
|
|
345
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(16)
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
it('should accumulate edge scroll duration over multiple updates', () => {
|
|
349
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
350
|
+
|
|
351
|
+
edgeScrollManager.updateEdgeScrolling(50)
|
|
352
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(50)
|
|
353
|
+
|
|
354
|
+
edgeScrollManager.updateEdgeScrolling(30)
|
|
355
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(80)
|
|
356
|
+
|
|
357
|
+
edgeScrollManager.updateEdgeScrolling(25)
|
|
358
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(105)
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
it('should reset duration when stopping edge scroll', () => {
|
|
362
|
+
// Start edge scrolling
|
|
363
|
+
editor.inputs.currentScreenPoint = new Vec(5, 300)
|
|
364
|
+
edgeScrollManager.updateEdgeScrolling(100)
|
|
365
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(100)
|
|
366
|
+
|
|
367
|
+
// Stop edge scrolling
|
|
368
|
+
editor.inputs.currentScreenPoint = new Vec(500, 300)
|
|
369
|
+
edgeScrollManager.updateEdgeScrolling(16)
|
|
370
|
+
expect((edgeScrollManager as any)._isEdgeScrolling).toBe(false)
|
|
371
|
+
expect((edgeScrollManager as any)._edgeScrollDuration).toBe(0)
|
|
372
|
+
})
|
|
373
|
+
})
|
|
374
|
+
})
|
package/src/lib/editor/managers/{EdgeScrollManager.ts → EdgeScrollManager/EdgeScrollManager.ts}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Vec } from '
|
|
2
|
-
import { EASINGS } from '
|
|
3
|
-
import { Editor } from '
|
|
1
|
+
import { Vec } from '../../../primitives/Vec'
|
|
2
|
+
import { EASINGS } from '../../../primitives/easings'
|
|
3
|
+
import { Editor } from '../../Editor'
|
|
4
4
|
|
|
5
5
|
/** @public */
|
|
6
6
|
export class EdgeScrollManager {
|