@netless/forge-imagery-doc 1.0.10 → 1.1.0-beta.2

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.
@@ -11,10 +11,26 @@ export class InfinityScroll extends EventEmitter<InfinityScrollEvents> {
11
11
  private lastDelta: {x: number, y: number} = { x: 0, y: 0 };
12
12
  private lastTriggerTime: number = 0;
13
13
 
14
+ // Touch event properties
15
+ private lastTouchDistance: number = 0;
16
+ private lastTouchCenter: {x: number, y: number} = { x: 0, y: 0 };
17
+ private isPinching: boolean = false;
18
+
19
+ // Gesture detection properties
20
+ private touchEventCache: Array<{x: number, y: number, distance: number}> = [];
21
+ private gestureType: 'drag' | 'zoom' | 'unknown' = 'unknown';
22
+ private gestureDetectionComplete: boolean = false;
23
+
14
24
  public constructor(view: HTMLDivElement) {
15
25
  super();
16
26
  this.view = view;
17
27
  this.view.addEventListener('wheel', this.handleWheel, { passive: false, capture: true });
28
+
29
+ console.log(this.view);
30
+ // Add touch event listeners
31
+ this.view.addEventListener('touchstart', this.handleTouchStart, { passive: false, capture: true });
32
+ this.view.addEventListener('touchmove', this.handleTouchMove, { passive: false, capture: true });
33
+ this.view.addEventListener('touchend', this.handleTouchEnd, { passive: false, capture: true });
18
34
  }
19
35
 
20
36
  private handleWheel = (evt: WheelEvent) => {
@@ -49,8 +65,153 @@ export class InfinityScroll extends EventEmitter<InfinityScrollEvents> {
49
65
  this.lastDelta = { x: 0, y: 0 };
50
66
  };
51
67
 
68
+ private handleTouchStart = (evt: TouchEvent) => {
69
+ console.log('Touch Start');
70
+ evt.preventDefault();
71
+
72
+ if (evt.touches.length === 2) {
73
+ // Reset gesture detection for new gesture
74
+ this.resetGestureDetection();
75
+ this.isPinching = true;
76
+ this.lastTouchDistance = this.getDistance(evt.touches[0], evt.touches[1]);
77
+ this.lastTouchCenter = this.getCenter(evt.touches[0], evt.touches[1]);
78
+ }
79
+ };
80
+
81
+ private handleTouchMove = (evt: TouchEvent) => {
82
+ evt.preventDefault();
83
+
84
+ if (evt.touches.length === 2 && this.isPinching) {
85
+ const currentDistance = this.getDistance(evt.touches[0], evt.touches[1]);
86
+ const currentCenter = this.getCenter(evt.touches[0], evt.touches[1]);
87
+
88
+ // Detect gesture type if not yet determined
89
+ if (!this.gestureDetectionComplete) {
90
+ this.gestureType = this.detectGesture(evt.touches[0], evt.touches[1]);
91
+
92
+ if (this.gestureType !== 'unknown') {
93
+ this.gestureDetectionComplete = true;
94
+ }
95
+ }
96
+
97
+ // Handle based on detected gesture
98
+ if (this.gestureType === 'drag' || this.gestureType === 'unknown') {
99
+ // Handle two-finger drag
100
+ const deltaX = currentCenter.x - this.lastTouchCenter.x;
101
+ const deltaY = this.lastTouchCenter.y - currentCenter.y;
102
+ this.emit('translate', deltaX, deltaY);
103
+ }
104
+
105
+ if (this.gestureType === 'zoom' || this.gestureType === 'unknown') {
106
+ // Handle pinch-to-zoom
107
+ if (this.lastTouchDistance > 0) {
108
+ const scale = currentDistance / this.lastTouchDistance;
109
+ this.emit('scale', scale);
110
+ }
111
+ }
112
+
113
+ this.lastTouchDistance = currentDistance;
114
+ this.lastTouchCenter = currentCenter;
115
+ }
116
+ };
117
+
118
+ private handleTouchEnd = (evt: TouchEvent) => {
119
+ evt.preventDefault();
120
+
121
+ if (evt.touches.length < 2) {
122
+ this.isPinching = false;
123
+ this.lastTouchDistance = 0;
124
+ this.resetGestureDetection();
125
+ }
126
+ };
127
+
128
+ private getDistance = (touch1: Touch, touch2: Touch): number => {
129
+ const dx = touch1.clientX - touch2.clientX;
130
+ const dy = touch1.clientY - touch2.clientY;
131
+ return Math.sqrt(dx * dx + dy * dy);
132
+ };
133
+
134
+ private getCenter = (touch1: Touch, touch2: Touch): {x: number, y: number} => {
135
+ return {
136
+ x: (touch1.clientX + touch2.clientX) / 2,
137
+ y: (touch1.clientY + touch2.clientY) / 2,
138
+ };
139
+ };
140
+
141
+ private detectGesture = (touch1: Touch, touch2: Touch): 'drag' | 'zoom' | 'unknown' => {
142
+ const center = this.getCenter(touch1, touch2);
143
+ const distance = this.getDistance(touch1, touch2);
144
+
145
+ // Add to cache
146
+ this.touchEventCache.push({ x: center.x, y: center.y, distance });
147
+
148
+ // Keep only last 3 events
149
+ if (this.touchEventCache.length > 3) {
150
+ this.touchEventCache.shift();
151
+ }
152
+
153
+ // Need at least 3 events to determine gesture
154
+ if (this.touchEventCache.length < 3) {
155
+ return 'unknown';
156
+ }
157
+
158
+ // Check for drag gesture (consistent movement in one direction)
159
+ const events = this.touchEventCache;
160
+ let xDirectionSame = true;
161
+ let yDirectionSame = true;
162
+
163
+ // Check X axis direction consistency
164
+ const xDirection1 = Math.sign(events[1].x - events[0].x);
165
+ const xDirection2 = Math.sign(events[2].x - events[1].x);
166
+
167
+ if (xDirection1 !== 0 && xDirection2 !== 0 && xDirection1 !== xDirection2) {
168
+ xDirectionSame = false;
169
+ }
170
+
171
+ // Check Y axis direction consistency
172
+ const yDirection1 = Math.sign(events[1].y - events[0].y);
173
+ const yDirection2 = Math.sign(events[2].y - events[1].y);
174
+
175
+ if (yDirection1 !== 0 && yDirection2 !== 0 && yDirection1 !== yDirection2) {
176
+ yDirectionSame = false;
177
+ }
178
+
179
+ // If movement is consistent in either axis, it's a drag
180
+ if (xDirectionSame || yDirectionSame) {
181
+ const movementThreshold = 10; // Minimum movement to be considered drag
182
+ const totalXMovement = Math.abs(events[2].x - events[0].x);
183
+ const totalYMovement = Math.abs(events[2].y - events[0].y);
184
+
185
+ if (totalXMovement > movementThreshold || totalYMovement > movementThreshold) {
186
+ return 'drag';
187
+ }
188
+ }
189
+
190
+ // Check for zoom gesture (significant distance change)
191
+ const totalDistanceChange = Math.abs(events[2].distance - events[0].distance);
192
+
193
+ const zoomThreshold = 15; // Minimum distance change to be considered zoom
194
+ if (totalDistanceChange > zoomThreshold) {
195
+ return 'zoom';
196
+ }
197
+
198
+ return 'unknown';
199
+ };
200
+
201
+ private resetGestureDetection = () => {
202
+ this.touchEventCache = [];
203
+ this.gestureType = 'unknown';
204
+ this.gestureDetectionComplete = false;
205
+ };
206
+
52
207
  public dispose() {
53
208
  this.view.removeEventListener('wheel', this.handleWheel);
209
+
210
+ // Remove touch event listeners
211
+ this.view.removeEventListener('touchstart', this.handleTouchStart);
212
+ this.view.removeEventListener('touchmove', this.handleTouchMove);
213
+ this.view.removeEventListener('touchend', this.handleTouchEnd);
214
+
54
215
  this.removeAllListeners();
55
216
  }
56
217
  }