@aics/vole-core 3.12.4

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.
Files changed (141) hide show
  1. package/LICENSE.txt +26 -0
  2. package/README.md +119 -0
  3. package/es/Atlas2DSlice.js +224 -0
  4. package/es/Channel.js +264 -0
  5. package/es/FileSaver.js +31 -0
  6. package/es/FusedChannelData.js +192 -0
  7. package/es/Histogram.js +250 -0
  8. package/es/ImageInfo.js +127 -0
  9. package/es/Light.js +74 -0
  10. package/es/Lut.js +500 -0
  11. package/es/MarchingCubes.js +507 -0
  12. package/es/MeshVolume.js +334 -0
  13. package/es/NaiveSurfaceNets.js +251 -0
  14. package/es/PathTracedVolume.js +482 -0
  15. package/es/RayMarchedAtlasVolume.js +250 -0
  16. package/es/RenderToBuffer.js +31 -0
  17. package/es/ThreeJsPanel.js +633 -0
  18. package/es/Timing.js +28 -0
  19. package/es/TrackballControls.js +538 -0
  20. package/es/View3d.js +848 -0
  21. package/es/Volume.js +352 -0
  22. package/es/VolumeCache.js +161 -0
  23. package/es/VolumeDims.js +16 -0
  24. package/es/VolumeDrawable.js +702 -0
  25. package/es/VolumeMaker.js +101 -0
  26. package/es/VolumeRenderImpl.js +1 -0
  27. package/es/VolumeRenderSettings.js +203 -0
  28. package/es/constants/basicShaders.js +29 -0
  29. package/es/constants/colors.js +59 -0
  30. package/es/constants/denoiseShader.js +43 -0
  31. package/es/constants/lights.js +42 -0
  32. package/es/constants/materials.js +85 -0
  33. package/es/constants/pathtraceOutputShader.js +13 -0
  34. package/es/constants/scaleBarSVG.js +21 -0
  35. package/es/constants/time.js +34 -0
  36. package/es/constants/volumePTshader.js +153 -0
  37. package/es/constants/volumeRayMarchShader.js +123 -0
  38. package/es/constants/volumeSliceShader.js +115 -0
  39. package/es/index.js +21 -0
  40. package/es/loaders/IVolumeLoader.js +131 -0
  41. package/es/loaders/JsonImageInfoLoader.js +255 -0
  42. package/es/loaders/OmeZarrLoader.js +495 -0
  43. package/es/loaders/OpenCellLoader.js +65 -0
  44. package/es/loaders/RawArrayLoader.js +89 -0
  45. package/es/loaders/TiffLoader.js +219 -0
  46. package/es/loaders/VolumeLoadError.js +44 -0
  47. package/es/loaders/VolumeLoaderUtils.js +221 -0
  48. package/es/loaders/index.js +40 -0
  49. package/es/loaders/zarr_utils/ChunkPrefetchIterator.js +143 -0
  50. package/es/loaders/zarr_utils/WrappedStore.js +51 -0
  51. package/es/loaders/zarr_utils/types.js +24 -0
  52. package/es/loaders/zarr_utils/utils.js +225 -0
  53. package/es/loaders/zarr_utils/validation.js +49 -0
  54. package/es/test/ChunkPrefetchIterator.test.js +208 -0
  55. package/es/test/RequestQueue.test.js +442 -0
  56. package/es/test/SubscribableRequestQueue.test.js +244 -0
  57. package/es/test/VolumeCache.test.js +118 -0
  58. package/es/test/VolumeRenderSettings.test.js +71 -0
  59. package/es/test/lut.test.js +671 -0
  60. package/es/test/num_utils.test.js +140 -0
  61. package/es/test/volume.test.js +98 -0
  62. package/es/test/zarr_utils.test.js +358 -0
  63. package/es/types/Atlas2DSlice.d.ts +41 -0
  64. package/es/types/Channel.d.ts +44 -0
  65. package/es/types/FileSaver.d.ts +6 -0
  66. package/es/types/FusedChannelData.d.ts +26 -0
  67. package/es/types/Histogram.d.ts +57 -0
  68. package/es/types/ImageInfo.d.ts +87 -0
  69. package/es/types/Light.d.ts +27 -0
  70. package/es/types/Lut.d.ts +67 -0
  71. package/es/types/MarchingCubes.d.ts +53 -0
  72. package/es/types/MeshVolume.d.ts +40 -0
  73. package/es/types/NaiveSurfaceNets.d.ts +11 -0
  74. package/es/types/PathTracedVolume.d.ts +65 -0
  75. package/es/types/RayMarchedAtlasVolume.d.ts +41 -0
  76. package/es/types/RenderToBuffer.d.ts +17 -0
  77. package/es/types/ThreeJsPanel.d.ts +107 -0
  78. package/es/types/Timing.d.ts +11 -0
  79. package/es/types/TrackballControls.d.ts +51 -0
  80. package/es/types/View3d.d.ts +357 -0
  81. package/es/types/Volume.d.ts +152 -0
  82. package/es/types/VolumeCache.d.ts +43 -0
  83. package/es/types/VolumeDims.d.ts +28 -0
  84. package/es/types/VolumeDrawable.d.ts +108 -0
  85. package/es/types/VolumeMaker.d.ts +49 -0
  86. package/es/types/VolumeRenderImpl.d.ts +22 -0
  87. package/es/types/VolumeRenderSettings.d.ts +98 -0
  88. package/es/types/constants/basicShaders.d.ts +4 -0
  89. package/es/types/constants/colors.d.ts +2 -0
  90. package/es/types/constants/denoiseShader.d.ts +40 -0
  91. package/es/types/constants/lights.d.ts +38 -0
  92. package/es/types/constants/materials.d.ts +20 -0
  93. package/es/types/constants/pathtraceOutputShader.d.ts +11 -0
  94. package/es/types/constants/scaleBarSVG.d.ts +2 -0
  95. package/es/types/constants/time.d.ts +19 -0
  96. package/es/types/constants/volumePTshader.d.ts +137 -0
  97. package/es/types/constants/volumeRayMarchShader.d.ts +117 -0
  98. package/es/types/constants/volumeSliceShader.d.ts +109 -0
  99. package/es/types/glsl.d.js +0 -0
  100. package/es/types/index.d.ts +28 -0
  101. package/es/types/loaders/IVolumeLoader.d.ts +113 -0
  102. package/es/types/loaders/JsonImageInfoLoader.d.ts +80 -0
  103. package/es/types/loaders/OmeZarrLoader.d.ts +87 -0
  104. package/es/types/loaders/OpenCellLoader.d.ts +9 -0
  105. package/es/types/loaders/RawArrayLoader.d.ts +33 -0
  106. package/es/types/loaders/TiffLoader.d.ts +45 -0
  107. package/es/types/loaders/VolumeLoadError.d.ts +18 -0
  108. package/es/types/loaders/VolumeLoaderUtils.d.ts +38 -0
  109. package/es/types/loaders/index.d.ts +22 -0
  110. package/es/types/loaders/zarr_utils/ChunkPrefetchIterator.d.ts +22 -0
  111. package/es/types/loaders/zarr_utils/WrappedStore.d.ts +24 -0
  112. package/es/types/loaders/zarr_utils/types.d.ts +94 -0
  113. package/es/types/loaders/zarr_utils/utils.d.ts +23 -0
  114. package/es/types/loaders/zarr_utils/validation.d.ts +7 -0
  115. package/es/types/test/ChunkPrefetchIterator.test.d.ts +1 -0
  116. package/es/types/test/RequestQueue.test.d.ts +1 -0
  117. package/es/types/test/SubscribableRequestQueue.test.d.ts +1 -0
  118. package/es/types/test/VolumeCache.test.d.ts +1 -0
  119. package/es/types/test/VolumeRenderSettings.test.d.ts +1 -0
  120. package/es/types/test/lut.test.d.ts +1 -0
  121. package/es/types/test/num_utils.test.d.ts +1 -0
  122. package/es/types/test/volume.test.d.ts +1 -0
  123. package/es/types/test/zarr_utils.test.d.ts +1 -0
  124. package/es/types/types.d.ts +115 -0
  125. package/es/types/utils/RequestQueue.d.ts +112 -0
  126. package/es/types/utils/SubscribableRequestQueue.d.ts +52 -0
  127. package/es/types/utils/num_utils.d.ts +43 -0
  128. package/es/types/workers/VolumeLoaderContext.d.ts +106 -0
  129. package/es/types/workers/types.d.ts +101 -0
  130. package/es/types/workers/util.d.ts +3 -0
  131. package/es/types.js +75 -0
  132. package/es/typings.d.js +0 -0
  133. package/es/utils/RequestQueue.js +267 -0
  134. package/es/utils/SubscribableRequestQueue.js +187 -0
  135. package/es/utils/num_utils.js +231 -0
  136. package/es/workers/FetchTiffWorker.js +153 -0
  137. package/es/workers/VolumeLoadWorker.js +129 -0
  138. package/es/workers/VolumeLoaderContext.js +271 -0
  139. package/es/workers/types.js +41 -0
  140. package/es/workers/util.js +8 -0
  141. package/package.json +83 -0
