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,475 +0,0 @@
|
|
|
1
|
-
// src/core/compose/features/gestures/pinch.ts
|
|
2
|
-
/**
|
|
3
|
-
* @module core/compose/features/gestures
|
|
4
|
-
* @description Adds pinch gesture recognition to components
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { BaseComponent, ElementComponent } from "mtrl";
|
|
8
|
-
import { PinchEvent, GestureHandler } from "../../../gestures";
|
|
9
|
-
import { getDistance } from "../../../gestures/utils";
|
|
10
|
-
import { hasLifecycle, hasEmit } from "mtrl";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Extended PinchEvent to support our custom event types
|
|
14
|
-
*/
|
|
15
|
-
interface ExtendedPinchEvent extends Omit<PinchEvent, "type"> {
|
|
16
|
-
type: "pinch" | "pinchstart" | "pinchend";
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Configuration for pinch gesture feature
|
|
21
|
-
*/
|
|
22
|
-
export interface PinchGestureConfig {
|
|
23
|
-
/**
|
|
24
|
-
* Whether to prevent default behaviors on touch events
|
|
25
|
-
* @default true
|
|
26
|
-
*/
|
|
27
|
-
preventDefault?: boolean;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Handler for pinch gesture
|
|
31
|
-
*/
|
|
32
|
-
onPinch?: GestureHandler;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Handler for pinch start
|
|
36
|
-
*/
|
|
37
|
-
onPinchStart?: GestureHandler;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Handler for pinch end
|
|
41
|
-
*/
|
|
42
|
-
onPinchEnd?: GestureHandler;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Whether to enable pinch recognition immediately
|
|
46
|
-
* @default true
|
|
47
|
-
*/
|
|
48
|
-
enabled?: boolean;
|
|
49
|
-
|
|
50
|
-
[key: string]: any;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Component with pinch gesture recognition capabilities
|
|
55
|
-
*/
|
|
56
|
-
export interface PinchGestureComponent extends BaseComponent {
|
|
57
|
-
/**
|
|
58
|
-
* Add a pinch event handler
|
|
59
|
-
* @param handler - Event handler function
|
|
60
|
-
* @returns Component for chaining
|
|
61
|
-
*/
|
|
62
|
-
onPinch: (handler: (event: PinchEvent) => void) => PinchGestureComponent;
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Add a pinch start event handler
|
|
66
|
-
* @param handler - Event handler function
|
|
67
|
-
* @returns Component for chaining
|
|
68
|
-
*/
|
|
69
|
-
onPinchStart: (handler: (event: PinchEvent) => void) => PinchGestureComponent;
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Add a pinch end event handler
|
|
73
|
-
* @param handler - Event handler function
|
|
74
|
-
* @returns Component for chaining
|
|
75
|
-
*/
|
|
76
|
-
onPinchEnd: (handler: (event: PinchEvent) => void) => PinchGestureComponent;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Remove a pinch event handler
|
|
80
|
-
* @param handler - Event handler function
|
|
81
|
-
* @returns Component for chaining
|
|
82
|
-
*/
|
|
83
|
-
offPinch: (handler: (event: PinchEvent) => void) => PinchGestureComponent;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Remove a pinch start event handler
|
|
87
|
-
* @param handler - Event handler function
|
|
88
|
-
* @returns Component for chaining
|
|
89
|
-
*/
|
|
90
|
-
offPinchStart: (
|
|
91
|
-
handler: (event: PinchEvent) => void
|
|
92
|
-
) => PinchGestureComponent;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Remove a pinch end event handler
|
|
96
|
-
* @param handler - Event handler function
|
|
97
|
-
* @returns Component for chaining
|
|
98
|
-
*/
|
|
99
|
-
offPinchEnd: (handler: (event: PinchEvent) => void) => PinchGestureComponent;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Enable pinch recognition
|
|
103
|
-
* @returns Component for chaining
|
|
104
|
-
*/
|
|
105
|
-
enablePinch: () => PinchGestureComponent;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Disable pinch recognition
|
|
109
|
-
* @returns Component for chaining
|
|
110
|
-
*/
|
|
111
|
-
disablePinch: () => PinchGestureComponent;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Check if pinch gestures are supported on the current device
|
|
115
|
-
* @returns Whether pinch gestures are supported
|
|
116
|
-
*/
|
|
117
|
-
isPinchSupported: () => boolean;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Adds pinch gesture recognition to a component.
|
|
122
|
-
* This is a lightweight alternative to the full gesture system,
|
|
123
|
-
* focused only on pinch detection.
|
|
124
|
-
*
|
|
125
|
-
* @param config - Configuration object containing pinch settings
|
|
126
|
-
* @returns Function that enhances a component with pinch capabilities
|
|
127
|
-
*
|
|
128
|
-
* @example
|
|
129
|
-
* ```ts
|
|
130
|
-
* // Add pinch gesture recognition to a component
|
|
131
|
-
* const component = pipe(
|
|
132
|
-
* createBase,
|
|
133
|
-
* withElement(...),
|
|
134
|
-
* withPinchGesture({
|
|
135
|
-
* onPinch: (e) => updateZoom(e.scale)
|
|
136
|
-
* })
|
|
137
|
-
* )(config);
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
|
-
export const withPinchGesture =
|
|
141
|
-
(config: PinchGestureConfig = {}) =>
|
|
142
|
-
<C extends ElementComponent>(component: C): C & PinchGestureComponent => {
|
|
143
|
-
if (!component.element) {
|
|
144
|
-
console.warn("Cannot add pinch gesture recognition: missing element");
|
|
145
|
-
return component as C & PinchGestureComponent;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Default configuration
|
|
149
|
-
const {
|
|
150
|
-
preventDefault = true,
|
|
151
|
-
onPinch,
|
|
152
|
-
onPinchStart,
|
|
153
|
-
onPinchEnd,
|
|
154
|
-
enabled = true,
|
|
155
|
-
} = config;
|
|
156
|
-
|
|
157
|
-
// Event handlers storage
|
|
158
|
-
const handlers = {
|
|
159
|
-
pinch: new Set<(event: PinchEvent) => void>(),
|
|
160
|
-
pinchstart: new Set<(event: PinchEvent) => void>(),
|
|
161
|
-
pinchend: new Set<(event: PinchEvent) => void>(),
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
// Add initial handlers if provided
|
|
165
|
-
if (onPinch) handlers.pinch.add(onPinch as (event: PinchEvent) => void);
|
|
166
|
-
if (onPinchStart)
|
|
167
|
-
handlers.pinchstart.add(onPinchStart as (event: PinchEvent) => void);
|
|
168
|
-
if (onPinchEnd)
|
|
169
|
-
handlers.pinchend.add(onPinchEnd as (event: PinchEvent) => void);
|
|
170
|
-
|
|
171
|
-
// Check if device supports touch (required for pinch)
|
|
172
|
-
const isTouchSupported =
|
|
173
|
-
"ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
174
|
-
|
|
175
|
-
// Gesture state for tracking
|
|
176
|
-
let startDistance = 0;
|
|
177
|
-
let lastScale = 1;
|
|
178
|
-
let isPinching = false;
|
|
179
|
-
let startTime = 0;
|
|
180
|
-
let isEnabled = enabled;
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Create a pinch event
|
|
184
|
-
*/
|
|
185
|
-
const createPinchEvent = (
|
|
186
|
-
e: TouchEvent,
|
|
187
|
-
type: "pinch" | "pinchstart" | "pinchend",
|
|
188
|
-
scale: number,
|
|
189
|
-
centerX: number,
|
|
190
|
-
centerY: number
|
|
191
|
-
): ExtendedPinchEvent => {
|
|
192
|
-
const event: ExtendedPinchEvent = {
|
|
193
|
-
type,
|
|
194
|
-
originalEvent: e,
|
|
195
|
-
target: e.target!,
|
|
196
|
-
startTime,
|
|
197
|
-
endTime: Date.now(),
|
|
198
|
-
duration: Date.now() - startTime,
|
|
199
|
-
defaultPrevented: false,
|
|
200
|
-
preventDefault: () => {
|
|
201
|
-
event.defaultPrevented = true;
|
|
202
|
-
if (e.cancelable) {
|
|
203
|
-
e.preventDefault();
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
stopPropagation: () => {
|
|
207
|
-
e.stopPropagation();
|
|
208
|
-
},
|
|
209
|
-
scale,
|
|
210
|
-
centerX,
|
|
211
|
-
centerY,
|
|
212
|
-
};
|
|
213
|
-
return event;
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Dispatch a pinch event to registered handlers
|
|
218
|
-
*/
|
|
219
|
-
const dispatchPinchEvent = (
|
|
220
|
-
e: TouchEvent,
|
|
221
|
-
type: "pinch" | "pinchstart" | "pinchend",
|
|
222
|
-
scale: number,
|
|
223
|
-
centerX: number,
|
|
224
|
-
centerY: number
|
|
225
|
-
): void => {
|
|
226
|
-
const extendedPinchEvent = createPinchEvent(
|
|
227
|
-
e,
|
|
228
|
-
type,
|
|
229
|
-
scale,
|
|
230
|
-
centerX,
|
|
231
|
-
centerY
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
// Call each handler for this type
|
|
235
|
-
handlers[type].forEach((handler) => {
|
|
236
|
-
try {
|
|
237
|
-
// Type assertion for the handler call
|
|
238
|
-
handler(extendedPinchEvent as unknown as PinchEvent);
|
|
239
|
-
} catch (error) {
|
|
240
|
-
console.error(`Error in ${type} handler:`, error);
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// Forward to component's event system if available
|
|
245
|
-
if (hasEmit(component)) {
|
|
246
|
-
component.emit(type, extendedPinchEvent);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Apply preventDefault if configured
|
|
250
|
-
if (preventDefault && !extendedPinchEvent.defaultPrevented) {
|
|
251
|
-
extendedPinchEvent.preventDefault();
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Handle touch start
|
|
257
|
-
*/
|
|
258
|
-
const handleTouchStart = (e: TouchEvent): void => {
|
|
259
|
-
if (!isEnabled || e.touches.length !== 2) return;
|
|
260
|
-
|
|
261
|
-
// Calculate initial distance between touch points
|
|
262
|
-
const touch1 = e.touches[0];
|
|
263
|
-
const touch2 = e.touches[1];
|
|
264
|
-
|
|
265
|
-
startDistance = getDistance(
|
|
266
|
-
touch1.clientX,
|
|
267
|
-
touch1.clientY,
|
|
268
|
-
touch2.clientX,
|
|
269
|
-
touch2.clientY
|
|
270
|
-
);
|
|
271
|
-
|
|
272
|
-
startTime = Date.now();
|
|
273
|
-
lastScale = 1;
|
|
274
|
-
isPinching = false;
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Handle touch move
|
|
279
|
-
*/
|
|
280
|
-
const handleTouchMove = (e: TouchEvent): void => {
|
|
281
|
-
if (!isEnabled || e.touches.length !== 2 || startDistance === 0) return;
|
|
282
|
-
|
|
283
|
-
const touch1 = e.touches[0];
|
|
284
|
-
const touch2 = e.touches[1];
|
|
285
|
-
|
|
286
|
-
// Calculate current distance and scale
|
|
287
|
-
const currentDistance = getDistance(
|
|
288
|
-
touch1.clientX,
|
|
289
|
-
touch1.clientY,
|
|
290
|
-
touch2.clientX,
|
|
291
|
-
touch2.clientY
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
const scale = currentDistance / startDistance;
|
|
295
|
-
const centerX = (touch1.clientX + touch2.clientX) / 2;
|
|
296
|
-
const centerY = (touch1.clientY + touch2.clientY) / 2;
|
|
297
|
-
|
|
298
|
-
// Check if scale change is significant enough
|
|
299
|
-
const scaleDiff = Math.abs(scale - lastScale);
|
|
300
|
-
const SCALE_THRESHOLD = 0.01;
|
|
301
|
-
|
|
302
|
-
if (scaleDiff > SCALE_THRESHOLD) {
|
|
303
|
-
// Start pinch if this is the first significant scale change
|
|
304
|
-
if (!isPinching) {
|
|
305
|
-
isPinching = true;
|
|
306
|
-
dispatchPinchEvent(e, "pinchstart", scale, centerX, centerY);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Dispatch continuous pinch event
|
|
310
|
-
dispatchPinchEvent(e, "pinch", scale, centerX, centerY);
|
|
311
|
-
lastScale = scale;
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Handle touch end
|
|
317
|
-
*/
|
|
318
|
-
const handleTouchEnd = (e: TouchEvent): void => {
|
|
319
|
-
if (!isEnabled || !isPinching) return;
|
|
320
|
-
|
|
321
|
-
// Calculate final center point if we still have one finger on screen
|
|
322
|
-
let centerX = 0;
|
|
323
|
-
let centerY = 0;
|
|
324
|
-
|
|
325
|
-
if (e.touches.length === 1) {
|
|
326
|
-
centerX = e.touches[0].clientX;
|
|
327
|
-
centerY = e.touches[0].clientY;
|
|
328
|
-
} else if (e.changedTouches.length > 0) {
|
|
329
|
-
centerX = e.changedTouches[0].clientX;
|
|
330
|
-
centerY = e.changedTouches[0].clientY;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// Dispatch pinch end event
|
|
334
|
-
dispatchPinchEvent(e, "pinchend", lastScale, centerX, centerY);
|
|
335
|
-
|
|
336
|
-
// Reset state
|
|
337
|
-
startDistance = 0;
|
|
338
|
-
isPinching = false;
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Handle touch cancel
|
|
343
|
-
*/
|
|
344
|
-
const handleTouchCancel = (e: TouchEvent): void => {
|
|
345
|
-
if (!isEnabled || !isPinching) return;
|
|
346
|
-
|
|
347
|
-
// Calculate final center point
|
|
348
|
-
let centerX = 0;
|
|
349
|
-
let centerY = 0;
|
|
350
|
-
|
|
351
|
-
if (e.touches.length > 0) {
|
|
352
|
-
centerX = e.touches[0].clientX;
|
|
353
|
-
centerY = e.touches[0].clientY;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Dispatch pinch end event
|
|
357
|
-
dispatchPinchEvent(e, "pinchend", lastScale, centerX, centerY);
|
|
358
|
-
|
|
359
|
-
// Reset state
|
|
360
|
-
startDistance = 0;
|
|
361
|
-
isPinching = false;
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
// Event listeners dictionary
|
|
365
|
-
const eventListeners: Record<string, EventListener> = {
|
|
366
|
-
touchstart: handleTouchStart as EventListener,
|
|
367
|
-
touchmove: handleTouchMove as EventListener,
|
|
368
|
-
touchend: handleTouchEnd as EventListener,
|
|
369
|
-
touchcancel: handleTouchCancel as EventListener,
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Add event listeners to element
|
|
374
|
-
*/
|
|
375
|
-
const setupEventListeners = (): void => {
|
|
376
|
-
if (!isTouchSupported) return;
|
|
377
|
-
|
|
378
|
-
Object.entries(eventListeners).forEach(([event, listener]) => {
|
|
379
|
-
component.element.addEventListener(event, listener, {
|
|
380
|
-
passive: !preventDefault,
|
|
381
|
-
});
|
|
382
|
-
});
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Remove event listeners from element
|
|
387
|
-
*/
|
|
388
|
-
const removeEventListeners = (): void => {
|
|
389
|
-
if (!isTouchSupported) return;
|
|
390
|
-
|
|
391
|
-
Object.entries(eventListeners).forEach(([event, listener]) => {
|
|
392
|
-
component.element.removeEventListener(event, listener);
|
|
393
|
-
});
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
// Setup listeners if initially enabled
|
|
397
|
-
if (isEnabled && isTouchSupported) {
|
|
398
|
-
setupEventListeners();
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
// Handle lifecycle integration
|
|
402
|
-
if (hasLifecycle(component)) {
|
|
403
|
-
const originalDestroy = component.lifecycle.destroy;
|
|
404
|
-
|
|
405
|
-
component.lifecycle.destroy = () => {
|
|
406
|
-
// Clean up event listeners
|
|
407
|
-
removeEventListeners();
|
|
408
|
-
|
|
409
|
-
// Clear handlers
|
|
410
|
-
Object.values(handlers).forEach((handlerSet) => handlerSet.clear());
|
|
411
|
-
|
|
412
|
-
// Call original destroy method
|
|
413
|
-
originalDestroy.call(component.lifecycle);
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// Create enhanced component
|
|
418
|
-
return {
|
|
419
|
-
...component,
|
|
420
|
-
|
|
421
|
-
// Add handler methods
|
|
422
|
-
onPinch(handler: (event: PinchEvent) => void) {
|
|
423
|
-
handlers.pinch.add(handler);
|
|
424
|
-
return this;
|
|
425
|
-
},
|
|
426
|
-
|
|
427
|
-
onPinchStart(handler: (event: PinchEvent) => void) {
|
|
428
|
-
handlers.pinchstart.add(handler);
|
|
429
|
-
return this;
|
|
430
|
-
},
|
|
431
|
-
|
|
432
|
-
onPinchEnd(handler: (event: PinchEvent) => void) {
|
|
433
|
-
handlers.pinchend.add(handler);
|
|
434
|
-
return this;
|
|
435
|
-
},
|
|
436
|
-
|
|
437
|
-
// Remove handler methods
|
|
438
|
-
offPinch(handler: (event: PinchEvent) => void) {
|
|
439
|
-
handlers.pinch.delete(handler);
|
|
440
|
-
return this;
|
|
441
|
-
},
|
|
442
|
-
|
|
443
|
-
offPinchStart(handler: (event: PinchEvent) => void) {
|
|
444
|
-
handlers.pinchstart.delete(handler);
|
|
445
|
-
return this;
|
|
446
|
-
},
|
|
447
|
-
|
|
448
|
-
offPinchEnd(handler: (event: PinchEvent) => void) {
|
|
449
|
-
handlers.pinchend.delete(handler);
|
|
450
|
-
return this;
|
|
451
|
-
},
|
|
452
|
-
|
|
453
|
-
// Enable/disable methods
|
|
454
|
-
enablePinch() {
|
|
455
|
-
if (!isEnabled) {
|
|
456
|
-
isEnabled = true;
|
|
457
|
-
setupEventListeners();
|
|
458
|
-
}
|
|
459
|
-
return this;
|
|
460
|
-
},
|
|
461
|
-
|
|
462
|
-
disablePinch() {
|
|
463
|
-
if (isEnabled) {
|
|
464
|
-
isEnabled = false;
|
|
465
|
-
removeEventListeners();
|
|
466
|
-
}
|
|
467
|
-
return this;
|
|
468
|
-
},
|
|
469
|
-
|
|
470
|
-
// Support check method
|
|
471
|
-
isPinchSupported() {
|
|
472
|
-
return isTouchSupported;
|
|
473
|
-
},
|
|
474
|
-
};
|
|
475
|
-
};
|