@netless/forge-imagery-doc 1.0.7 → 1.1.0-beta.1
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/ImageryDocApplication.d.ts.map +1 -1
- package/dist/InfinityScroll.d.ts +13 -0
- package/dist/InfinityScroll.d.ts.map +1 -1
- package/dist/imagery-doc.esm.js +132 -4
- package/dist/imagery-doc.esm.js.map +2 -2
- package/dist/imagery-doc.js +132 -4
- package/dist/imagery-doc.js.map +2 -2
- package/package.json +3 -3
- package/src/ImageryDocApplication.ts +6 -4
- package/src/InfinityScroll.ts +161 -0
package/src/InfinityScroll.ts
CHANGED
|
@@ -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
|
}
|