/
index.js
130 lines (106 loc) · 4.05 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import macro from 'vtk.js/Sources/macros';
import vtkRenderer from 'vtk.js/Sources/Rendering/Core/Renderer';
import vtkRenderWindow from 'vtk.js/Sources/Rendering/Core/RenderWindow';
import vtkRenderWindowInteractor from 'vtk.js/Sources/Rendering/Core/RenderWindowInteractor';
import vtkInteractorStyleTrackballCamera from 'vtk.js/Sources/Interaction/Style/InteractorStyleTrackballCamera';
import vtkURLExtract from 'vtk.js/Sources/Common/Core/URLExtract';
// Load basic classes for vtk() factory
import 'vtk.js/Sources/Common/Core/Points';
import 'vtk.js/Sources/Common/Core/DataArray';
import 'vtk.js/Sources/Common/DataModel/PolyData';
import 'vtk.js/Sources/Rendering/Core/Actor';
import 'vtk.js/Sources/Rendering/Core/Mapper';
import 'vtk.js/Sources/Rendering/Misc/RenderingAPIs';
// Process arguments from URL
const userParams = vtkURLExtract.extractURLParameters();
function vtkGenericRenderWindow(publicAPI, model) {
// Capture resize trigger method to remove from publicAPI
const invokeResize = publicAPI.invokeResize;
delete publicAPI.invokeResize;
// VTK renderWindow/renderer
model.renderWindow = vtkRenderWindow.newInstance();
model.renderer = vtkRenderer.newInstance();
model.renderWindow.addRenderer(model.renderer);
// OpenGLRenderWindow
model._apiSpecificRenderWindow = model.renderWindow.newAPISpecificView(
userParams.viewAPI ?? model.defaultViewAPI
);
model.renderWindow.addView(model._apiSpecificRenderWindow);
// Interactor
model.interactor = vtkRenderWindowInteractor.newInstance();
model.interactor.setInteractorStyle(
vtkInteractorStyleTrackballCamera.newInstance()
);
model.interactor.setView(model._apiSpecificRenderWindow);
model.interactor.initialize();
// Expose background
publicAPI.setBackground = model.renderer.setBackground;
// Update BG color
publicAPI.setBackground(...model.background);
// Handle window resize
publicAPI.resize = () => {
if (model.container) {
const dims = model.container.getBoundingClientRect();
const devicePixelRatio = window.devicePixelRatio || 1;
model._apiSpecificRenderWindow.setSize(
Math.floor(dims.width * devicePixelRatio),
Math.floor(dims.height * devicePixelRatio)
);
invokeResize();
model.renderWindow.render();
}
};
// Handle DOM container relocation
publicAPI.setContainer = (el) => {
if (model.container) {
model.interactor.unbindEvents(model.container);
}
// Switch container
model.container = el;
model._apiSpecificRenderWindow.setContainer(model.container);
// Bind to new container
if (model.container) {
model.interactor.bindEvents(model.container);
}
};
// Properly release GL context
publicAPI.delete = macro.chain(
publicAPI.setContainer,
model._apiSpecificRenderWindow.delete,
publicAPI.delete
);
// Handle size
if (model.listenWindowResize) {
window.addEventListener('resize', publicAPI.resize);
}
publicAPI.resize();
}
// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
const DEFAULT_VALUES = {
background: [0.32, 0.34, 0.43],
listenWindowResize: true,
container: null,
};
// ----------------------------------------------------------------------------
export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);
// Object methods
macro.obj(publicAPI, model);
macro.get(publicAPI, model, [
'renderWindow',
'renderer',
'_apiSpecificRenderWindow',
'interactor',
'container',
]);
macro.moveToProtected(publicAPI, model, ['_apiSpecificRenderWindow']);
macro.event(publicAPI, model, 'resize');
// Object specific methods
vtkGenericRenderWindow(publicAPI, model);
}
// ----------------------------------------------------------------------------
export const newInstance = macro.newInstance(extend);
// ----------------------------------------------------------------------------
export default { newInstance, extend };