mtrl-addons 0.2.2 → 0.2.4
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/{src/components/index.ts → dist/components/index.d.ts} +0 -2
- package/dist/components/vlist/config.d.ts +86 -0
- package/{src/components/vlist/constants.ts → dist/components/vlist/constants.d.ts} +10 -11
- package/dist/components/vlist/features/api.d.ts +7 -0
- package/{src/components/vlist/features/index.ts → dist/components/vlist/features/index.d.ts} +0 -2
- package/dist/components/vlist/features/selection.d.ts +6 -0
- package/dist/components/vlist/features/viewport.d.ts +9 -0
- package/dist/components/vlist/features.d.ts +31 -0
- package/{src/components/vlist/index.ts → dist/components/vlist/index.d.ts} +1 -10
- package/dist/components/vlist/types.d.ts +596 -0
- package/dist/components/vlist/vlist.d.ts +29 -0
- package/dist/core/compose/features/gestures/index.d.ts +86 -0
- package/dist/core/compose/features/gestures/longpress.d.ts +85 -0
- package/dist/core/compose/features/gestures/pan.d.ts +108 -0
- package/dist/core/compose/features/gestures/pinch.d.ts +111 -0
- package/dist/core/compose/features/gestures/rotate.d.ts +111 -0
- package/dist/core/compose/features/gestures/swipe.d.ts +149 -0
- package/dist/core/compose/features/gestures/tap.d.ts +79 -0
- package/{src/core/compose/features/index.ts → dist/core/compose/features/index.d.ts} +1 -2
- package/{src/core/compose/index.ts → dist/core/compose/index.d.ts} +2 -11
- package/{src/core/gestures/index.ts → dist/core/gestures/index.d.ts} +1 -20
- package/dist/core/gestures/longpress.d.ts +23 -0
- package/dist/core/gestures/manager.d.ts +14 -0
- package/dist/core/gestures/pan.d.ts +12 -0
- package/dist/core/gestures/pinch.d.ts +14 -0
- package/dist/core/gestures/rotate.d.ts +14 -0
- package/dist/core/gestures/swipe.d.ts +20 -0
- package/dist/core/gestures/tap.d.ts +12 -0
- package/dist/core/gestures/types.d.ts +320 -0
- package/dist/core/gestures/utils.d.ts +57 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/layout/config.d.ts +33 -0
- package/dist/core/layout/index.d.ts +51 -0
- package/dist/core/layout/jsx.d.ts +65 -0
- package/dist/core/layout/schema.d.ts +112 -0
- package/dist/core/layout/types.d.ts +69 -0
- package/dist/core/viewport/constants.d.ts +105 -0
- package/dist/core/viewport/features/base.d.ts +14 -0
- package/dist/core/viewport/features/collection.d.ts +41 -0
- package/dist/core/viewport/features/events.d.ts +13 -0
- package/{src/core/viewport/features/index.ts → dist/core/viewport/features/index.d.ts} +0 -7
- package/dist/core/viewport/features/item-size.d.ts +30 -0
- package/dist/core/viewport/features/loading.d.ts +34 -0
- package/dist/core/viewport/features/momentum.d.ts +17 -0
- package/dist/core/viewport/features/performance.d.ts +53 -0
- package/dist/core/viewport/features/placeholders.d.ts +38 -0
- package/dist/core/viewport/features/rendering.d.ts +16 -0
- package/dist/core/viewport/features/scrollbar.d.ts +26 -0
- package/dist/core/viewport/features/scrolling.d.ts +16 -0
- package/dist/core/viewport/features/utils.d.ts +43 -0
- package/dist/core/viewport/features/virtual.d.ts +18 -0
- package/{src/core/viewport/index.ts → dist/core/viewport/index.d.ts} +1 -17
- package/dist/core/viewport/types.d.ts +96 -0
- package/dist/core/viewport/utils/speed-tracker.d.ts +22 -0
- package/dist/core/viewport/viewport.d.ts +11 -0
- package/{src/index.ts → dist/index.d.ts} +0 -4
- package/dist/index.js +5143 -0
- package/dist/index.mjs +5111 -0
- package/dist/styles.css +254 -0
- package/dist/styles.css.map +1 -0
- package/package.json +16 -2
- package/.cursorrules +0 -117
- package/AI.md +0 -39
- package/CLAUDE.md +0 -882
- package/build.js +0 -377
- package/index.ts +0 -7
- package/scripts/analyze-orphaned-functions.ts +0 -387
- package/scripts/debug/vlist-selection.ts +0 -121
- package/src/components/vlist/config.ts +0 -323
- package/src/components/vlist/features/api.ts +0 -626
- package/src/components/vlist/features/selection.ts +0 -436
- package/src/components/vlist/features/viewport.ts +0 -59
- package/src/components/vlist/features.ts +0 -112
- package/src/components/vlist/types.ts +0 -723
- package/src/components/vlist/vlist.ts +0 -92
- package/src/core/compose/features/gestures/index.ts +0 -227
- package/src/core/compose/features/gestures/longpress.ts +0 -383
- package/src/core/compose/features/gestures/pan.ts +0 -424
- package/src/core/compose/features/gestures/pinch.ts +0 -475
- package/src/core/compose/features/gestures/rotate.ts +0 -485
- package/src/core/compose/features/gestures/swipe.ts +0 -492
- package/src/core/compose/features/gestures/tap.ts +0 -334
- package/src/core/gestures/longpress.ts +0 -68
- package/src/core/gestures/manager.ts +0 -418
- package/src/core/gestures/pan.ts +0 -48
- package/src/core/gestures/pinch.ts +0 -58
- package/src/core/gestures/rotate.ts +0 -58
- package/src/core/gestures/swipe.ts +0 -66
- package/src/core/gestures/tap.ts +0 -45
- package/src/core/gestures/types.ts +0 -387
- package/src/core/gestures/utils.ts +0 -128
- package/src/core/index.ts +0 -43
- package/src/core/layout/config.ts +0 -102
- package/src/core/layout/index.ts +0 -168
- package/src/core/layout/jsx.ts +0 -174
- package/src/core/layout/schema.ts +0 -1044
- package/src/core/layout/types.ts +0 -95
- package/src/core/viewport/constants.ts +0 -145
- package/src/core/viewport/features/base.ts +0 -73
- package/src/core/viewport/features/collection.ts +0 -1182
- package/src/core/viewport/features/events.ts +0 -130
- package/src/core/viewport/features/item-size.ts +0 -271
- package/src/core/viewport/features/loading.ts +0 -263
- package/src/core/viewport/features/momentum.ts +0 -269
- package/src/core/viewport/features/performance.ts +0 -161
- package/src/core/viewport/features/placeholders.ts +0 -335
- package/src/core/viewport/features/rendering.ts +0 -962
- package/src/core/viewport/features/scrollbar.ts +0 -434
- package/src/core/viewport/features/scrolling.ts +0 -634
- package/src/core/viewport/features/utils.ts +0 -94
- package/src/core/viewport/features/virtual.ts +0 -525
- package/src/core/viewport/types.ts +0 -133
- package/src/core/viewport/utils/speed-tracker.ts +0 -79
- package/src/core/viewport/viewport.ts +0 -265
- package/test/benchmarks/layout/advanced.test.ts +0 -656
- package/test/benchmarks/layout/comparison.test.ts +0 -519
- package/test/benchmarks/layout/performance-comparison.test.ts +0 -274
- package/test/benchmarks/layout/real-components.test.ts +0 -733
- package/test/benchmarks/layout/simple.test.ts +0 -321
- package/test/benchmarks/layout/stress.test.ts +0 -990
- package/test/collection/basic.test.ts +0 -304
- package/test/components/vlist-selection.test.ts +0 -240
- package/test/components/vlist.test.ts +0 -63
- package/test/core/collection/adapter.test.ts +0 -161
- package/test/core/collection/collection.test.ts +0 -394
- package/test/core/layout/layout.test.ts +0 -201
- package/test/utils/dom-helpers.ts +0 -275
- package/test/utils/performance-helpers.ts +0 -392
- package/tsconfig.json +0 -20
|
@@ -1,418 +0,0 @@
|
|
|
1
|
-
// src/core/gestures/manager.ts
|
|
2
|
-
/**
|
|
3
|
-
* @module core/gestures
|
|
4
|
-
* @description Gesture management system for handling touch and mouse interactions
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
GestureConfig,
|
|
9
|
-
GestureManager,
|
|
10
|
-
GestureState,
|
|
11
|
-
GestureHandler,
|
|
12
|
-
GestureDetectionContext,
|
|
13
|
-
AnyGestureEvent,
|
|
14
|
-
GESTURE_TYPES,
|
|
15
|
-
SWIPE_DIRECTIONS
|
|
16
|
-
} from './types';
|
|
17
|
-
|
|
18
|
-
import { detectTap } from './tap';
|
|
19
|
-
import { detectSwipe } from './swipe';
|
|
20
|
-
import { detectLongPress, shouldCancelLongPress } from './longpress';
|
|
21
|
-
import { detectPan } from './pan';
|
|
22
|
-
import { detectPinch } from './pinch';
|
|
23
|
-
import { detectRotate } from './rotate';
|
|
24
|
-
import { hasTouchSupport, hasPointerSupport, getTouchCoordinates } from './utils';
|
|
25
|
-
|
|
26
|
-
// Re-export types and constants
|
|
27
|
-
export { GESTURE_TYPES, SWIPE_DIRECTIONS };
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Creates a gesture manager for handling touch and mouse interactions
|
|
31
|
-
*
|
|
32
|
-
* @param element - DOM element to attach gesture recognition to
|
|
33
|
-
* @param config - Configuration options
|
|
34
|
-
* @returns Gesture manager instance
|
|
35
|
-
*/
|
|
36
|
-
export const createGestureManager = (
|
|
37
|
-
element: HTMLElement,
|
|
38
|
-
config: GestureConfig = {}
|
|
39
|
-
): GestureManager => {
|
|
40
|
-
// Default configuration
|
|
41
|
-
const options: Required<GestureConfig> = {
|
|
42
|
-
swipeThreshold: 30,
|
|
43
|
-
swipeTimeThreshold: 300,
|
|
44
|
-
longPressTime: 500,
|
|
45
|
-
tapDistanceThreshold: 10,
|
|
46
|
-
preventDefault: true,
|
|
47
|
-
stopPropagation: false,
|
|
48
|
-
...config
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
// Event handlers storage
|
|
52
|
-
const handlers: Map<string, Set<GestureHandler>> = new Map();
|
|
53
|
-
|
|
54
|
-
// Gesture state
|
|
55
|
-
const state: GestureState = {
|
|
56
|
-
active: false,
|
|
57
|
-
startTime: 0,
|
|
58
|
-
startX: 0,
|
|
59
|
-
startY: 0,
|
|
60
|
-
lastX: 0,
|
|
61
|
-
lastY: 0,
|
|
62
|
-
currentX: 0,
|
|
63
|
-
currentY: 0,
|
|
64
|
-
touchCount: 0,
|
|
65
|
-
longPressTimer: null,
|
|
66
|
-
startDistance: 0,
|
|
67
|
-
startAngle: 0,
|
|
68
|
-
lastTapTime: 0,
|
|
69
|
-
tapCount: 0,
|
|
70
|
-
target: null
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
// Detect feature support
|
|
74
|
-
const supportTouch = hasTouchSupport();
|
|
75
|
-
const supportPointer = hasPointerSupport();
|
|
76
|
-
|
|
77
|
-
const gestureSupport = {
|
|
78
|
-
tap: true,
|
|
79
|
-
swipe: true,
|
|
80
|
-
swipeleft: true,
|
|
81
|
-
swiperight: true,
|
|
82
|
-
swipeup: true,
|
|
83
|
-
swipedown: true,
|
|
84
|
-
longpress: true,
|
|
85
|
-
pan: true,
|
|
86
|
-
pinch: supportTouch || supportPointer,
|
|
87
|
-
rotate: supportTouch || supportPointer
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Dispatch a gesture event
|
|
92
|
-
*/
|
|
93
|
-
const dispatchGesture = (event: AnyGestureEvent): void => {
|
|
94
|
-
// Get handlers for this event type
|
|
95
|
-
const eventHandlers = handlers.get(event.type);
|
|
96
|
-
if (!eventHandlers) return;
|
|
97
|
-
|
|
98
|
-
// Call each handler
|
|
99
|
-
eventHandlers.forEach(handler => {
|
|
100
|
-
try {
|
|
101
|
-
handler(event);
|
|
102
|
-
} catch (error) {
|
|
103
|
-
console.error(`Error in gesture handler for ${event.type}:`, error);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// For swipe, also dispatch direction-specific events
|
|
108
|
-
if (event.type === 'swipe' && 'direction' in event) {
|
|
109
|
-
const directionEvent = { ...event, type: `swipe${event.direction}` as any };
|
|
110
|
-
dispatchGesture(directionEvent as any);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Apply default configuration for preventDefault and stopPropagation
|
|
114
|
-
if (options.preventDefault && !event.defaultPrevented) {
|
|
115
|
-
event.preventDefault();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (options.stopPropagation) {
|
|
119
|
-
event.stopPropagation();
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
// Reference to the longpress cleanup function
|
|
124
|
-
let longPressCleanup: (() => void) | null = null;
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Handle touch/mouse start
|
|
128
|
-
*/
|
|
129
|
-
const handleStart = (e: TouchEvent | MouseEvent | PointerEvent): void => {
|
|
130
|
-
const touch = getTouchCoordinates(e);
|
|
131
|
-
const touchCount = 'touches' in e ? e.touches.length : 1;
|
|
132
|
-
|
|
133
|
-
// Store gesture state
|
|
134
|
-
state.active = true;
|
|
135
|
-
state.startTime = Date.now();
|
|
136
|
-
state.startX = state.lastX = state.currentX = touch.clientX;
|
|
137
|
-
state.startY = state.lastY = state.currentY = touch.clientY;
|
|
138
|
-
state.touchCount = touchCount;
|
|
139
|
-
state.target = e.target;
|
|
140
|
-
|
|
141
|
-
// Handle multi-touch gestures
|
|
142
|
-
if (touchCount === 2 && 'touches' in e) {
|
|
143
|
-
const touch1 = e.touches[0];
|
|
144
|
-
const touch2 = e.touches[1];
|
|
145
|
-
|
|
146
|
-
// Set initial values for pinch and rotate
|
|
147
|
-
state.startDistance = Math.sqrt(
|
|
148
|
-
Math.pow(touch2.clientX - touch1.clientX, 2) +
|
|
149
|
-
Math.pow(touch2.clientY - touch1.clientY, 2)
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
state.startAngle = Math.atan2(
|
|
153
|
-
touch2.clientY - touch1.clientY,
|
|
154
|
-
touch2.clientX - touch1.clientX
|
|
155
|
-
) * 180 / Math.PI;
|
|
156
|
-
|
|
157
|
-
if (state.startAngle < 0) state.startAngle += 360;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Setup context for gesture detection
|
|
161
|
-
const context: GestureDetectionContext = {
|
|
162
|
-
state,
|
|
163
|
-
options,
|
|
164
|
-
originalEvent: e
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
// Start long press detection
|
|
168
|
-
if (longPressCleanup) {
|
|
169
|
-
longPressCleanup();
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
longPressCleanup = detectLongPress(context, (longPressEvent) => {
|
|
173
|
-
dispatchGesture(longPressEvent);
|
|
174
|
-
});
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Handle touch/mouse move
|
|
179
|
-
*/
|
|
180
|
-
const handleMove = (e: TouchEvent | MouseEvent | PointerEvent): void => {
|
|
181
|
-
if (!state.active) return;
|
|
182
|
-
|
|
183
|
-
const touch = getTouchCoordinates(e);
|
|
184
|
-
const touchCount = 'touches' in e ? e.touches.length : 1;
|
|
185
|
-
|
|
186
|
-
// Update positions
|
|
187
|
-
state.lastX = state.currentX;
|
|
188
|
-
state.lastY = state.currentY;
|
|
189
|
-
state.currentX = touch.clientX;
|
|
190
|
-
state.currentY = touch.clientY;
|
|
191
|
-
|
|
192
|
-
// Setup context for gesture detection
|
|
193
|
-
const context: GestureDetectionContext = {
|
|
194
|
-
state,
|
|
195
|
-
options,
|
|
196
|
-
originalEvent: e
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
// Check if we should cancel longpress
|
|
200
|
-
if (shouldCancelLongPress(context) && longPressCleanup) {
|
|
201
|
-
longPressCleanup();
|
|
202
|
-
longPressCleanup = null;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Detect pan gesture
|
|
206
|
-
const panEvent = detectPan(context);
|
|
207
|
-
if (panEvent) {
|
|
208
|
-
dispatchGesture(panEvent);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Multi-touch gestures
|
|
212
|
-
if (touchCount === 2 && 'touches' in e) {
|
|
213
|
-
const touch1 = e.touches[0];
|
|
214
|
-
const touch2 = e.touches[1];
|
|
215
|
-
|
|
216
|
-
// Detect pinch
|
|
217
|
-
const pinchEvent = detectPinch(context, touch1, touch2);
|
|
218
|
-
if (pinchEvent) {
|
|
219
|
-
dispatchGesture(pinchEvent);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Detect rotate
|
|
223
|
-
const rotateEvent = detectRotate(context, touch1, touch2);
|
|
224
|
-
if (rotateEvent) {
|
|
225
|
-
dispatchGesture(rotateEvent);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Handle touch/mouse end
|
|
232
|
-
*/
|
|
233
|
-
const handleEnd = (e: TouchEvent | MouseEvent | PointerEvent): void => {
|
|
234
|
-
if (!state.active) return;
|
|
235
|
-
|
|
236
|
-
// Cancel any ongoing long press detection
|
|
237
|
-
if (longPressCleanup) {
|
|
238
|
-
longPressCleanup();
|
|
239
|
-
longPressCleanup = null;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Setup context for gesture detection
|
|
243
|
-
const context: GestureDetectionContext = {
|
|
244
|
-
state,
|
|
245
|
-
options,
|
|
246
|
-
originalEvent: e
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
// Detect tap
|
|
250
|
-
const tapEvent = detectTap(context);
|
|
251
|
-
if (tapEvent) {
|
|
252
|
-
// Update tap count for next tap
|
|
253
|
-
state.lastTapTime = Date.now();
|
|
254
|
-
state.tapCount = tapEvent.count;
|
|
255
|
-
|
|
256
|
-
dispatchGesture(tapEvent);
|
|
257
|
-
} else {
|
|
258
|
-
// Detect swipe
|
|
259
|
-
const swipeEvent = detectSwipe(context);
|
|
260
|
-
if (swipeEvent) {
|
|
261
|
-
dispatchGesture(swipeEvent);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Reset state
|
|
266
|
-
state.active = false;
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Handle touch/mouse cancel
|
|
271
|
-
*/
|
|
272
|
-
const handleCancel = (): void => {
|
|
273
|
-
// Cancel long press detection
|
|
274
|
-
if (longPressCleanup) {
|
|
275
|
-
longPressCleanup();
|
|
276
|
-
longPressCleanup = null;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Reset state
|
|
280
|
-
state.active = false;
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
// Event listener references
|
|
284
|
-
let eventListeners: {
|
|
285
|
-
[event: string]: EventListener
|
|
286
|
-
} = {};
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Set up event listeners based on available APIs
|
|
290
|
-
*/
|
|
291
|
-
const setupEventListeners = (): void => {
|
|
292
|
-
if (supportPointer) {
|
|
293
|
-
// Use Pointer Events API
|
|
294
|
-
eventListeners = {
|
|
295
|
-
pointerdown: handleStart as EventListener,
|
|
296
|
-
pointermove: handleMove as EventListener,
|
|
297
|
-
pointerup: handleEnd as EventListener,
|
|
298
|
-
pointercancel: handleCancel as EventListener
|
|
299
|
-
};
|
|
300
|
-
} else if (supportTouch) {
|
|
301
|
-
// Use Touch Events API
|
|
302
|
-
eventListeners = {
|
|
303
|
-
touchstart: handleStart as EventListener,
|
|
304
|
-
touchmove: handleMove as EventListener,
|
|
305
|
-
touchend: handleEnd as EventListener,
|
|
306
|
-
touchcancel: handleCancel as EventListener
|
|
307
|
-
};
|
|
308
|
-
} else {
|
|
309
|
-
// Fall back to Mouse Events API
|
|
310
|
-
eventListeners = {
|
|
311
|
-
mousedown: handleStart as EventListener,
|
|
312
|
-
mousemove: handleMove as EventListener,
|
|
313
|
-
mouseup: handleEnd as EventListener,
|
|
314
|
-
mouseleave: handleCancel as EventListener
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Add listeners to element
|
|
319
|
-
Object.entries(eventListeners).forEach(([event, listener]) => {
|
|
320
|
-
element.addEventListener(event, listener, { passive: !options.preventDefault });
|
|
321
|
-
});
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Remove all event listeners
|
|
326
|
-
*/
|
|
327
|
-
const removeEventListeners = (): void => {
|
|
328
|
-
// Remove all listeners from element
|
|
329
|
-
Object.entries(eventListeners).forEach(([event, listener]) => {
|
|
330
|
-
element.removeEventListener(event, listener);
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
// Clear eventListeners object
|
|
334
|
-
eventListeners = {};
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
// Initialize event listeners
|
|
338
|
-
setupEventListeners();
|
|
339
|
-
|
|
340
|
-
return {
|
|
341
|
-
/**
|
|
342
|
-
* Add a gesture event listener
|
|
343
|
-
* @param eventType - Type of gesture to listen for
|
|
344
|
-
* @param handler - Event handler function
|
|
345
|
-
* @returns Gesture manager for chaining
|
|
346
|
-
*/
|
|
347
|
-
on(eventType: string, handler: GestureHandler): GestureManager {
|
|
348
|
-
if (!handlers.has(eventType)) {
|
|
349
|
-
handlers.set(eventType, new Set());
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
handlers.get(eventType)!.add(handler);
|
|
353
|
-
return this;
|
|
354
|
-
},
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Remove a gesture event listener
|
|
358
|
-
* @param eventType - Type of gesture
|
|
359
|
-
* @param handler - Event handler to remove
|
|
360
|
-
* @returns Gesture manager for chaining
|
|
361
|
-
*/
|
|
362
|
-
off(eventType: string, handler: GestureHandler): GestureManager {
|
|
363
|
-
const eventHandlers = handlers.get(eventType);
|
|
364
|
-
if (eventHandlers) {
|
|
365
|
-
eventHandlers.delete(handler);
|
|
366
|
-
|
|
367
|
-
if (eventHandlers.size === 0) {
|
|
368
|
-
handlers.delete(eventType);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
return this;
|
|
372
|
-
},
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Check if a gesture is supported on the current device
|
|
376
|
-
* @param gestureType - Type of gesture to check
|
|
377
|
-
* @returns Whether the gesture is supported
|
|
378
|
-
*/
|
|
379
|
-
isSupported(gestureType: string): boolean {
|
|
380
|
-
return gestureType in gestureSupport && gestureSupport[gestureType as keyof typeof gestureSupport];
|
|
381
|
-
},
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* Enable gesture recognition by adding event listeners
|
|
385
|
-
* @returns Gesture manager for chaining
|
|
386
|
-
*/
|
|
387
|
-
enable(): GestureManager {
|
|
388
|
-
setupEventListeners();
|
|
389
|
-
return this;
|
|
390
|
-
},
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Disable gesture recognition by removing event listeners
|
|
394
|
-
* @returns Gesture manager for chaining
|
|
395
|
-
*/
|
|
396
|
-
disable(): GestureManager {
|
|
397
|
-
removeEventListeners();
|
|
398
|
-
return this;
|
|
399
|
-
},
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Clean up event listeners and timers
|
|
403
|
-
*/
|
|
404
|
-
destroy(): void {
|
|
405
|
-
// Clean up listeners
|
|
406
|
-
removeEventListeners();
|
|
407
|
-
|
|
408
|
-
// Clear long press timer
|
|
409
|
-
if (longPressCleanup) {
|
|
410
|
-
longPressCleanup();
|
|
411
|
-
longPressCleanup = null;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// Clear handler references
|
|
415
|
-
handlers.clear();
|
|
416
|
-
}
|
|
417
|
-
};
|
|
418
|
-
};
|
package/src/core/gestures/pan.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
// src/core/gestures/pan.ts
|
|
2
|
-
/**
|
|
3
|
-
* @module core/gestures
|
|
4
|
-
* @description Pan gesture detection
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { PanEvent, GestureDetectionContext } from "./types";
|
|
8
|
-
import { createGestureEvent } from "./utils";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Detect pan gesture
|
|
12
|
-
*
|
|
13
|
-
* @param context - Gesture detection context
|
|
14
|
-
* @returns Pan event or null if no significant movement
|
|
15
|
-
*/
|
|
16
|
-
export function detectPan(context: GestureDetectionContext): PanEvent | null {
|
|
17
|
-
const { state, originalEvent } = context;
|
|
18
|
-
|
|
19
|
-
// Calculate delta from start position
|
|
20
|
-
const deltaX = state.currentX - state.startX;
|
|
21
|
-
const deltaY = state.currentY - state.startY;
|
|
22
|
-
|
|
23
|
-
// Calculate delta from last position to determine if there's significant movement
|
|
24
|
-
const moveDeltaX = state.currentX - state.lastX;
|
|
25
|
-
const moveDeltaY = state.currentY - state.lastY;
|
|
26
|
-
const moveDelta = Math.sqrt(
|
|
27
|
-
moveDeltaX * moveDeltaX + moveDeltaY * moveDeltaY
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
// Check if movement is significant
|
|
31
|
-
if (moveDelta > 0) {
|
|
32
|
-
// Create pan event
|
|
33
|
-
const panEvent: PanEvent = {
|
|
34
|
-
...createGestureEvent("pan", originalEvent, state),
|
|
35
|
-
type: "pan",
|
|
36
|
-
deltaX,
|
|
37
|
-
deltaY,
|
|
38
|
-
startX: state.startX,
|
|
39
|
-
startY: state.startY,
|
|
40
|
-
currentX: state.currentX,
|
|
41
|
-
currentY: state.currentY,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
return panEvent;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
// src/core/gestures/pinch.ts
|
|
2
|
-
/**
|
|
3
|
-
* @module core/gestures
|
|
4
|
-
* @description Pinch gesture detection
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { PinchEvent, GestureDetectionContext } from "./types";
|
|
8
|
-
import { createGestureEvent, getDistance } from "./utils";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Detect pinch gesture
|
|
12
|
-
*
|
|
13
|
-
* @param context - Gesture detection context
|
|
14
|
-
* @param touch1 - First touch point
|
|
15
|
-
* @param touch2 - Second touch point
|
|
16
|
-
* @returns Pinch event or null if no pinch detected
|
|
17
|
-
*/
|
|
18
|
-
export function detectPinch(
|
|
19
|
-
context: GestureDetectionContext,
|
|
20
|
-
touch1: Touch,
|
|
21
|
-
touch2: Touch
|
|
22
|
-
): PinchEvent | null {
|
|
23
|
-
const { state, originalEvent } = context;
|
|
24
|
-
|
|
25
|
-
// Calculate current distance between touch points
|
|
26
|
-
const currentDistance = getDistance(
|
|
27
|
-
touch1.clientX,
|
|
28
|
-
touch1.clientY,
|
|
29
|
-
touch2.clientX,
|
|
30
|
-
touch2.clientY
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
// Minimum movement threshold for pinch detection
|
|
34
|
-
const PINCH_THRESHOLD = 10;
|
|
35
|
-
|
|
36
|
-
// Check if the distance change is significant
|
|
37
|
-
if (Math.abs(currentDistance - state.startDistance) > PINCH_THRESHOLD) {
|
|
38
|
-
// Calculate scale factor
|
|
39
|
-
const scale = currentDistance / state.startDistance;
|
|
40
|
-
|
|
41
|
-
// Calculate center point
|
|
42
|
-
const centerX = (touch1.clientX + touch2.clientX) / 2;
|
|
43
|
-
const centerY = (touch1.clientY + touch2.clientY) / 2;
|
|
44
|
-
|
|
45
|
-
// Create pinch event
|
|
46
|
-
const pinchEvent: PinchEvent = {
|
|
47
|
-
...createGestureEvent("pinch", originalEvent, state),
|
|
48
|
-
type: "pinch",
|
|
49
|
-
scale,
|
|
50
|
-
centerX,
|
|
51
|
-
centerY,
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return pinchEvent;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
// src/core/gestures/rotate.ts
|
|
2
|
-
/**
|
|
3
|
-
* @module core/gestures
|
|
4
|
-
* @description Rotate gesture detection
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { RotateEvent, GestureDetectionContext } from "./types";
|
|
8
|
-
import { createGestureEvent, getAngle } from "./utils";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Detect rotate gesture
|
|
12
|
-
*
|
|
13
|
-
* @param context - Gesture detection context
|
|
14
|
-
* @param touch1 - First touch point
|
|
15
|
-
* @param touch2 - Second touch point
|
|
16
|
-
* @returns Rotate event or null if no rotation detected
|
|
17
|
-
*/
|
|
18
|
-
export function detectRotate(
|
|
19
|
-
context: GestureDetectionContext,
|
|
20
|
-
touch1: Touch,
|
|
21
|
-
touch2: Touch
|
|
22
|
-
): RotateEvent | null {
|
|
23
|
-
const { state, originalEvent } = context;
|
|
24
|
-
|
|
25
|
-
// Calculate current angle between touch points
|
|
26
|
-
const currentAngle = getAngle(
|
|
27
|
-
touch1.clientX,
|
|
28
|
-
touch1.clientY,
|
|
29
|
-
touch2.clientX,
|
|
30
|
-
touch2.clientY
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
// Minimum rotation threshold for detection
|
|
34
|
-
const ROTATION_THRESHOLD = 10;
|
|
35
|
-
|
|
36
|
-
// Calculate rotation difference
|
|
37
|
-
const rotationDiff = currentAngle - state.startAngle;
|
|
38
|
-
|
|
39
|
-
// Check if rotation is significant
|
|
40
|
-
if (Math.abs(rotationDiff) > ROTATION_THRESHOLD) {
|
|
41
|
-
// Calculate center point
|
|
42
|
-
const centerX = (touch1.clientX + touch2.clientX) / 2;
|
|
43
|
-
const centerY = (touch1.clientY + touch2.clientY) / 2;
|
|
44
|
-
|
|
45
|
-
// Create rotate event
|
|
46
|
-
const rotateEvent: RotateEvent = {
|
|
47
|
-
...createGestureEvent("rotate", originalEvent, state),
|
|
48
|
-
type: "rotate",
|
|
49
|
-
rotation: rotationDiff,
|
|
50
|
-
centerX,
|
|
51
|
-
centerY,
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
return rotateEvent;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
// src/core/gestures/swipe.ts
|
|
2
|
-
/**
|
|
3
|
-
* @module core/gestures
|
|
4
|
-
* @description Swipe gesture detection
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { SwipeEvent, GestureDetectionContext, SWIPE_DIRECTIONS } from './types';
|
|
8
|
-
import { createGestureEvent } from './utils';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Determine swipe direction based on delta X and Y
|
|
12
|
-
*
|
|
13
|
-
* @param deltaX - Distance moved in X direction
|
|
14
|
-
* @param deltaY - Distance moved in Y direction
|
|
15
|
-
* @returns Direction of the swipe
|
|
16
|
-
*/
|
|
17
|
-
export function getSwipeDirection(deltaX: number, deltaY: number): SWIPE_DIRECTIONS {
|
|
18
|
-
if (Math.abs(deltaX) > Math.abs(deltaY)) {
|
|
19
|
-
return deltaX > 0 ? SWIPE_DIRECTIONS.RIGHT : SWIPE_DIRECTIONS.LEFT;
|
|
20
|
-
}
|
|
21
|
-
return deltaY > 0 ? SWIPE_DIRECTIONS.DOWN : SWIPE_DIRECTIONS.UP;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Detect swipe gesture
|
|
26
|
-
*
|
|
27
|
-
* @param context - Gesture detection context
|
|
28
|
-
* @returns Swipe event or null if no swipe detected
|
|
29
|
-
*/
|
|
30
|
-
export function detectSwipe(context: GestureDetectionContext): SwipeEvent | null {
|
|
31
|
-
const { state, options, originalEvent } = context;
|
|
32
|
-
|
|
33
|
-
// Calculate deltas and distance
|
|
34
|
-
const deltaX = state.currentX - state.startX;
|
|
35
|
-
const deltaY = state.currentY - state.startY;
|
|
36
|
-
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
37
|
-
|
|
38
|
-
// Calculate time and velocity
|
|
39
|
-
const endTime = Date.now();
|
|
40
|
-
const deltaTime = endTime - state.startTime;
|
|
41
|
-
const velocity = distance / deltaTime;
|
|
42
|
-
|
|
43
|
-
// Check if it's a swipe
|
|
44
|
-
if (distance >= options.swipeThreshold && deltaTime <= options.swipeTimeThreshold) {
|
|
45
|
-
const direction = getSwipeDirection(deltaX, deltaY);
|
|
46
|
-
|
|
47
|
-
// Create swipe event
|
|
48
|
-
const swipeEvent: SwipeEvent = {
|
|
49
|
-
...createGestureEvent('swipe', originalEvent, state),
|
|
50
|
-
type: 'swipe',
|
|
51
|
-
direction,
|
|
52
|
-
deltaX,
|
|
53
|
-
deltaY,
|
|
54
|
-
distance,
|
|
55
|
-
velocity,
|
|
56
|
-
startX: state.startX,
|
|
57
|
-
startY: state.startY,
|
|
58
|
-
endX: state.currentX,
|
|
59
|
-
endY: state.currentY
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
return swipeEvent;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return null;
|
|
66
|
-
}
|
package/src/core/gestures/tap.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// src/core/gestures/tap.ts
|
|
2
|
-
/**
|
|
3
|
-
* @module core/gestures
|
|
4
|
-
* @description Tap gesture detection
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { TapEvent, GestureDetectionContext } from './types';
|
|
8
|
-
import { createGestureEvent } from './utils';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Detect tap gesture
|
|
12
|
-
*
|
|
13
|
-
* @param context - Gesture detection context
|
|
14
|
-
* @returns Tap event or null if no tap detected
|
|
15
|
-
*/
|
|
16
|
-
export function detectTap(context: GestureDetectionContext): TapEvent | null {
|
|
17
|
-
const { state, options, originalEvent } = context;
|
|
18
|
-
|
|
19
|
-
// Calculate distance between start and current position
|
|
20
|
-
const deltaX = state.currentX - state.startX;
|
|
21
|
-
const deltaY = state.currentY - state.startY;
|
|
22
|
-
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
23
|
-
|
|
24
|
-
// Check if movement is within threshold
|
|
25
|
-
if (distance < options.tapDistanceThreshold) {
|
|
26
|
-
// Check for double tap
|
|
27
|
-
const now = Date.now();
|
|
28
|
-
const isDoubleTap = now - state.lastTapTime < 300;
|
|
29
|
-
|
|
30
|
-
const tapCount = isDoubleTap ? state.tapCount + 1 : 1;
|
|
31
|
-
|
|
32
|
-
// Create tap event
|
|
33
|
-
const tapEvent: TapEvent = {
|
|
34
|
-
...createGestureEvent('tap', originalEvent, state),
|
|
35
|
-
type: 'tap',
|
|
36
|
-
count: tapCount,
|
|
37
|
-
x: state.currentX,
|
|
38
|
-
y: state.currentY
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
return tapEvent;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return null;
|
|
45
|
-
}
|