Skip to content

Commit b3fade5

Browse files
authored
Merge pull request #2431 from Kitware/pointer-events
Use pointer events (and pointer capture)
2 parents ac41cd0 + 2ec8c34 commit b3fade5

File tree

3 files changed

+314
-197
lines changed

3 files changed

+314
-197
lines changed

Examples/Rendering/ManyRenderers/index.js

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'vtk.js/Sources/favicon';
22

33
// Load the rendering pieces we want to use (for both WebGL and WebGPU)
44
import 'vtk.js/Sources/Rendering/Profiles/Geometry';
5+
import 'vtk.js/Sources/Rendering/Misc/RenderingAPIs';
56

67
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
78
import vtkConeSource from 'vtk.js/Sources/Filters/Sources/ConeSource';
@@ -14,8 +15,6 @@ import vtkRenderWindowInteractor from 'vtk.js/Sources/Rendering/Core/RenderWindo
1415
import vtkRenderer from 'vtk.js/Sources/Rendering/Core/Renderer';
1516
import vtkInteractorStyleTrackballCamera from 'vtk.js/Sources/Interaction/Style/InteractorStyleTrackballCamera';
1617

17-
import vtkOpenGLRenderWindow from 'vtk.js/Sources/Rendering/OpenGL/RenderWindow';
18-
1918
// ----------------------------------------------------------------------------
2019
// Meshes
2120
// ----------------------------------------------------------------------------
@@ -85,8 +84,8 @@ const colors = [
8584
const RENDERERS = {};
8685

8786
const renderWindow = vtkRenderWindow.newInstance();
88-
const openglRenderWindow = vtkOpenGLRenderWindow.newInstance();
89-
renderWindow.addView(openglRenderWindow);
87+
const renderWindowView = renderWindow.newAPISpecificView();
88+
renderWindow.addView(renderWindowView);
9089

9190
const rootContainer = document.createElement('div');
9291
rootContainer.style.position = 'fixed';
@@ -96,12 +95,11 @@ rootContainer.style.top = 0;
9695
rootContainer.style.pointerEvents = 'none';
9796
document.body.appendChild(rootContainer);
9897

99-
openglRenderWindow.setContainer(rootContainer);
98+
renderWindowView.setContainer(rootContainer);
10099

101100
const interactor = vtkRenderWindowInteractor.newInstance();
102-
interactor.setView(openglRenderWindow);
101+
interactor.setView(renderWindowView);
103102
interactor.initialize();
104-
interactor.bindEvents(document.body);
105103
interactor.setInteractorStyle(vtkInteractorStyleTrackballCamera.newInstance());
106104

107105
function updateViewPort(element, renderer) {
@@ -129,12 +127,11 @@ function recomputeViewports() {
129127

130128
function resize() {
131129
rootContainer.style.width = `${window.innerWidth}px`;
132-
openglRenderWindow.setSize(window.innerWidth, window.innerHeight);
130+
renderWindowView.setSize(window.innerWidth, window.innerHeight);
133131
recomputeViewports();
134-
// Object.values(RENDERERS).forEach((r) => r.resetCamera());
135132
}
136133

137-
window.addEventListener('resize', resize);
134+
new ResizeObserver(resize).observe(document.body);
138135
document.addEventListener('scroll', recomputeViewports);
139136

140137
// ----------------------------------------------------------------------------
@@ -155,15 +152,36 @@ function applyStyle(element) {
155152
element.style.display = 'inline-block';
156153
element.style.boxSizing = 'border';
157154
element.style.textAlign = 'center';
155+
element.style.color = 'white';
158156
return element;
159157
}
160158

161-
function enterCurrentRenderer(e) {
162-
interactor.setCurrentRenderer(RENDERERS[e.target.id]);
159+
let captureCurrentRenderer = false;
160+
161+
function setCaptureCurrentRenderer(yn) {
162+
captureCurrentRenderer = yn;
163+
if (yn && interactor.getCurrentRenderer()) {
164+
// fix the current renderer to, well, the current renderer
165+
interactor.setCurrentRenderer(interactor.getCurrentRenderer());
166+
} else {
167+
// remove the fixed current renderer
168+
interactor.setCurrentRenderer(null);
169+
}
163170
}
164171

165-
function exitCurrentRenderer(e) {
166-
interactor.setCurrentRenderer(null);
172+
function bindInteractor(renderer, el) {
173+
// only change the interactor's container if needed
174+
if (interactor.getContainer() !== el) {
175+
if (interactor.getContainer()) {
176+
interactor.unbindEvents();
177+
}
178+
if (captureCurrentRenderer) {
179+
interactor.setCurrentRenderer(renderer);
180+
}
181+
if (el) {
182+
interactor.bindEvents(el);
183+
}
184+
}
167185
}
168186

169187
function addRenderer() {
@@ -188,8 +206,10 @@ function addRenderer() {
188206
const renderer = vtkRenderer.newInstance({ background });
189207
container.innerHTML = `${mesh.name} ${prop.name}`;
190208

191-
container.addEventListener('mouseenter', enterCurrentRenderer);
192-
container.addEventListener('mouseleave', exitCurrentRenderer);
209+
container.addEventListener('pointerenter', () =>
210+
bindInteractor(renderer, container)
211+
);
212+
container.addEventListener('pointerleave', () => bindInteractor(null, null));
193213

194214
renderer.addActor(actor);
195215
renderWindow.addRenderer(renderer);
@@ -204,14 +224,29 @@ function addRenderer() {
204224
// Fill up page
205225
// ----------------------------------------------------------------------------
206226

227+
const checkbox = document.createElement('input');
228+
checkbox.type = 'checkbox';
229+
checkbox.name = 'singleRendererCapture';
230+
const label = document.createElement('label');
231+
label.for = checkbox.name;
232+
label.innerText = 'Enable single renderer capture';
233+
234+
checkbox.addEventListener('input', (ev) => {
235+
setCaptureCurrentRenderer(ev.target.checked);
236+
});
237+
238+
document.body.appendChild(checkbox);
239+
document.body.appendChild(label);
240+
document.body.appendChild(document.createElement('br'));
241+
207242
for (let i = 0; i < 64; i++) {
208243
addRenderer();
209244
}
210245
resize();
211246

212247
function updateCamera(renderer) {
213248
const camera = renderer.getActiveCamera();
214-
camera.azimuth(2);
249+
camera.azimuth(0.5);
215250
renderer.resetCameraClippingRange();
216251
}
217252

@@ -228,5 +263,5 @@ window.requestAnimationFrame(animate);
228263
// ----------------------------------------------------------------------------
229264

230265
global.rw = renderWindow;
231-
global.glrw = openglRenderWindow;
266+
global.glrw = renderWindowView;
232267
global.renderers = RENDERERS;

Sources/Rendering/Core/RenderWindowInteractor/index.d.ts

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,16 @@ export interface vtkRenderWindowInteractor extends vtkObject {
173173
*
174174
* @param {IRenderWindowInteractorEvent} callData
175175
*/
176+
invokePointerEnter(callData: IRenderWindowInteractorEvent): void;
177+
178+
/**
179+
*
180+
*/
181+
invokePointerLeave(callData: IRenderWindowInteractorEvent): void;
182+
183+
/**
184+
*
185+
*/
176186
invokeMouseEnter(callData: IRenderWindowInteractorEvent): void;
177187

178188
/**
@@ -392,6 +402,18 @@ export interface vtkRenderWindowInteractor extends vtkObject {
392402
* @param {InteractorEventCallback} cb The callback to be called.
393403
* @param {Number} [priority] The priority of the event.
394404
*/
405+
onPointerEnter(cb: InteractorEventCallback, priority?: number): Readonly<vtkSubscription>;
406+
407+
/**
408+
*
409+
* @param cb The callback to be called
410+
*/
411+
onPointerLeave(cb: InteractorEventCallback, priority?: number): Readonly<vtkSubscription>;
412+
413+
/**
414+
*
415+
* @param cb The callback to be called
416+
*/
395417
onMouseEnter(cb: InteractorEventCallback, priority?: number): Readonly<vtkSubscription>;
396418

397419
/**
@@ -949,11 +971,35 @@ export interface vtkRenderWindowInteractor extends vtkObject {
949971
*/
950972
handleKeyUp(event: KeyboardEvent): void;
951973

974+
/**
975+
*
976+
* @param {PointerEvent} event
977+
*/
978+
handlePointerDown(event: PointerEvent): void;
979+
980+
/**
981+
*
982+
* @param {PointerEvent} event
983+
*/
984+
handlePointerUp(event: PointerEvent): void;
985+
986+
/**
987+
*
988+
* @param {PointerEvent} event
989+
*/
990+
handlePointerCancel(event: PointerEvent): void;
991+
992+
/**
993+
*
994+
* @param {PointerEvent} event
995+
*/
996+
handlePointerMove(event: PointerEvent): void;
997+
952998
/**
953999
*
954-
* @param {MouseEvent} event
1000+
* @param {PointerEvent} event
9551001
*/
956-
handleMouseDown(event: MouseEvent): void;
1002+
handleMouseDown(event: PointerEvent): void;
9571003

9581004
/**
9591005
*
@@ -1011,9 +1057,9 @@ export interface vtkRenderWindowInteractor extends vtkObject {
10111057

10121058
/**
10131059
*
1014-
* @param {MouseEvent} event
1060+
* @param {PointerEvent} event
10151061
*/
1016-
handleMouseMove(event: MouseEvent): void;
1062+
handleMouseMove(event: PointerEvent): void;
10171063

10181064
/**
10191065
*
@@ -1028,39 +1074,39 @@ export interface vtkRenderWindowInteractor extends vtkObject {
10281074

10291075
/**
10301076
*
1031-
* @param {MouseEvent} event
1077+
* @param {PointerEvent} event
10321078
*/
1033-
handleMouseEnter(event: MouseEvent): void;
1079+
handlePointerEnter(event: PointerEvent): void;
10341080

10351081
/**
10361082
*
1037-
* @param {MouseEvent} event
1083+
* @param {PointerEvent} event
10381084
*/
1039-
handleMouseLeave(event: MouseEvent): void;
1085+
handlePointerLeave(event: PointerEvent): void;
10401086

10411087
/**
10421088
*
1043-
* @param {MouseEvent} event
1089+
* @param {PointerEvent} event
10441090
*/
1045-
handleMouseUp(event: MouseEvent): void;
1091+
handleMouseUp(event: PointerEvent): void;
10461092

10471093
/**
10481094
*
1049-
* @param {TouchEvent} event
1095+
* @param {PointerEvent} event
10501096
*/
1051-
handleTouchStart(event: TouchEvent): void;
1097+
handleTouchStart(event: PointerEvent): void;
10521098

10531099
/**
10541100
*
1055-
* @param {TouchEvent} event
1101+
* @param {PointerEvent} event
10561102
*/
1057-
handleTouchMove(event: TouchEvent): void;
1103+
handleTouchMove(event: PointerEvent): void;
10581104

10591105
/**
10601106
*
1061-
* @param {TouchEvent} event
1107+
* @param {PointerEvent} event
10621108
*/
1063-
handleTouchEnd(event: TouchEvent): void;
1109+
handleTouchEnd(event: PointerEvent): void;
10641110

10651111
/**
10661112
*
@@ -1093,7 +1139,7 @@ export interface vtkRenderWindowInteractor extends vtkObject {
10931139
* @param event
10941140
* @param positions
10951141
*/
1096-
recognizeGesture(event: 'TouchStart' | 'TouchMouve' | 'TouchEnd', positions: IPosition): void;
1142+
recognizeGesture(event: 'TouchStart' | 'TouchMove' | 'TouchEnd', positions: IPosition): void;
10971143

10981144
/**
10991145
*

0 commit comments

Comments
 (0)