@shapediver/viewer.features.drawing-tools 3.12.16 → 3.12.18
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/package.json +10 -10
- package/dist/business/implementation/managers/interaction/InteractionManagerAdapter.d.ts +0 -36
- package/dist/business/implementation/managers/interaction/InteractionManagerAdapter.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/InteractionManagerAdapter.js +0 -77
- package/dist/business/implementation/managers/interaction/InteractionManagerAdapter.js.map +0 -1
- package/dist/business/implementation/managers/interaction/InteractionManagerRefactored.d.ts +0 -82
- package/dist/business/implementation/managers/interaction/InteractionManagerRefactored.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/InteractionManagerRefactored.js +0 -406
- package/dist/business/implementation/managers/interaction/InteractionManagerRefactored.js.map +0 -1
- package/dist/business/implementation/managers/interaction/actions/InteractionActions.d.ts +0 -107
- package/dist/business/implementation/managers/interaction/actions/InteractionActions.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/actions/InteractionActions.js +0 -191
- package/dist/business/implementation/managers/interaction/actions/InteractionActions.js.map +0 -1
- package/dist/business/implementation/managers/interaction/config/InteractionConfig.d.ts +0 -134
- package/dist/business/implementation/managers/interaction/config/InteractionConfig.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/config/InteractionConfig.js +0 -218
- package/dist/business/implementation/managers/interaction/config/InteractionConfig.js.map +0 -1
- package/dist/business/implementation/managers/interaction/gestures/GestureRecognition.d.ts +0 -118
- package/dist/business/implementation/managers/interaction/gestures/GestureRecognition.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/gestures/GestureRecognition.js +0 -352
- package/dist/business/implementation/managers/interaction/gestures/GestureRecognition.js.map +0 -1
- package/dist/business/implementation/managers/interaction/index.d.ts +0 -13
- package/dist/business/implementation/managers/interaction/index.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/index.js +0 -49
- package/dist/business/implementation/managers/interaction/index.js.map +0 -1
- package/dist/business/implementation/managers/interaction/interfaces/IInteractionManagerForStrategy.d.ts +0 -24
- package/dist/business/implementation/managers/interaction/interfaces/IInteractionManagerForStrategy.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/interfaces/IInteractionManagerForStrategy.js +0 -3
- package/dist/business/implementation/managers/interaction/interfaces/IInteractionManagerForStrategy.js.map +0 -1
- package/dist/business/implementation/managers/interaction/mobile-detection-example.d.ts +0 -24
- package/dist/business/implementation/managers/interaction/mobile-detection-example.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/mobile-detection-example.js +0 -112
- package/dist/business/implementation/managers/interaction/mobile-detection-example.js.map +0 -1
- package/dist/business/implementation/managers/interaction/strategies/DesktopInteractionStrategy.d.ts +0 -37
- package/dist/business/implementation/managers/interaction/strategies/DesktopInteractionStrategy.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/strategies/DesktopInteractionStrategy.js +0 -301
- package/dist/business/implementation/managers/interaction/strategies/DesktopInteractionStrategy.js.map +0 -1
- package/dist/business/implementation/managers/interaction/strategies/IInteractionStrategy.d.ts +0 -52
- package/dist/business/implementation/managers/interaction/strategies/IInteractionStrategy.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/strategies/IInteractionStrategy.js +0 -21
- package/dist/business/implementation/managers/interaction/strategies/IInteractionStrategy.js.map +0 -1
- package/dist/business/implementation/managers/interaction/strategies/MobileInteractionStrategy.d.ts +0 -80
- package/dist/business/implementation/managers/interaction/strategies/MobileInteractionStrategy.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/strategies/MobileInteractionStrategy.js +0 -671
- package/dist/business/implementation/managers/interaction/strategies/MobileInteractionStrategy.js.map +0 -1
- package/dist/business/implementation/managers/interaction/test-mobile-detection.d.ts +0 -24
- package/dist/business/implementation/managers/interaction/test-mobile-detection.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/test-mobile-detection.js +0 -136
- package/dist/business/implementation/managers/interaction/test-mobile-detection.js.map +0 -1
- package/dist/business/implementation/managers/interaction/test-refactored.d.ts +0 -9
- package/dist/business/implementation/managers/interaction/test-refactored.d.ts.map +0 -1
- package/dist/business/implementation/managers/interaction/test-refactored.js +0 -57
- package/dist/business/implementation/managers/interaction/test-refactored.js.map +0 -1
package/dist/business/implementation/managers/interaction/strategies/MobileInteractionStrategy.js
DELETED
|
@@ -1,671 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MobileInteractionStrategy = void 0;
|
|
4
|
-
const viewer_1 = require("@shapediver/viewer");
|
|
5
|
-
const viewer_shared_services_1 = require("@shapediver/viewer.shared.services");
|
|
6
|
-
const IInteractionStrategy_1 = require("./IInteractionStrategy");
|
|
7
|
-
/**
|
|
8
|
-
* Mobile-specific interaction strategy using touch gestures
|
|
9
|
-
*/
|
|
10
|
-
class MobileInteractionStrategy {
|
|
11
|
-
constructor(drawingToolsManager, interactionManager, config) {
|
|
12
|
-
// Touch-specific state
|
|
13
|
-
this.touchStartTime = 0;
|
|
14
|
-
this.touchStartPosition = { x: 0, y: 0 };
|
|
15
|
-
this.isLongPress = false;
|
|
16
|
-
this.touchHasMoved = false;
|
|
17
|
-
this.isPotentialInsertion = false;
|
|
18
|
-
this.isDraggingPoint = false; // Track if we're dragging a point
|
|
19
|
-
this.lastTapTime = 0;
|
|
20
|
-
this.tapCount = 0;
|
|
21
|
-
this.drawingToolsManager = drawingToolsManager;
|
|
22
|
-
this.interactionManager = interactionManager;
|
|
23
|
-
this.config = config;
|
|
24
|
-
}
|
|
25
|
-
canHandle(event) {
|
|
26
|
-
// Handle all pointer types on mobile devices (touch, pen, mouse on tablets)
|
|
27
|
-
// Note: Strategy selection is now done via SystemInfo.isMobile,
|
|
28
|
-
// so this method is primarily for compatibility
|
|
29
|
-
return (event.pointerType === "touch" ||
|
|
30
|
-
event.pointerType === "pen" ||
|
|
31
|
-
event.pointerType === "mouse");
|
|
32
|
-
}
|
|
33
|
-
onPointerDown(event, ray) {
|
|
34
|
-
if (this.drawingToolsManager.closed) {
|
|
35
|
-
return { handled: false };
|
|
36
|
-
}
|
|
37
|
-
this.touchStartTime = Date.now();
|
|
38
|
-
this.touchStartPosition = { x: event.clientX, y: event.clientY };
|
|
39
|
-
this.isLongPress = false;
|
|
40
|
-
this.longPressPoint = undefined; // Reset long press point
|
|
41
|
-
this.touchHasMoved = false;
|
|
42
|
-
this.isPotentialInsertion = false;
|
|
43
|
-
this.isDraggingPoint = false; // Reset drag state
|
|
44
|
-
// Start long press detection
|
|
45
|
-
this.startLongPressDetection(event, ray);
|
|
46
|
-
// Handle multi-touch for different actions
|
|
47
|
-
if (this.isMultiTouch(event)) {
|
|
48
|
-
return this.handleMultiTouch(event, ray);
|
|
49
|
-
}
|
|
50
|
-
// Handle insertion immediately in onPointerDown (like desktop strategy)
|
|
51
|
-
// Only if we're not near an existing point (which would be for dragging)
|
|
52
|
-
const distances = this.drawingToolsManager.geometryMathManager.checkPointDistances(ray, this.drawingToolsManager.positionArray);
|
|
53
|
-
const nearPoint = this.findNearestTouchTarget(distances);
|
|
54
|
-
// IMPORTANT: Check for closing FIRST, before any other logic that might change insertion state
|
|
55
|
-
// Special case: If we're in insertion mode and touching the first point, close immediately
|
|
56
|
-
if (nearPoint === 0 &&
|
|
57
|
-
this.interactionManager.insertionInteractionHandler
|
|
58
|
-
.insertionActive &&
|
|
59
|
-
this.canCloseDrawing()) {
|
|
60
|
-
// Close the drawing immediately when touching the first point
|
|
61
|
-
this.interactionManager.insertionInteractionHandler.stopInsertion();
|
|
62
|
-
this.drawingToolsManager.geometryState.closeLoop = true;
|
|
63
|
-
this.disableMobileContinuousRendering();
|
|
64
|
-
// Emit GEOMETRY_CHANGED event
|
|
65
|
-
viewer_shared_services_1.EventEngine.instance.emitEvent(viewer_shared_services_1.EVENTTYPE_DRAWING_TOOLS.GEOMETRY_CHANGED, {
|
|
66
|
-
viewportId: this.drawingToolsManager.viewport.id,
|
|
67
|
-
drawingToolId: this.drawingToolsManager.uuid,
|
|
68
|
-
points: this.drawingToolsManager.geometryState.getPointsData(),
|
|
69
|
-
temporary: false,
|
|
70
|
-
fromHistory: false,
|
|
71
|
-
});
|
|
72
|
-
this.drawingToolsManager.viewport.render(); // Force immediate render after closing
|
|
73
|
-
return {
|
|
74
|
-
handled: true,
|
|
75
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_END,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
if (nearPoint === undefined) {
|
|
79
|
-
// Not near a point, this could be an insertion tap
|
|
80
|
-
// Check if insertion is allowed before proceeding
|
|
81
|
-
if (!this.canInsertPoint()) {
|
|
82
|
-
return {
|
|
83
|
-
handled: true,
|
|
84
|
-
action: IInteractionStrategy_1.InteractionAction.NONE,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
// Handle insertion finalization (exactly like desktop strategy)
|
|
88
|
-
if (this.interactionManager.insertionInteractionHandler
|
|
89
|
-
.insertionActive) {
|
|
90
|
-
const result = this.interactionManager.insertionInteractionHandler.finalizeInsertion();
|
|
91
|
-
if (result) {
|
|
92
|
-
this.drawingToolsManager.update();
|
|
93
|
-
this.disableMobileContinuousRendering();
|
|
94
|
-
this.drawingToolsManager.viewport.render(); // Force immediate render after closing
|
|
95
|
-
return {
|
|
96
|
-
handled: true,
|
|
97
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_END,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
// Only continue insertion if we can still insert points
|
|
102
|
-
if (this.canInsertPoint()) {
|
|
103
|
-
this.enableMobileContinuousRendering();
|
|
104
|
-
this.interactionManager.insertionInteractionHandler.startInsertion(event);
|
|
105
|
-
this.drawingToolsManager.update();
|
|
106
|
-
return {
|
|
107
|
-
handled: true,
|
|
108
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_START,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
// Can't insert more points, stop insertion
|
|
113
|
-
this.disableMobileContinuousRendering();
|
|
114
|
-
return {
|
|
115
|
-
handled: true,
|
|
116
|
-
action: IInteractionStrategy_1.InteractionAction.NONE,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
// Set last event in manager (important for insertion logic)
|
|
122
|
-
this.interactionManager.setLastEvent(event);
|
|
123
|
-
// Check if insertion is already active (need to finalize previous insertion)
|
|
124
|
-
if (this.interactionManager.insertionInteractionHandler
|
|
125
|
-
.insertionActive) {
|
|
126
|
-
const result = this.interactionManager.insertionInteractionHandler.finalizeInsertion();
|
|
127
|
-
if (result) {
|
|
128
|
-
// Drawing was closed
|
|
129
|
-
this.disableMobileContinuousRendering();
|
|
130
|
-
this.drawingToolsManager.update();
|
|
131
|
-
this.drawingToolsManager.viewport.render(); // Force immediate render after closing
|
|
132
|
-
return {
|
|
133
|
-
handled: true,
|
|
134
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_END,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
// Only continue insertion if we can still insert points
|
|
139
|
-
if (this.canInsertPoint()) {
|
|
140
|
-
// Continue with new insertion
|
|
141
|
-
this.interactionManager.startInsertion();
|
|
142
|
-
this.drawingToolsManager.update();
|
|
143
|
-
return {
|
|
144
|
-
handled: true,
|
|
145
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_START,
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
// Can't insert more points, stop insertion
|
|
150
|
-
this.disableMobileContinuousRendering();
|
|
151
|
-
return {
|
|
152
|
-
handled: true,
|
|
153
|
-
action: IInteractionStrategy_1.InteractionAction.NONE,
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
// Start insertion immediately (like desktop strategy) - but only if allowed
|
|
159
|
-
if (this.canInsertPoint()) {
|
|
160
|
-
this.isPotentialInsertion = true; // Track that we started an insertion
|
|
161
|
-
this.enableMobileContinuousRendering();
|
|
162
|
-
this.interactionManager.startInsertion();
|
|
163
|
-
return {
|
|
164
|
-
handled: true,
|
|
165
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_START,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
// Can't insert points, return without action
|
|
170
|
-
return {
|
|
171
|
-
handled: true,
|
|
172
|
-
action: IInteractionStrategy_1.InteractionAction.NONE,
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
return this.handleSingleTouch(event, ray);
|
|
177
|
-
}
|
|
178
|
-
onPointerMove(event, ray) {
|
|
179
|
-
if (this.drawingToolsManager.closed) {
|
|
180
|
-
return { handled: false };
|
|
181
|
-
}
|
|
182
|
-
// Handle different move scenarios - check dragging FIRST
|
|
183
|
-
if (this.isDragging()) {
|
|
184
|
-
return this.handleTouchDrag(event, ray);
|
|
185
|
-
}
|
|
186
|
-
// Cancel long press if moved too far
|
|
187
|
-
if (this.hasTouchMovedBeyondThreshold(event)) {
|
|
188
|
-
this.touchHasMoved = true;
|
|
189
|
-
// If we have a selected point and aren't dragging yet, start dragging
|
|
190
|
-
if (!this.isDragging() &&
|
|
191
|
-
this.interactionManager.interactionManagerHelper
|
|
192
|
-
.selectedPointIndices.length > 0) {
|
|
193
|
-
const selectedPoints = this.interactionManager.interactionManagerHelper
|
|
194
|
-
.selectedPointIndices;
|
|
195
|
-
if (selectedPoints.length > 0) {
|
|
196
|
-
// Start dragging the selected point(s)
|
|
197
|
-
const draggingStarted = this.interactionManager.interactionManagerHelper.startDragging();
|
|
198
|
-
if (draggingStarted) {
|
|
199
|
-
this.isDraggingPoint = true;
|
|
200
|
-
this.enableMobileCameraFreeze();
|
|
201
|
-
this.cancelLongPress(); // Cancel long press since we're now dragging
|
|
202
|
-
return this.handleTouchDrag(event, ray);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
// Cancel insertion if this was a potential insertion and we've started dragging
|
|
207
|
-
// (indicating user wants to drag, not insert)
|
|
208
|
-
if (this.isPotentialInsertion &&
|
|
209
|
-
this.interactionManager.insertionInteractionHandler
|
|
210
|
-
.insertionActive) {
|
|
211
|
-
// Check if we've started dragging - if so, cancel the insertion
|
|
212
|
-
if (this.isDragging() || this.isDraggingPoint) {
|
|
213
|
-
this.interactionManager.insertionInteractionHandler.stopInsertion();
|
|
214
|
-
this.disableMobileContinuousRendering();
|
|
215
|
-
this.isPotentialInsertion = false;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
this.cancelLongPress();
|
|
219
|
-
}
|
|
220
|
-
if (this.interactionManager.insertionInteractionHandler.insertionActive) {
|
|
221
|
-
return this.handleInsertionMove(event, ray);
|
|
222
|
-
}
|
|
223
|
-
// Update cursor for hover feedback
|
|
224
|
-
this.updateCursor();
|
|
225
|
-
return this.handleTouchHover(event, ray);
|
|
226
|
-
}
|
|
227
|
-
onPointerUp(event, ray) {
|
|
228
|
-
if (this.drawingToolsManager.closed) {
|
|
229
|
-
return { handled: false };
|
|
230
|
-
}
|
|
231
|
-
this.cancelLongPress();
|
|
232
|
-
// Clean up drag state
|
|
233
|
-
if (this.isDraggingPoint) {
|
|
234
|
-
// Call helper.onUp() to handle closing logic (like desktop)
|
|
235
|
-
this.interactionManager.interactionManagerHelper.onUp();
|
|
236
|
-
this.isDraggingPoint = false;
|
|
237
|
-
this.disableMobileCameraFreeze(); // Remove mobile camera freeze
|
|
238
|
-
// Camera freeze will be automatically removed by the interaction manager
|
|
239
|
-
}
|
|
240
|
-
const touchDuration = Date.now() - this.touchStartTime;
|
|
241
|
-
const touchDistance = this.getTouchDistance(event);
|
|
242
|
-
// Determine gesture type
|
|
243
|
-
if (this.isLongPress) {
|
|
244
|
-
return this.handleLongPress(event, ray);
|
|
245
|
-
}
|
|
246
|
-
if (touchDistance < this.config.touchSettings.tapThreshold) {
|
|
247
|
-
return this.handleTap(event, ray, touchDuration);
|
|
248
|
-
}
|
|
249
|
-
if (this.isDragging()) {
|
|
250
|
-
return this.handleDragEnd(event, ray);
|
|
251
|
-
}
|
|
252
|
-
// Clean up camera freeze if still active from point selection but no drag occurred
|
|
253
|
-
// (This handles cases where user touches a point but just taps without moving)
|
|
254
|
-
if (!this.isDraggingPoint) {
|
|
255
|
-
this.disableMobileCameraFreeze();
|
|
256
|
-
}
|
|
257
|
-
return { handled: true, action: IInteractionStrategy_1.InteractionAction.NONE };
|
|
258
|
-
}
|
|
259
|
-
onPointerOut() {
|
|
260
|
-
this.cancelLongPress();
|
|
261
|
-
// Clean up camera freeze if pointer leaves the area
|
|
262
|
-
this.disableMobileCameraFreeze();
|
|
263
|
-
return {
|
|
264
|
-
handled: true,
|
|
265
|
-
action: IInteractionStrategy_1.InteractionAction.NONE,
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
startLongPressDetection(event, ray) {
|
|
269
|
-
// Check if we're starting long press on a point
|
|
270
|
-
const distances = this.drawingToolsManager.geometryMathManager.checkPointDistances(ray, this.drawingToolsManager.positionArray);
|
|
271
|
-
const nearPoint = this.findNearestTouchTarget(distances);
|
|
272
|
-
this.longPressPoint = nearPoint; // Store the point for potential deletion
|
|
273
|
-
this.longPressTimer = window.setTimeout(() => {
|
|
274
|
-
this.isLongPress = true;
|
|
275
|
-
this.handleLongPressStart(event, ray);
|
|
276
|
-
}, this.config.touchSettings.longPressDuration);
|
|
277
|
-
}
|
|
278
|
-
cancelLongPress() {
|
|
279
|
-
if (this.longPressTimer) {
|
|
280
|
-
clearTimeout(this.longPressTimer);
|
|
281
|
-
this.longPressTimer = undefined;
|
|
282
|
-
}
|
|
283
|
-
this.longPressPoint = undefined; // Reset the long press point
|
|
284
|
-
}
|
|
285
|
-
isMultiTouch(event) {
|
|
286
|
-
// Check if there are multiple active pointers
|
|
287
|
-
// This would require tracking active pointers
|
|
288
|
-
return false; // Simplified for now
|
|
289
|
-
}
|
|
290
|
-
handleSingleTouch(event, ray) {
|
|
291
|
-
// Check if touching near a point for potential drag
|
|
292
|
-
const distances = this.drawingToolsManager.geometryMathManager.checkPointDistances(ray, this.drawingToolsManager.positionArray);
|
|
293
|
-
// Mobile-specific point selection with larger touch targets
|
|
294
|
-
const nearPoint = this.findNearestTouchTarget(distances);
|
|
295
|
-
if (nearPoint !== undefined) {
|
|
296
|
-
// Check if this is the first point and we can close
|
|
297
|
-
if (nearPoint === 0 && this.canCloseDrawing()) {
|
|
298
|
-
// Close the drawing by setting closeLoop and calling update
|
|
299
|
-
this.drawingToolsManager.geometryState.closeLoop = true;
|
|
300
|
-
// Emit GEOMETRY_CHANGED event for closing
|
|
301
|
-
viewer_shared_services_1.EventEngine.instance.emitEvent(viewer_shared_services_1.EVENTTYPE_DRAWING_TOOLS.GEOMETRY_CHANGED, {
|
|
302
|
-
viewportId: this.drawingToolsManager.viewport.id,
|
|
303
|
-
drawingToolId: this.drawingToolsManager.uuid,
|
|
304
|
-
points: this.drawingToolsManager.geometryState.getPointsData(),
|
|
305
|
-
temporary: false,
|
|
306
|
-
fromHistory: false,
|
|
307
|
-
});
|
|
308
|
-
this.disableMobileContinuousRendering();
|
|
309
|
-
this.disableMobileCameraFreeze(); // Clean up camera freeze since interaction is complete
|
|
310
|
-
this.drawingToolsManager.viewport.render(); // Force immediate render after closing
|
|
311
|
-
return {
|
|
312
|
-
handled: true,
|
|
313
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_END,
|
|
314
|
-
};
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
// Not first point or can't close, just select for interaction (drag/delete)
|
|
318
|
-
// Select the point but don't start dragging yet
|
|
319
|
-
// This allows taps and long press to still work
|
|
320
|
-
this.selectPointForInteraction(nearPoint, ray);
|
|
321
|
-
return {
|
|
322
|
-
handled: true,
|
|
323
|
-
action: IInteractionStrategy_1.InteractionAction.SELECT,
|
|
324
|
-
preventDefault: true,
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
return { handled: true, action: IInteractionStrategy_1.InteractionAction.NONE };
|
|
329
|
-
}
|
|
330
|
-
handleMultiTouch(event, ray) {
|
|
331
|
-
// Handle two-finger gestures for camera control or multi-select
|
|
332
|
-
return {
|
|
333
|
-
handled: true,
|
|
334
|
-
action: IInteractionStrategy_1.InteractionAction.NONE,
|
|
335
|
-
stopPropagation: true,
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
handleTap(event, ray, duration) {
|
|
339
|
-
const now = Date.now();
|
|
340
|
-
// Check for double tap
|
|
341
|
-
if (now - this.lastTapTime <
|
|
342
|
-
this.config.touchSettings.doubleTapInterval) {
|
|
343
|
-
this.tapCount++;
|
|
344
|
-
}
|
|
345
|
-
else {
|
|
346
|
-
this.tapCount = 1;
|
|
347
|
-
}
|
|
348
|
-
this.lastTapTime = now;
|
|
349
|
-
if (this.tapCount === 2) {
|
|
350
|
-
return this.handleDoubleTap(event, ray);
|
|
351
|
-
}
|
|
352
|
-
return this.handleSingleTap(event, ray);
|
|
353
|
-
}
|
|
354
|
-
handleSingleTap(event, ray) {
|
|
355
|
-
// Check if we're tapping on an existing point first
|
|
356
|
-
const distances = this.drawingToolsManager.geometryMathManager.checkPointDistances(ray, this.drawingToolsManager.positionArray);
|
|
357
|
-
const nearPoint = this.findNearestTouchTarget(distances);
|
|
358
|
-
// Get selected points from the touch down event
|
|
359
|
-
const selectedPoints = this.interactionManager.interactionManagerHelper
|
|
360
|
-
.selectedPointIndices;
|
|
361
|
-
// If we're in insertion mode and tapped on the first point, close the drawing
|
|
362
|
-
// Use nearPoint instead of selectedPoints since selectedPoints might be cleared
|
|
363
|
-
if (nearPoint !== undefined &&
|
|
364
|
-
nearPoint === 0 &&
|
|
365
|
-
this.interactionManager.insertionInteractionHandler
|
|
366
|
-
.insertionActive &&
|
|
367
|
-
this.canCloseDrawing()) {
|
|
368
|
-
// Close the drawing by tapping the first point
|
|
369
|
-
this.interactionManager.insertionInteractionHandler.stopInsertion();
|
|
370
|
-
this.drawingToolsManager.geometryState.closeLoop = true;
|
|
371
|
-
this.disableMobileContinuousRendering();
|
|
372
|
-
// Emit GEOMETRY_CHANGED event instead of calling update directly
|
|
373
|
-
viewer_shared_services_1.EventEngine.instance.emitEvent(viewer_shared_services_1.EVENTTYPE_DRAWING_TOOLS.GEOMETRY_CHANGED, {
|
|
374
|
-
viewportId: this.drawingToolsManager.viewport.id,
|
|
375
|
-
drawingToolId: this.drawingToolsManager.uuid,
|
|
376
|
-
points: this.drawingToolsManager.geometryState.getPointsData(),
|
|
377
|
-
temporary: false,
|
|
378
|
-
fromHistory: false,
|
|
379
|
-
});
|
|
380
|
-
this.drawingToolsManager.viewport.render(); // Force immediate render after closing
|
|
381
|
-
return {
|
|
382
|
-
handled: true,
|
|
383
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_END,
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
// Handle insertion finalization (mobile modification of desktop strategy)
|
|
387
|
-
// On mobile, we need to finalize points but keep insertion active for continuous drawing
|
|
388
|
-
if (this.interactionManager.insertionInteractionHandler.insertionActive) {
|
|
389
|
-
const result = this.interactionManager.insertionInteractionHandler.finalizeInsertion();
|
|
390
|
-
if (result) {
|
|
391
|
-
// Drawing was completed/closed
|
|
392
|
-
// Emit GEOMETRY_CHANGED event instead of calling update directly
|
|
393
|
-
viewer_shared_services_1.EventEngine.instance.emitEvent(viewer_shared_services_1.EVENTTYPE_DRAWING_TOOLS.GEOMETRY_CHANGED, {
|
|
394
|
-
viewportId: this.drawingToolsManager.viewport.id,
|
|
395
|
-
drawingToolId: this.drawingToolsManager.uuid,
|
|
396
|
-
points: this.drawingToolsManager.geometryState.getPointsData(),
|
|
397
|
-
temporary: false,
|
|
398
|
-
fromHistory: false,
|
|
399
|
-
});
|
|
400
|
-
this.disableMobileContinuousRendering();
|
|
401
|
-
this.drawingToolsManager.viewport.render(); // Force immediate render after closing
|
|
402
|
-
return {
|
|
403
|
-
handled: true,
|
|
404
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_END,
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
else {
|
|
408
|
-
// Point was added but drawing not complete
|
|
409
|
-
// On mobile: restart insertion immediately to keep continuous drawing
|
|
410
|
-
if (this.canInsertPoint()) {
|
|
411
|
-
try {
|
|
412
|
-
this.enableMobileContinuousRendering();
|
|
413
|
-
this.interactionManager.insertionInteractionHandler.startInsertion(event);
|
|
414
|
-
// Don't call update() here - let GEOMETRY_CHANGED events handle it
|
|
415
|
-
return {
|
|
416
|
-
handled: true,
|
|
417
|
-
action: IInteractionStrategy_1.InteractionAction.NONE, // Avoid triggering action system that might reset state
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
catch (error) {
|
|
421
|
-
console.warn("Failed to restart insertion:", error);
|
|
422
|
-
// Insertion restart failed, continue with fallback
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
else {
|
|
426
|
-
// Can't insert more points, stop insertion
|
|
427
|
-
this.disableMobileContinuousRendering();
|
|
428
|
-
return {
|
|
429
|
-
handled: true,
|
|
430
|
-
action: IInteractionStrategy_1.InteractionAction.NONE,
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
// Start insertion if not active (like desktop strategy) - but only if allowed
|
|
436
|
-
if (!this.interactionManager.insertionInteractionHandler
|
|
437
|
-
.insertionActive &&
|
|
438
|
-
this.canInsertPoint()) {
|
|
439
|
-
try {
|
|
440
|
-
this.enableMobileContinuousRendering();
|
|
441
|
-
this.interactionManager.insertionInteractionHandler.startInsertion(event);
|
|
442
|
-
this.drawingToolsManager.update();
|
|
443
|
-
return {
|
|
444
|
-
handled: true,
|
|
445
|
-
action: IInteractionStrategy_1.InteractionAction.NONE, // Avoid triggering action system that might reset state
|
|
446
|
-
};
|
|
447
|
-
}
|
|
448
|
-
catch (error) {
|
|
449
|
-
// Insertion failed, return default action
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
return { handled: true, action: IInteractionStrategy_1.InteractionAction.SELECT };
|
|
453
|
-
}
|
|
454
|
-
handleDoubleTap(event, ray) {
|
|
455
|
-
// Double tap for special actions like finishing insertion or deleting
|
|
456
|
-
this.tapCount = 0;
|
|
457
|
-
const distances = this.drawingToolsManager.geometryMathManager.checkPointDistances(ray, this.drawingToolsManager.positionArray);
|
|
458
|
-
const nearPoint = this.findNearestTouchTarget(distances);
|
|
459
|
-
if (nearPoint !== undefined) {
|
|
460
|
-
// Double tap on point could delete it
|
|
461
|
-
return this.handlePointDeletion(nearPoint);
|
|
462
|
-
}
|
|
463
|
-
// Double tap in empty space could finish current operation
|
|
464
|
-
if (this.interactionManager.insertionInteractionHandler.insertionActive) {
|
|
465
|
-
this.interactionManager.stopInsertion();
|
|
466
|
-
this.disableMobileContinuousRendering();
|
|
467
|
-
return {
|
|
468
|
-
handled: true,
|
|
469
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_END,
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
|
-
return { handled: true, action: IInteractionStrategy_1.InteractionAction.NONE };
|
|
473
|
-
}
|
|
474
|
-
handleLongPressStart(event, ray) {
|
|
475
|
-
// Long press could start context menu or multi-select mode
|
|
476
|
-
// Provide haptic feedback if available and enabled
|
|
477
|
-
this.triggerHapticFeedback();
|
|
478
|
-
}
|
|
479
|
-
handleLongPress(event, ray) {
|
|
480
|
-
// Long press actions - delete point if on existing point
|
|
481
|
-
this.triggerHapticFeedback();
|
|
482
|
-
// Check if we have a stored point from the long press start
|
|
483
|
-
if (this.longPressPoint !== undefined) {
|
|
484
|
-
// Delete the point by index directly to avoid ray precision issues
|
|
485
|
-
this.interactionManager.deletionInteractionHandler.deletePointByIndex(this.longPressPoint);
|
|
486
|
-
// Reset long press state
|
|
487
|
-
this.longPressPoint = undefined;
|
|
488
|
-
this.isLongPress = false;
|
|
489
|
-
// Remove camera freeze since long press interaction is complete
|
|
490
|
-
this.disableMobileCameraFreeze();
|
|
491
|
-
return {
|
|
492
|
-
handled: true,
|
|
493
|
-
action: IInteractionStrategy_1.InteractionAction.DELETE,
|
|
494
|
-
preventDefault: true,
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
|
-
// If no point to delete, remove camera freeze and return context menu action
|
|
498
|
-
this.disableMobileCameraFreeze();
|
|
499
|
-
return { handled: true, action: IInteractionStrategy_1.InteractionAction.CONTEXT_MENU };
|
|
500
|
-
}
|
|
501
|
-
triggerHapticFeedback() {
|
|
502
|
-
if (this.config.touchSettings.enableHapticFeedback &&
|
|
503
|
-
"vibrate" in navigator) {
|
|
504
|
-
navigator.vibrate(this.config.touchSettings.hapticPattern);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
handleTouchDrag(event, ray) {
|
|
508
|
-
// Touch drag for moving points - similar to mouse drag but with touch-specific behavior
|
|
509
|
-
this.moveDraggedPoints(ray);
|
|
510
|
-
return {
|
|
511
|
-
handled: true,
|
|
512
|
-
action: IInteractionStrategy_1.InteractionAction.DRAG_MOVE,
|
|
513
|
-
preventDefault: true,
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
handleInsertionMove(event, ray) {
|
|
517
|
-
// Handle moving insertion point on mobile
|
|
518
|
-
this.interactionManager.insertionInteractionHandler.onMove(ray);
|
|
519
|
-
return {
|
|
520
|
-
handled: true,
|
|
521
|
-
action: IInteractionStrategy_1.InteractionAction.INSERT_MOVE,
|
|
522
|
-
};
|
|
523
|
-
}
|
|
524
|
-
handleTouchHover(event, ray) {
|
|
525
|
-
// Mobile doesn't have true hover, but we can update visual feedback
|
|
526
|
-
return { handled: true, action: IInteractionStrategy_1.InteractionAction.HOVER };
|
|
527
|
-
}
|
|
528
|
-
handleDragEnd(event, ray) {
|
|
529
|
-
// End drag operation - the interaction manager will handle cleanup
|
|
530
|
-
return {
|
|
531
|
-
handled: true,
|
|
532
|
-
action: IInteractionStrategy_1.InteractionAction.DRAG_END,
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
handlePointDeletion(pointIndex) {
|
|
536
|
-
// Handle point deletion with confirmation or undo option
|
|
537
|
-
return {
|
|
538
|
-
handled: true,
|
|
539
|
-
action: IInteractionStrategy_1.InteractionAction.DELETE,
|
|
540
|
-
};
|
|
541
|
-
}
|
|
542
|
-
hasTouchMovedBeyondThreshold(event) {
|
|
543
|
-
const distance = this.getTouchDistance(event);
|
|
544
|
-
return distance > this.config.touchSettings.tapMovementThreshold;
|
|
545
|
-
}
|
|
546
|
-
getTouchDistance(event) {
|
|
547
|
-
const dx = event.clientX - this.touchStartPosition.x;
|
|
548
|
-
const dy = event.clientY - this.touchStartPosition.y;
|
|
549
|
-
return Math.sqrt(dx * dx + dy * dy);
|
|
550
|
-
}
|
|
551
|
-
findNearestTouchTarget(distances) {
|
|
552
|
-
// Find nearest point with larger touch target area for mobile
|
|
553
|
-
// Use a larger threshold for point selection to make it easier to grab points
|
|
554
|
-
const touchThreshold = this.config.touchSettings.minTouchTargetSize * 2; // Double the touch target for easier point selection
|
|
555
|
-
if (distances && distances.length > 0) {
|
|
556
|
-
// Find the closest point within the mobile touch threshold
|
|
557
|
-
for (let i = 0; i < distances.length; i++) {
|
|
558
|
-
if (distances[i] && distances[i].distance < touchThreshold) {
|
|
559
|
-
return distances[i].index; // Return the actual point index, not the array index
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
return undefined;
|
|
564
|
-
}
|
|
565
|
-
isDragging() {
|
|
566
|
-
return this.interactionManager.interactionManagerHelper.dragging;
|
|
567
|
-
}
|
|
568
|
-
selectPointForInteraction(pointIndex, ray) {
|
|
569
|
-
const helper = this.interactionManager.interactionManagerHelper;
|
|
570
|
-
// Just select the point for potential interaction, but don't start dragging
|
|
571
|
-
const distances = [{ index: pointIndex, distance: 0 }];
|
|
572
|
-
// Set the hovered point and select it
|
|
573
|
-
helper.checkHover(distances, ray);
|
|
574
|
-
helper.selectPoint(distances);
|
|
575
|
-
// Enable camera freeze immediately when touching a point since user might move it
|
|
576
|
-
this.enableMobileCameraFreeze();
|
|
577
|
-
// Don't start dragging here - that will happen on movement
|
|
578
|
-
}
|
|
579
|
-
moveDraggedPoints(ray) {
|
|
580
|
-
const helper = this.interactionManager.interactionManagerHelper;
|
|
581
|
-
helper.moveSelectedPoints(ray);
|
|
582
|
-
}
|
|
583
|
-
updateCursor() {
|
|
584
|
-
// Mobile devices don't typically show cursor changes, but we can update
|
|
585
|
-
// for hybrid devices (tablets with mouse support)
|
|
586
|
-
if (this.interactionManager.interactionManagerHelper.dragging) {
|
|
587
|
-
document.body.style.cursor = "grabbing";
|
|
588
|
-
}
|
|
589
|
-
else if (this.interactionManager.interactionManagerHelper.hoveredPoint !==
|
|
590
|
-
undefined) {
|
|
591
|
-
document.body.style.cursor = "pointer";
|
|
592
|
-
}
|
|
593
|
-
else {
|
|
594
|
-
document.body.style.cursor = "default";
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
/**
|
|
598
|
-
* Enable continuous rendering for mobile insertions to ensure immediate visual feedback
|
|
599
|
-
*/
|
|
600
|
-
enableMobileContinuousRendering() {
|
|
601
|
-
if (!this.mobileContinuousRenderingFlag) {
|
|
602
|
-
this.mobileContinuousRenderingFlag =
|
|
603
|
-
this.drawingToolsManager.viewport.addFlag(viewer_1.FLAG_TYPE.CONTINUOUS_RENDERING);
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
/**
|
|
607
|
-
* Disable continuous rendering for mobile insertions to save performance
|
|
608
|
-
*/
|
|
609
|
-
disableMobileContinuousRendering() {
|
|
610
|
-
if (this.mobileContinuousRenderingFlag) {
|
|
611
|
-
this.drawingToolsManager.viewport.removeFlag(this.mobileContinuousRenderingFlag);
|
|
612
|
-
this.mobileContinuousRenderingFlag = undefined;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
/**
|
|
616
|
-
* Check if the drawing can be closed (same logic as InsertionInteractionHandler)
|
|
617
|
-
*/
|
|
618
|
-
canCloseDrawing() {
|
|
619
|
-
const geometryState = this.drawingToolsManager.geometryState;
|
|
620
|
-
const settings = this.drawingToolsManager.settings;
|
|
621
|
-
const pointCount = geometryState.getPointCount();
|
|
622
|
-
// For closing, check current point count, not point count - 1
|
|
623
|
-
const checkNumberOfPointsResult = geometryState.checkNumberOfPoints(pointCount);
|
|
624
|
-
const canBeClosed = settings.geometry.mode === "lines" &&
|
|
625
|
-
pointCount > 3 &&
|
|
626
|
-
checkNumberOfPointsResult;
|
|
627
|
-
const shouldBeClosed = settings.geometry.close === true &&
|
|
628
|
-
geometryState.closeLoop === false &&
|
|
629
|
-
settings.geometry.autoClose === false;
|
|
630
|
-
return canBeClosed && shouldBeClosed;
|
|
631
|
-
}
|
|
632
|
-
/**
|
|
633
|
-
* Check if insertion should be allowed
|
|
634
|
-
* Returns false if drawing is closed or max points reached
|
|
635
|
-
*/
|
|
636
|
-
canInsertPoint() {
|
|
637
|
-
// Don't allow insertion if drawing tools manager is closed
|
|
638
|
-
if (this.drawingToolsManager.closed) {
|
|
639
|
-
return false;
|
|
640
|
-
}
|
|
641
|
-
// Don't allow insertion if the loop is already closed
|
|
642
|
-
if (this.drawingToolsManager.geometryState.closeLoop) {
|
|
643
|
-
return false;
|
|
644
|
-
}
|
|
645
|
-
// Don't allow insertion if we can't add more points (max points reached)
|
|
646
|
-
if (!this.drawingToolsManager.geometryManager.canAddPoint()) {
|
|
647
|
-
return false;
|
|
648
|
-
}
|
|
649
|
-
return true;
|
|
650
|
-
}
|
|
651
|
-
/**
|
|
652
|
-
* Enable camera freeze for mobile point dragging
|
|
653
|
-
*/
|
|
654
|
-
enableMobileCameraFreeze() {
|
|
655
|
-
if (!this.mobileCameraFreezeFlag) {
|
|
656
|
-
this.mobileCameraFreezeFlag =
|
|
657
|
-
this.drawingToolsManager.viewport.addFlag(viewer_1.FLAG_TYPE.CAMERA_FREEZE);
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* Disable camera freeze for mobile point dragging
|
|
662
|
-
*/
|
|
663
|
-
disableMobileCameraFreeze() {
|
|
664
|
-
if (this.mobileCameraFreezeFlag) {
|
|
665
|
-
this.drawingToolsManager.viewport.removeFlag(this.mobileCameraFreezeFlag);
|
|
666
|
-
this.mobileCameraFreezeFlag = undefined;
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
exports.MobileInteractionStrategy = MobileInteractionStrategy;
|
|
671
|
-
//# sourceMappingURL=MobileInteractionStrategy.js.map
|