@@ -0,0 +1,538 @@
1
+ /**
2
+ * @author Eberhard Graether / http://egraether.com/
3
+ * @author Mark Lundin / http://mark-lundin.com
4
+ * @author Simone Manini / http://daron1337.github.io
5
+ * @author Luca Antiga / http://lantiga.github.io
6
+ */
7
+
8
+ import { EventDispatcher, Quaternion, Vector2, Vector3, MOUSE } from "three";
9
+
10
+ // this file is heavily derived from threejs and so we disable a lot of our
11
+ // linting rules just for this file, to allow it to keep a similar form to the
12
+ // original.
13
+ /* eslint-disable @typescript-eslint/naming-convention */
14
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
15
+ /* eslint-disable @typescript-eslint/no-this-alias */
16
+ class TrackballControls extends EventDispatcher {
17
+ constructor(object, domElement) {
18
+ super();
19
+ const scope = this;
20
+ const STATE = {
21
+ NONE: -1,
22
+ ROTATE: 0,
23
+ ZOOM: 1,
24
+ PAN: 2,
25
+ TOUCH_ROTATE: 3,
26
+ TOUCH_ZOOM_PAN: 4
27
+ };
28
+ this.object = object;
29
+ this.domElement = domElement;
30
+ // API
31
+
32
+ this.enabled = true;
33
+ this.screen = {
34
+ left: 0,
35
+ top: 0,
36
+ width: 0,
37
+ height: 0
38
+ };
39
+ this.length = 10;
40
+ this.scale = 0.5;
41
+ this.scale0 = 0.5;
42
+ this.aspect = 1.0;
43
+ this.rotateSpeed = 1.0;
44
+ this.zoomSpeed = 1.2;
45
+ this.panSpeed = 0.3;
46
+ this.noRotate = false;
47
+ this.noZoom = false;
48
+ this.noPan = false;
49
+ this.staticMoving = false;
50
+ this.dynamicDampingFactor = 0.2;
51
+ this.minDistance = 0;
52
+ this.maxDistance = Infinity;
53
+ this.keys = ["KeyA", /*A*/"KeyS", /*S*/"KeyD" /*D*/];
54
+ this.mouseButtons = {
55
+ LEFT: MOUSE.ROTATE,
56
+ MIDDLE: MOUSE.DOLLY,
57
+ RIGHT: MOUSE.PAN
58
+ };
59
+
60
+ // Set to true to automatically rotate around the target
61
+ // If auto-rotate is enabled, you must call controls.update() in your animation loop
62
+ this.autoRotate = false;
63
+ this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
64
+
65
+ // internals
66
+
67
+ this.target = new Vector3();
68
+ const EPS = 0.000001;
69
+ const lastPosition = new Vector3();
70
+ let lastZoom = 1;
71
+ let _state = STATE.NONE,
72
+ _keyState = STATE.NONE,
73
+ _touchZoomDistanceStart = 0,
74
+ _touchZoomDistanceEnd = 0,
75
+ _lastAngle = 0;
76
+ const _eye = new Vector3(),
77
+ _movePrev = new Vector2(),
78
+ _moveCurr = new Vector2(),
79
+ _lastAxis = new Vector3(),
80
+ _zoomStart = new Vector2(),
81
+ _zoomEnd = new Vector2(),
82
+ _panStart = new Vector2(),
83
+ _panEnd = new Vector2(),
84
+ _pointers = [],
85
+ _pointerPositions = {};
86
+
87
+ // for reset
88
+
89
+ this.target0 = this.target.clone();
90
+ this.position0 = this.object.position.clone();
91
+ this.up0 = this.object.up.clone();
92
+ this.zoom0 = this.object.zoom;
93
+
94
+ // events
95
+
96
+ const _changeEvent = {
97
+ type: "change"
98
+ };
99
+ const _startEvent = {
100
+ type: "start"
101
+ };
102
+ const _endEvent = {
103
+ type: "end"
104
+ };
105
+
106
+ // methods
107
+
108
+ this.handleResize = function () {
109
+ const box = scope.domElement.getBoundingClientRect();
110
+ // adjustments come from similar code in the jquery offset() function
111
+ const d = scope.domElement.ownerDocument.documentElement;
112
+ scope.screen.left = box.left + window.pageXOffset - d.clientLeft;
113
+ scope.screen.top = box.top + window.pageYOffset - d.clientTop;
114
+ scope.screen.width = box.width;
115
+ scope.screen.height = box.height;
116
+ };
117
+ const getMouseOnScreen = function () {
118
+ const vector = new Vector2();
119
+ return function getMouseOnScreen(pageX, pageY) {
120
+ vector.set((pageX - scope.screen.left) / scope.screen.width, (pageY - scope.screen.top) / scope.screen.height);
121
+ return vector;
122
+ };
123
+ }();
124
+ const getMouseOnCircle = function () {
125
+ const vector = new Vector2();
126
+ return function getMouseOnCircle(pageX, pageY) {
127
+ vector.set((pageX - scope.screen.width * 0.5 - scope.screen.left) / (scope.screen.width * 0.5), (scope.screen.height + 2 * (scope.screen.top - pageY)) / scope.screen.width // screen.width intentional
128
+ );
129
+ return vector;
130
+ };
131
+ }();
132
+ function getAutoRotationAngle(delta) {
133
+ return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed * (delta * 60.0);
134
+ }
135
+ this.rotateCamera = function () {
136
+ const axis = new Vector3(),
137
+ quaternion = new Quaternion(),
138
+ eyeDirection = new Vector3(),
139
+ objectUpDirection = new Vector3(),
140
+ objectSidewaysDirection = new Vector3(),
141
+ moveDirection = new Vector3();
142
+ let angle, dx, dy;
143
+ return function rotateCamera(delta) {
144
+ dx = _moveCurr.x - _movePrev.x;
145
+ dy = _moveCurr.y - _movePrev.y;
146
+ moveDirection.set(dx, dy, 0);
147
+ angle = moveDirection.length();
148
+ angle *= scope.rotateSpeed;
149
+ if (scope.autoRotate && _state === STATE.NONE) {
150
+ // rotate about vertical axis
151
+ angle = getAutoRotationAngle(delta);
152
+ dx = angle;
153
+ dy = 0;
154
+ moveDirection.set(angle, 0, 0);
155
+ }
156
+ if (angle) {
157
+ _eye.copy(scope.object.position).sub(scope.target);
158
+ eyeDirection.copy(_eye).normalize();
159
+ objectUpDirection.copy(scope.object.up).normalize();
160
+ objectSidewaysDirection.crossVectors(objectUpDirection, eyeDirection).normalize();
161
+ objectUpDirection.setLength(dy);
162
+ objectSidewaysDirection.setLength(dx);
163
+ moveDirection.copy(objectUpDirection.add(objectSidewaysDirection));
164
+ axis.crossVectors(moveDirection, _eye).normalize();
165
+ quaternion.setFromAxisAngle(axis, angle);
166
+ _eye.applyQuaternion(quaternion);
167
+ scope.object.up.applyQuaternion(quaternion);
168
+ _lastAxis.copy(axis);
169
+ _lastAngle = angle;
170
+ } else if (!scope.staticMoving && _lastAngle) {
171
+ _lastAngle *= Math.sqrt(1.0 - scope.dynamicDampingFactor);
172
+ _eye.copy(scope.object.position).sub(scope.target);
173
+ quaternion.setFromAxisAngle(_lastAxis, _lastAngle);
174
+ _eye.applyQuaternion(quaternion);
175
+ scope.object.up.applyQuaternion(quaternion);
176
+ }
177
+ _movePrev.copy(_moveCurr);
178
+ };
179
+ }();
180
+ this.zoomCamera = function () {
181
+ let factor;
182
+ if (_state === STATE.TOUCH_ZOOM_PAN) {
183
+ factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
184
+ _touchZoomDistanceStart = _touchZoomDistanceEnd;
185
+ if (scope.object.isPerspectiveCamera) {
186
+ _eye.multiplyScalar(factor);
187
+ } else if (scope.object.isOrthographicCamera) {
188
+ scope.scale = scope.scale * factor;
189
+ scope.object.zoom /= factor;
190
+ scope.object.updateProjectionMatrix();
191
+ } else {
192
+ console.warn("THREE.TrackballControls: Unsupported camera type");
193
+ }
194
+ } else {
195
+ factor = 1.0 + (_zoomEnd.y - _zoomStart.y) * scope.zoomSpeed;
196
+ if (factor !== 1.0 && factor > 0.0) {
197
+ if (scope.object.isPerspectiveCamera) {
198
+ _eye.multiplyScalar(factor);
199
+ } else if (scope.object.isOrthographicCamera) {
200
+ scope.scale = scope.scale * factor;
201
+ scope.object.zoom /= factor;
202
+ scope.object.updateProjectionMatrix();
203
+ } else {
204
+ console.warn("THREE.TrackballControls: Unsupported camera type");
205
+ }
206
+ }
207
+ if (scope.staticMoving) {
208
+ _zoomStart.copy(_zoomEnd);
209
+ } else {
210
+ _zoomStart.y += (_zoomEnd.y - _zoomStart.y) * this.dynamicDampingFactor;
211
+ }
212
+ }
213
+ };
214
+ this.panCamera = function () {
215
+ const mouseChange = new Vector2(),
216
+ objectUp = new Vector3(),
217
+ pan = new Vector3();
218
+ return function panCamera() {
219
+ mouseChange.copy(_panEnd).sub(_panStart);
220
+ if (mouseChange.lengthSq()) {
221
+ if (scope.object.isOrthographicCamera) {
222
+ const scale_x = (scope.object.right - scope.object.left) / scope.object.zoom / scope.domElement.clientWidth;
223
+ const scale_y = (scope.object.top - scope.object.bottom) / scope.object.zoom / scope.domElement.clientWidth;
224
+ mouseChange.x *= scale_x;
225
+ mouseChange.y *= scale_y;
226
+ }
227
+ mouseChange.multiplyScalar(_eye.length() * scope.panSpeed);
228
+ pan.copy(_eye).cross(scope.object.up).setLength(mouseChange.x);
229
+ pan.add(objectUp.copy(scope.object.up).setLength(mouseChange.y));
230
+ scope.object.position.add(pan);
231
+ scope.target.add(pan);
232
+ if (scope.staticMoving) {
233
+ _panStart.copy(_panEnd);
234
+ } else {
235
+ _panStart.add(mouseChange.subVectors(_panEnd, _panStart).multiplyScalar(scope.dynamicDampingFactor));
236
+ }
237
+ }
238
+ };
239
+ }();
240
+ this.checkDistances = function () {
241
+ if (!scope.noZoom || !scope.noPan) {
242
+ if (_eye.lengthSq() > scope.maxDistance * scope.maxDistance) {
243
+ scope.object.position.addVectors(scope.target, _eye.setLength(scope.maxDistance));
244
+ _zoomStart.copy(_zoomEnd);
245
+ }
246
+ if (_eye.lengthSq() < scope.minDistance * scope.minDistance) {
247
+ scope.object.position.addVectors(scope.target, _eye.setLength(scope.minDistance));
248
+ _zoomStart.copy(_zoomEnd);
249
+ }
250
+ }
251
+ };
252
+ this.update = function (delta) {
253
+ if (scope.enabled === false) return;
254
+ delta = delta || 0.0;
255
+ _eye.subVectors(scope.object.position, scope.target);
256
+ if (!scope.noRotate) {
257
+ scope.rotateCamera(delta);
258
+ }
259
+ if (!scope.noZoom) {
260
+ scope.zoomCamera();
261
+ }
262
+ if (!scope.noPan) {
263
+ scope.panCamera();
264
+ }
265
+ scope.object.position.addVectors(scope.target, _eye);
266
+ if (scope.object.isPerspectiveCamera) {
267
+ scope.checkDistances();
268
+ scope.object.lookAt(scope.target);
269
+ if (lastPosition.distanceToSquared(scope.object.position) > EPS) {
270
+ scope.dispatchEvent(_changeEvent);
271
+ lastPosition.copy(scope.object.position);
272
+ }
273
+ } else if (scope.object.isOrthographicCamera) {
274
+ scope.object.lookAt(scope.target);
275
+ if (lastPosition.distanceToSquared(scope.object.position) > EPS || lastZoom !== scope.object.zoom) {
276
+ scope.dispatchEvent(_changeEvent);
277
+ lastPosition.copy(scope.object.position);
278
+ lastZoom = scope.object.zoom;
279
+ }
280
+ } else {
281
+ console.warn("THREE.TrackballControls: Unsupported camera type");
282
+ }
283
+ };
284
+ this.reset = function () {
285
+ //if (scope.enabled === false) return;
286
+
287
+ _state = STATE.NONE;
288
+ _keyState = STATE.NONE;
289
+ scope.target.copy(scope.target0);
290
+ scope.object.position.copy(scope.position0);
291
+ scope.object.up.copy(scope.up0);
292
+ scope.object.zoom = scope.zoom0;
293
+ scope.scale = scope.scale0;
294
+ scope.object.updateProjectionMatrix();
295
+ _eye.subVectors(scope.object.position, scope.target);
296
+ scope.object.lookAt(scope.target);
297
+ scope.dispatchEvent(_changeEvent);
298
+ lastPosition.copy(scope.object.position);
299
+ lastZoom = scope.object.zoom;
300
+ };
301
+
302
+ // listeners
303
+
304
+ function onPointerDown(event) {
305
+ if (scope.enabled === false) return;
306
+ if (_pointers.length === 0) {
307
+ scope.domElement.setPointerCapture(event.pointerId);
308
+ scope.domElement.addEventListener("pointermove", onPointerMove);
309
+ scope.domElement.addEventListener("pointerup", onPointerUp);
310
+ } //
311
+
312
+ addPointer(event);
313
+ if (event.pointerType === "touch") {
314
+ onTouchStart(event);
315
+ } else {
316
+ onMouseDown(event);
317
+ }
318
+ }
319
+ function onPointerMove(event) {
320
+ if (scope.enabled === false) return;
321
+ if (event.pointerType === "touch") {
322
+ onTouchMove(event);
323
+ } else {
324
+ onMouseMove(event);
325
+ }
326
+ }
327
+ function onPointerUp(event) {
328
+ if (scope.enabled === false) return;
329
+ if (event.pointerType === "touch") {
330
+ onTouchEnd(event);
331
+ } else {
332
+ onMouseUp();
333
+ } //
334
+
335
+ removePointer(event);
336
+ if (_pointers.length === 0) {
337
+ scope.domElement.releasePointerCapture(event.pointerId);
338
+ scope.domElement.removeEventListener("pointermove", onPointerMove);
339
+ scope.domElement.removeEventListener("pointerup", onPointerUp);
340
+ }
341
+ }
342
+ function onPointerCancel(event) {
343
+ removePointer(event);
344
+ }
345
+ function keydown(event) {
346
+ if (scope.enabled === false) return;
347
+ window.removeEventListener("keydown", keydown);
348
+ if (_keyState !== STATE.NONE) {
349
+ return;
350
+ } else if (event.code === scope.keys[STATE.ROTATE] && !scope.noRotate) {
351
+ _keyState = STATE.ROTATE;
352
+ } else if (event.code === scope.keys[STATE.ZOOM] && !scope.noZoom) {
353
+ _keyState = STATE.ZOOM;
354
+ } else if (event.code === scope.keys[STATE.PAN] && !scope.noPan) {
355
+ _keyState = STATE.PAN;
356
+ }
357
+ }
358
+ function keyup(_event) {
359
+ if (scope.enabled === false) return;
360
+ _keyState = STATE.NONE;
361
+ window.addEventListener("keydown", keydown);
362
+ }
363
+ function onMouseDown(event) {
364
+ if (_state === STATE.NONE) {
365
+ switch (event.button) {
366
+ case scope.mouseButtons.LEFT:
367
+ _state = STATE.ROTATE;
368
+ break;
369
+ case scope.mouseButtons.MIDDLE:
370
+ _state = STATE.ZOOM;
371
+ break;
372
+ case scope.mouseButtons.RIGHT:
373
+ _state = STATE.PAN;
374
+ break;
375
+ }
376
+ }
377
+ const state = _keyState !== STATE.NONE ? _keyState : _state;
378
+ if (state === STATE.ROTATE && !scope.noRotate) {
379
+ _moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY));
380
+ _movePrev.copy(_moveCurr);
381
+ } else if (state === STATE.ZOOM && !scope.noZoom) {
382
+ _zoomStart.copy(getMouseOnScreen(event.pageX, event.pageY));
383
+ _zoomEnd.copy(_zoomStart);
384
+ } else if (state === STATE.PAN && !scope.noPan) {
385
+ _panStart.copy(getMouseOnScreen(event.pageX, event.pageY));
386
+ _panEnd.copy(_panStart);
387
+ }
388
+ scope.dispatchEvent(_startEvent);
389
+ }
390
+ function onMouseMove(event) {
391
+ const state = _keyState !== STATE.NONE ? _keyState : _state;
392
+ if (state === STATE.ROTATE && !scope.noRotate) {
393
+ _movePrev.copy(_moveCurr);
394
+ _moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY));
395
+ } else if (state === STATE.ZOOM && !scope.noZoom) {
396
+ _zoomEnd.copy(getMouseOnScreen(event.pageX, event.pageY));
397
+ } else if (state === STATE.PAN && !scope.noPan) {
398
+ _panEnd.copy(getMouseOnScreen(event.pageX, event.pageY));
399
+ }
400
+ }
401
+ function onMouseUp() {
402
+ _state = STATE.NONE;
403
+ scope.dispatchEvent(_endEvent);
404
+ }
405
+ function onMouseWheel(event) {
406
+ if (scope.enabled === false) return;
407
+ if (scope.noZoom === true) return;
408
+ event.preventDefault();
409
+ switch (event.deltaMode) {
410
+ case 2:
411
+ // Zoom in pages
412
+ _zoomStart.y -= event.deltaY * 0.025;
413
+ break;
414
+ case 1:
415
+ // Zoom in lines
416
+ _zoomStart.y -= event.deltaY * 0.01;
417
+ break;
418
+ default:
419
+ // undefined, 0, assume pixels
420
+ _zoomStart.y -= event.deltaY * 0.00025;
421
+ break;
422
+ }
423
+ scope.dispatchEvent(_startEvent);
424
+ scope.dispatchEvent(_endEvent);
425
+ }
426
+ function onTouchStart(event) {
427
+ trackPointer(event);
428
+ let dx, dy, x, y;
429
+ switch (_pointers.length) {
430
+ case 1:
431
+ _state = STATE.TOUCH_ROTATE;
432
+ _moveCurr.copy(getMouseOnCircle(_pointers[0].pageX, _pointers[0].pageY));
433
+ _movePrev.copy(_moveCurr);
434
+ break;
435
+ default:
436
+ // 2 or more
437
+ _state = STATE.TOUCH_ZOOM_PAN;
438
+ dx = _pointers[0].pageX - _pointers[1].pageX;
439
+ dy = _pointers[0].pageY - _pointers[1].pageY;
440
+ _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt(dx * dx + dy * dy);
441
+ x = (_pointers[0].pageX + _pointers[1].pageX) / 2;
442
+ y = (_pointers[0].pageY + _pointers[1].pageY) / 2;
443
+ _panStart.copy(getMouseOnScreen(x, y));
444
+ _panEnd.copy(_panStart);
445
+ break;
446
+ }
447
+ scope.dispatchEvent(_startEvent);
448
+ }
449
+ function onTouchMove(event) {
450
+ trackPointer(event);
451
+ let position, dx, dy, x, y;
452
+ switch (_pointers.length) {
453
+ case 1:
454
+ _movePrev.copy(_moveCurr);
455
+ _moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY));
456
+ break;
457
+ default:
458
+ // 2 or more
459
+ position = getSecondPointerPosition(event);
460
+ dx = event.pageX - position.x;
461
+ dy = event.pageY - position.y;
462
+ _touchZoomDistanceEnd = Math.sqrt(dx * dx + dy * dy);
463
+ x = (event.pageX + position.x) / 2;
464
+ y = (event.pageY + position.y) / 2;
465
+ _panEnd.copy(getMouseOnScreen(x, y));
466
+ break;
467
+ }
468
+ }
469
+ function onTouchEnd(event) {
470
+ switch (_pointers.length) {
471
+ case 0:
472
+ _state = STATE.NONE;
473
+ break;
474
+ case 1:
475
+ _state = STATE.TOUCH_ROTATE;
476
+ _moveCurr.copy(getMouseOnCircle(event.pageX, event.pageY));
477
+ _movePrev.copy(_moveCurr);
478
+ break;
479
+ case 2:
480
+ _state = STATE.TOUCH_ZOOM_PAN;
481
+ _moveCurr.copy(getMouseOnCircle(event.pageX - _movePrev.x, event.pageY - _movePrev.y));
482
+ _movePrev.copy(_moveCurr);
483
+ break;
484
+ }
485
+ scope.dispatchEvent(_endEvent);
486
+ }
487
+ function contextmenu(event) {
488
+ if (scope.enabled === false) return;
489
+ event.preventDefault();
490
+ }
491
+ function addPointer(event) {
492
+ _pointers.push(event);
493
+ }
494
+ function removePointer(event) {
495
+ delete _pointerPositions[event.pointerId];
496
+ for (let i = 0; i < _pointers.length; i++) {
497
+ if (_pointers[i].pointerId == event.pointerId) {
498
+ _pointers.splice(i, 1);
499
+ return;
500
+ }
501
+ }
502
+ }
503
+ function trackPointer(event) {
504
+ let position = _pointerPositions[event.pointerId];
505
+ if (position === undefined) {
506
+ position = new Vector2();
507
+ _pointerPositions[event.pointerId] = position;
508
+ }
509
+ position.set(event.pageX, event.pageY);
510
+ }
511
+ function getSecondPointerPosition(event) {
512
+ const pointer = event.pointerId === _pointers[0].pointerId ? _pointers[1] : _pointers[0];
513
+ return _pointerPositions[pointer.pointerId];
514
+ }
515
+ this.dispose = function () {
516
+ scope.domElement.removeEventListener("contextmenu", contextmenu);
517
+ scope.domElement.removeEventListener("pointerdown", onPointerDown);
518
+ scope.domElement.removeEventListener("pointercancel", onPointerCancel);
519
+ scope.domElement.removeEventListener("wheel", onMouseWheel);
520
+ scope.domElement.removeEventListener("pointermove", onPointerMove);
521
+ scope.domElement.removeEventListener("pointerup", onPointerUp);
522
+ window.removeEventListener("keydown", keydown);
523
+ window.removeEventListener("keyup", keyup);
524
+ };
525
+ this.domElement.addEventListener("contextmenu", contextmenu);
526
+ this.domElement.addEventListener("pointerdown", onPointerDown);
527
+ this.domElement.addEventListener("pointercancel", onPointerCancel);
528
+ this.domElement.addEventListener("wheel", onMouseWheel, {
529
+ passive: false
530
+ });
531
+ window.addEventListener("keydown", keydown);
532
+ window.addEventListener("keyup", keyup);
533
+ this.handleResize(); // force an update at start
534
+
535
+ this.update();
536
+ }
537
+ }
538
+ export default TrackballControls;