@kitware/vtk.js 29.4.4 → 29.4.6
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/Rendering/Core/RenderWindowInteractor.d.ts +12 -2
- package/Rendering/Core/RenderWindowInteractor.js +62 -22
- package/Widgets/Manipulators/LineManipulator.js +7 -1
- package/Widgets/Manipulators/PickerManipulator.js +4 -2
- package/Widgets/Widgets3D/PaintWidget/behavior.js +16 -4
- package/Widgets/Widgets3D/SeedWidget/behavior.js +6 -4
- package/package.json +1 -1
|
@@ -93,7 +93,7 @@ export interface vtkRenderWindowInteractor extends vtkObject {
|
|
|
93
93
|
*
|
|
94
94
|
* @default null
|
|
95
95
|
*/
|
|
96
|
-
getContainer(): HTMLElement
|
|
96
|
+
getContainer(): Nullable<HTMLElement>;
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
99
|
*
|
|
@@ -827,6 +827,13 @@ export interface vtkRenderWindowInteractor extends vtkObject {
|
|
|
827
827
|
*/
|
|
828
828
|
rotateEvent(args: any): any;
|
|
829
829
|
|
|
830
|
+
/**
|
|
831
|
+
* Add an HTMLElement as the new container for the interactor.
|
|
832
|
+
* All events will be bound to this new container.
|
|
833
|
+
* Any old container will be removed along with its listeners.
|
|
834
|
+
*/
|
|
835
|
+
setContainer(container: Nullable<HTMLElement>): boolean;
|
|
836
|
+
|
|
830
837
|
/**
|
|
831
838
|
* Turn on/off the automatic repositioning of lights as the camera moves.
|
|
832
839
|
* @param lightFollowCamera
|
|
@@ -992,12 +999,15 @@ export interface vtkRenderWindowInteractor extends vtkObject {
|
|
|
992
999
|
|
|
993
1000
|
/**
|
|
994
1001
|
*
|
|
995
|
-
* @param container
|
|
1002
|
+
* @param container kept for backward compatibility.
|
|
1003
|
+
* @deprecated please use vtkRenderWindowInteractor.setContainer(container: HTMLElement)
|
|
1004
|
+
* which will also bind events.
|
|
996
1005
|
*/
|
|
997
1006
|
bindEvents(container: any): void;
|
|
998
1007
|
|
|
999
1008
|
/**
|
|
1000
1009
|
*
|
|
1010
|
+
* @deprecated please use vtkRenderWindowInteractor.setContainer(null) instead.
|
|
1001
1011
|
*/
|
|
1002
1012
|
unbindEvents(): void;
|
|
1003
1013
|
|
|
@@ -51,6 +51,11 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
51
51
|
// Set our className
|
|
52
52
|
model.classHierarchy.push('vtkRenderWindowInteractor');
|
|
53
53
|
|
|
54
|
+
// Capture "parentClass" api for internal use
|
|
55
|
+
const superClass = {
|
|
56
|
+
...publicAPI
|
|
57
|
+
};
|
|
58
|
+
|
|
54
59
|
// Initialize list of requesters
|
|
55
60
|
const animationRequesters = new Set();
|
|
56
61
|
|
|
@@ -161,8 +166,13 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
161
166
|
function getDeviceTypeFor(event) {
|
|
162
167
|
return event.pointerType || '';
|
|
163
168
|
}
|
|
164
|
-
|
|
165
|
-
model.container
|
|
169
|
+
const _bindEvents = () => {
|
|
170
|
+
if (model.container === null) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const {
|
|
174
|
+
container
|
|
175
|
+
} = model;
|
|
166
176
|
container.addEventListener('contextmenu', preventDefault);
|
|
167
177
|
container.addEventListener('wheel', publicAPI.handleWheel);
|
|
168
178
|
container.addEventListener('DOMMouseScroll', publicAPI.handleWheel);
|
|
@@ -188,30 +198,53 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
188
198
|
// disables tap highlight for when cursor is pointer
|
|
189
199
|
container.style.webkitTapHighlightColor = 'rgba(0,0,0,0)';
|
|
190
200
|
};
|
|
191
|
-
|
|
201
|
+
|
|
202
|
+
// For backward compatibility.
|
|
203
|
+
// Necessary for using unbind/bindEvent without calling setContainer.
|
|
204
|
+
publicAPI.bindEvents = container => {
|
|
205
|
+
if (container === null) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const res = superClass.setContainer(container);
|
|
209
|
+
if (res) {
|
|
210
|
+
_bindEvents();
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const _unbindEvents = () => {
|
|
214
|
+
// Clear any previous timeouts and state variables that control mouse / touchpad behavior.
|
|
215
|
+
clearTimeout(model.moveTimeoutID);
|
|
216
|
+
clearTimeout(model.wheelTimeoutID);
|
|
217
|
+
model.moveTimeoutID = 0;
|
|
218
|
+
model.wheelTimeoutID = 0;
|
|
219
|
+
wheelCoefficient = 1.0;
|
|
192
220
|
const {
|
|
193
221
|
container
|
|
194
222
|
} = model;
|
|
195
|
-
container
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
223
|
+
if (container) {
|
|
224
|
+
container.removeEventListener('contextmenu', preventDefault);
|
|
225
|
+
container.removeEventListener('wheel', publicAPI.handleWheel);
|
|
226
|
+
container.removeEventListener('DOMMouseScroll', publicAPI.handleWheel);
|
|
227
|
+
container.removeEventListener('pointerenter', publicAPI.handlePointerEnter);
|
|
228
|
+
container.removeEventListener('pointerleave', publicAPI.handlePointerLeave);
|
|
229
|
+
container.removeEventListener('pointermove', publicAPI.handlePointerMove, {
|
|
230
|
+
passive: false
|
|
231
|
+
});
|
|
232
|
+
container.removeEventListener('pointerdown', publicAPI.handlePointerDown, {
|
|
233
|
+
passive: false
|
|
234
|
+
});
|
|
235
|
+
container.removeEventListener('pointerup', publicAPI.handlePointerUp);
|
|
236
|
+
container.removeEventListener('pointercancel', publicAPI.handlePointerCancel);
|
|
237
|
+
}
|
|
208
238
|
document.removeEventListener('keypress', publicAPI.handleKeyPress);
|
|
209
239
|
document.removeEventListener('keydown', publicAPI.handleKeyDown);
|
|
210
240
|
document.removeEventListener('keyup', publicAPI.handleKeyUp);
|
|
211
241
|
document.removeEventListener('pointerlockchange', publicAPI.handlePointerLockChange);
|
|
212
|
-
model.container = null;
|
|
213
242
|
pointerCache.clear();
|
|
214
243
|
};
|
|
244
|
+
publicAPI.unbindEvents = () => {
|
|
245
|
+
_unbindEvents();
|
|
246
|
+
superClass.setContainer(null);
|
|
247
|
+
};
|
|
215
248
|
publicAPI.handleKeyPress = event => {
|
|
216
249
|
const data = getKeysFor(event);
|
|
217
250
|
publicAPI.keyPressEvent(data);
|
|
@@ -947,9 +980,16 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
947
980
|
model._forcedRenderer = !!r;
|
|
948
981
|
model.currentRenderer = r;
|
|
949
982
|
};
|
|
983
|
+
publicAPI.setContainer = container => {
|
|
984
|
+
_unbindEvents();
|
|
985
|
+
const res = superClass.setContainer(container ?? null);
|
|
986
|
+
if (res) {
|
|
987
|
+
_bindEvents();
|
|
988
|
+
}
|
|
989
|
+
return res;
|
|
990
|
+
};
|
|
950
991
|
|
|
951
992
|
// Stop animating if the renderWindowInteractor is deleted.
|
|
952
|
-
const superDelete = publicAPI.delete;
|
|
953
993
|
publicAPI.delete = () => {
|
|
954
994
|
while (animationRequesters.size) {
|
|
955
995
|
publicAPI.cancelAnimation(animationRequesters.values().next().value);
|
|
@@ -958,9 +998,9 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
958
998
|
document.removeEventListener('visibilitychange', publicAPI.handleVisibilityChange);
|
|
959
999
|
}
|
|
960
1000
|
if (model.container) {
|
|
961
|
-
publicAPI.
|
|
1001
|
+
publicAPI.setContainer(null);
|
|
962
1002
|
}
|
|
963
|
-
|
|
1003
|
+
superClass.delete();
|
|
964
1004
|
};
|
|
965
1005
|
|
|
966
1006
|
// Use the Page Visibility API to detect when we switch away from or back to
|
|
@@ -1017,10 +1057,10 @@ function extend(publicAPI, model) {
|
|
|
1017
1057
|
handledEvents.forEach(eventName => macro.event(publicAPI, model, eventName));
|
|
1018
1058
|
|
|
1019
1059
|
// Create get-only macros
|
|
1020
|
-
macro.get(publicAPI, model, ['initialized', '
|
|
1060
|
+
macro.get(publicAPI, model, ['initialized', 'interactorStyle', 'lastFrameTime', 'recentAnimationFrameRate', '_view']);
|
|
1021
1061
|
|
|
1022
1062
|
// Create get-set macros
|
|
1023
|
-
macro.setGet(publicAPI, model, ['lightFollowCamera', 'enabled', 'enableRender', 'recognizeGestures', 'desiredUpdateRate', 'stillUpdateRate', 'picker', 'preventDefaultOnPointerDown', 'preventDefaultOnPointerUp', 'mouseScrollDebounceByPass']);
|
|
1063
|
+
macro.setGet(publicAPI, model, ['container', 'lightFollowCamera', 'enabled', 'enableRender', 'recognizeGestures', 'desiredUpdateRate', 'stillUpdateRate', 'picker', 'preventDefaultOnPointerDown', 'preventDefaultOnPointerUp', 'mouseScrollDebounceByPass']);
|
|
1024
1064
|
macro.moveToProtected(publicAPI, model, ['view']);
|
|
1025
1065
|
|
|
1026
1066
|
// For more macro methods, see "Sources/macros.js"
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { m as macro } from '../../macros2.js';
|
|
2
|
-
import {
|
|
2
|
+
import { d as dot, s as subtract, j as cross, w as multiplyScalar, k as add } from '../../Common/Core/Math/index.js';
|
|
3
3
|
import vtkAbstractManipulator from './AbstractManipulator.js';
|
|
4
|
+
import { EPSILON } from '../../Common/Core/Math/Constants.js';
|
|
4
5
|
|
|
5
6
|
function projectDisplayToLine(x, y, lineOrigin, lineDirection, renderer, glRenderWindow) {
|
|
7
|
+
// if the active camera viewPlaneNormal and line direction are parallel, no change is allowed
|
|
8
|
+
const dotProduct = Math.abs(dot(renderer.getActiveCamera().getViewPlaneNormal(), lineDirection));
|
|
9
|
+
if (1 - dotProduct < EPSILON) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
6
12
|
const near = glRenderWindow.displayToWorld(x, y, 0, renderer);
|
|
7
13
|
const far = glRenderWindow.displayToWorld(x, y, 1, renderer);
|
|
8
14
|
const viewDir = [0, 0, 0];
|
|
@@ -15,11 +15,13 @@ function vtkPickerManipulator(publicAPI, model) {
|
|
|
15
15
|
pokedRenderer
|
|
16
16
|
} = callData;
|
|
17
17
|
model.picker.pick([position.x, position.y, 0.0], pokedRenderer);
|
|
18
|
-
if (model.picker.
|
|
18
|
+
if (model.picker.getPickedPositions().length > 0) {
|
|
19
19
|
model.position = model.picker.getPickedPositions()[0];
|
|
20
|
+
} else {
|
|
21
|
+
model.position = null;
|
|
20
22
|
}
|
|
21
23
|
return {
|
|
22
|
-
worldCoords: model.position
|
|
24
|
+
worldCoords: model.position
|
|
23
25
|
};
|
|
24
26
|
};
|
|
25
27
|
}
|
|
@@ -3,8 +3,17 @@ import { vec3 } from 'gl-matrix';
|
|
|
3
3
|
|
|
4
4
|
function widgetBehavior(publicAPI, model) {
|
|
5
5
|
model.painting = model._factory.getPainting();
|
|
6
|
-
publicAPI.handleLeftButtonPress =
|
|
7
|
-
|
|
6
|
+
publicAPI.handleLeftButtonPress = callData => {
|
|
7
|
+
const manipulator = model.activeState?.getManipulator?.() ?? model.manipulator;
|
|
8
|
+
if (!(manipulator && model.activeState && model.activeState.getActive())) {
|
|
9
|
+
model.painting = false;
|
|
10
|
+
return macro.VOID;
|
|
11
|
+
}
|
|
12
|
+
const {
|
|
13
|
+
worldCoords
|
|
14
|
+
} = manipulator.handleEvent(callData, model._apiSpecificRenderWindow);
|
|
15
|
+
if (!worldCoords?.length) {
|
|
16
|
+
model.painting = false;
|
|
8
17
|
return macro.VOID;
|
|
9
18
|
}
|
|
10
19
|
model.painting = true;
|
|
@@ -20,11 +29,12 @@ function widgetBehavior(publicAPI, model) {
|
|
|
20
29
|
model.widgetState.clearTrailList();
|
|
21
30
|
}
|
|
22
31
|
model.painting = false;
|
|
23
|
-
return
|
|
32
|
+
return macro.VOID;
|
|
24
33
|
};
|
|
25
34
|
publicAPI.handleEvent = callData => {
|
|
26
35
|
const manipulator = model.activeState?.getManipulator?.() ?? model.manipulator;
|
|
27
36
|
if (!(manipulator && model.activeState && model.activeState.getActive())) {
|
|
37
|
+
model.painting = false;
|
|
28
38
|
return macro.VOID;
|
|
29
39
|
}
|
|
30
40
|
const normal = model._camera.getDirectionOfProjection();
|
|
@@ -37,7 +47,7 @@ function widgetBehavior(publicAPI, model) {
|
|
|
37
47
|
const {
|
|
38
48
|
worldCoords
|
|
39
49
|
} = manipulator.handleEvent(callData, model._apiSpecificRenderWindow);
|
|
40
|
-
if (!worldCoords
|
|
50
|
+
if (!worldCoords?.length) {
|
|
41
51
|
return macro.VOID;
|
|
42
52
|
}
|
|
43
53
|
model.widgetState.setTrueOrigin(...worldCoords);
|
|
@@ -45,6 +55,8 @@ function widgetBehavior(publicAPI, model) {
|
|
|
45
55
|
if (model.painting) {
|
|
46
56
|
const trailCircle = model.widgetState.addTrail();
|
|
47
57
|
trailCircle.set(model.activeState.get('origin', 'up', 'right', 'direction', 'scale1'));
|
|
58
|
+
} else {
|
|
59
|
+
return macro.VOID;
|
|
48
60
|
}
|
|
49
61
|
publicAPI.invokeInteractionEvent();
|
|
50
62
|
return macro.EVENT_ABORT;
|
|
@@ -30,13 +30,13 @@ function widgetBehavior(publicAPI, model) {
|
|
|
30
30
|
}
|
|
31
31
|
const worldCoords = currentWorldCoords(e);
|
|
32
32
|
if (model.activeState === moveHandle) {
|
|
33
|
-
if (!moveHandle.getOrigin()) {
|
|
33
|
+
if (!moveHandle.getOrigin() && worldCoords) {
|
|
34
34
|
moveHandle.setOrigin(worldCoords);
|
|
35
|
+
model.previousPosition = [...worldCoords];
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
model._isDragging = true;
|
|
38
39
|
model._apiSpecificRenderWindow.setCursor('grabbing');
|
|
39
|
-
model.previousPosition = [...currentWorldCoords(e)];
|
|
40
40
|
publicAPI.invokeStartInteractionEvent();
|
|
41
41
|
return macro.EVENT_ABORT;
|
|
42
42
|
};
|
|
@@ -63,8 +63,10 @@ function widgetBehavior(publicAPI, model) {
|
|
|
63
63
|
}
|
|
64
64
|
if (!model.activeState) throw Error('no activestate');
|
|
65
65
|
const worldCoords = currentWorldCoords(e);
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
if (worldCoords) {
|
|
67
|
+
model.activeState.setOrigin(worldCoords);
|
|
68
|
+
model.previousPosition = worldCoords;
|
|
69
|
+
}
|
|
68
70
|
return macro.VOID;
|
|
69
71
|
};
|
|
70
72
|
publicAPI.grabFocus = () => {
|