three-render-objects 1.29.4 → 1.29.5

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.
@@ -1,4 +1,4 @@
1
- // Version 1.29.4 three-render-objects - https://github.com/vasturiano/three-render-objects
1
+ // Version 1.29.5 three-render-objects - https://github.com/vasturiano/three-render-objects
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('three')) :
4
4
  typeof define === 'function' && define.amd ? define(['three'], factory) :
@@ -6,8 +6,8 @@
6
6
  })(this, (function (three$1) { 'use strict';
7
7
 
8
8
  function styleInject(css, ref) {
9
- ref = {};
10
- ref.insertAt;
9
+ if ( ref === void 0 ) ref = {};
10
+ var insertAt = ref.insertAt;
11
11
 
12
12
  if (typeof document === 'undefined') { return; }
13
13
 
@@ -15,7 +15,13 @@
15
15
  var style = document.createElement('style');
16
16
  style.type = 'text/css';
17
17
 
18
- {
18
+ if (insertAt === 'top') {
19
+ if (head.firstChild) {
20
+ head.insertBefore(style, head.firstChild);
21
+ } else {
22
+ head.appendChild(style);
23
+ }
24
+ } else {
19
25
  head.appendChild(style);
20
26
  }
21
27
 
@@ -29,6 +35,28 @@
29
35
  var css_248z = ".scene-nav-info {\n bottom: 5px;\n width: 100%;\n text-align: center;\n color: slategrey;\n opacity: 0.7;\n font-size: 10px;\n}\n\n.scene-tooltip {\n top: 0;\n color: lavender;\n font-size: 15px;\n}\n\n.scene-nav-info, .scene-tooltip {\n position: absolute;\n font-family: sans-serif;\n pointer-events: none;\n user-select: none;\n}\n\n.scene-container canvas:focus {\n outline: none;\n}";
30
36
  styleInject(css_248z);
31
37
 
38
+ function _arrayLikeToArray$1(r, a) {
39
+ (null == a || a > r.length) && (a = r.length);
40
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
41
+ return n;
42
+ }
43
+ function _arrayWithHoles$1(r) {
44
+ if (Array.isArray(r)) return r;
45
+ }
46
+ function _arrayWithoutHoles(r) {
47
+ if (Array.isArray(r)) return _arrayLikeToArray$1(r);
48
+ }
49
+ function _defineProperty(e, r, t) {
50
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
51
+ value: t,
52
+ enumerable: !0,
53
+ configurable: !0,
54
+ writable: !0
55
+ }) : e[r] = t, e;
56
+ }
57
+ function _iterableToArray(r) {
58
+ if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
59
+ }
32
60
  function _iterableToArrayLimit$1(r, l) {
33
61
  var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
34
62
  if (null != t) {
@@ -53,85 +81,63 @@
53
81
  return a;
54
82
  }
55
83
  }
84
+ function _nonIterableRest$1() {
85
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
86
+ }
87
+ function _nonIterableSpread() {
88
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
89
+ }
90
+ function _slicedToArray$1(r, e) {
91
+ return _arrayWithHoles$1(r) || _iterableToArrayLimit$1(r, e) || _unsupportedIterableToArray$1(r, e) || _nonIterableRest$1();
92
+ }
93
+ function _toConsumableArray(r) {
94
+ return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray$1(r) || _nonIterableSpread();
95
+ }
56
96
  function _toPrimitive(t, r) {
57
97
  if ("object" != typeof t || !t) return t;
58
98
  var e = t[Symbol.toPrimitive];
59
99
  if (void 0 !== e) {
60
- var i = e.call(t, r );
100
+ var i = e.call(t, r || "default");
61
101
  if ("object" != typeof i) return i;
62
102
  throw new TypeError("@@toPrimitive must return a primitive value.");
63
103
  }
64
- return (String )(t);
104
+ return ("string" === r ? String : Number)(t);
65
105
  }
66
106
  function _toPropertyKey(t) {
67
107
  var i = _toPrimitive(t, "string");
68
108
  return "symbol" == typeof i ? i : i + "";
69
109
  }
70
- function _defineProperty(obj, key, value) {
71
- key = _toPropertyKey(key);
72
- if (key in obj) {
73
- Object.defineProperty(obj, key, {
74
- value: value,
75
- enumerable: true,
76
- configurable: true,
77
- writable: true
78
- });
79
- } else {
80
- obj[key] = value;
110
+ function _unsupportedIterableToArray$1(r, a) {
111
+ if (r) {
112
+ if ("string" == typeof r) return _arrayLikeToArray$1(r, a);
113
+ var t = {}.toString.call(r).slice(8, -1);
114
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$1(r, a) : void 0;
81
115
  }
82
- return obj;
83
- }
84
- function _slicedToArray$1(arr, i) {
85
- return _arrayWithHoles$1(arr) || _iterableToArrayLimit$1(arr, i) || _unsupportedIterableToArray$1(arr, i) || _nonIterableRest$1();
86
- }
87
- function _toConsumableArray(arr) {
88
- return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray$1(arr) || _nonIterableSpread();
89
- }
90
- function _arrayWithoutHoles(arr) {
91
- if (Array.isArray(arr)) return _arrayLikeToArray$1(arr);
92
- }
93
- function _arrayWithHoles$1(arr) {
94
- if (Array.isArray(arr)) return arr;
95
- }
96
- function _iterableToArray(iter) {
97
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
98
- }
99
- function _unsupportedIterableToArray$1(o, minLen) {
100
- if (!o) return;
101
- if (typeof o === "string") return _arrayLikeToArray$1(o, minLen);
102
- var n = Object.prototype.toString.call(o).slice(8, -1);
103
- if (n === "Object" && o.constructor) n = o.constructor.name;
104
- if (n === "Map" || n === "Set") return Array.from(o);
105
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen);
106
- }
107
- function _arrayLikeToArray$1(arr, len) {
108
- if (len == null || len > arr.length) len = arr.length;
109
- for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
110
- return arr2;
111
- }
112
- function _nonIterableSpread() {
113
- throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
114
- }
115
- function _nonIterableRest$1() {
116
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
117
116
  }
118
117
 
119
118
  const _changeEvent$2 = { type: 'change' };
120
119
  const _startEvent$1 = { type: 'start' };
121
120
  const _endEvent$1 = { type: 'end' };
122
121
 
123
- class TrackballControls extends three$1.EventDispatcher {
122
+ const _EPS$2 = 0.000001;
123
+ const _STATE$1 = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
124
124
 
125
- constructor( object, domElement ) {
125
+ const _v2 = new three$1.Vector2();
126
+ const _mouseChange = new three$1.Vector2();
127
+ const _objectUp = new three$1.Vector3();
128
+ const _pan = new three$1.Vector3();
129
+ const _axis = new three$1.Vector3();
130
+ const _quaternion = new three$1.Quaternion();
131
+ const _eyeDirection = new three$1.Vector3();
132
+ const _objectUpDirection = new three$1.Vector3();
133
+ const _objectSidewaysDirection = new three$1.Vector3();
134
+ const _moveDirection = new three$1.Vector3();
126
135
 
127
- super();
136
+ class TrackballControls extends three$1.Controls {
128
137
 
129
- const scope = this;
130
- const STATE = { NONE: - 1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM_PAN: 4 };
138
+ constructor( object, domElement = null ) {
131
139
 
132
- this.object = object;
133
- this.domElement = domElement;
134
- this.domElement.style.touchAction = 'none'; // disable touch scroll
140
+ super( object, domElement );
135
141
 
136
142
  // API
137
143
 
@@ -159,779 +165,773 @@
159
165
  this.keys = [ 'KeyA' /*A*/, 'KeyS' /*S*/, 'KeyD' /*D*/ ];
160
166
 
161
167
  this.mouseButtons = { LEFT: three$1.MOUSE.ROTATE, MIDDLE: three$1.MOUSE.DOLLY, RIGHT: three$1.MOUSE.PAN };
162
-
163
- // internals
168
+ this.state = _STATE$1.NONE;
169
+ this.keyState = _STATE$1.NONE;
164
170
 
165
171
  this.target = new three$1.Vector3();
166
172
 
167
- const EPS = 0.000001;
173
+ // internals
168
174
 
169
- const lastPosition = new three$1.Vector3();
170
- let lastZoom = 1;
175
+ this._lastPosition = new three$1.Vector3();
176
+ this._lastZoom = 1;
177
+ this._touchZoomDistanceStart = 0;
178
+ this._touchZoomDistanceEnd = 0;
179
+ this._lastAngle = 0;
171
180
 
172
- let _state = STATE.NONE,
173
- _keyState = STATE.NONE,
181
+ this._eye = new three$1.Vector3();
174
182
 
175
- _touchZoomDistanceStart = 0,
176
- _touchZoomDistanceEnd = 0,
183
+ this._movePrev = new three$1.Vector2();
184
+ this._moveCurr = new three$1.Vector2();
177
185
 
178
- _lastAngle = 0;
186
+ this._lastAxis = new three$1.Vector3();
179
187
 
180
- const _eye = new three$1.Vector3(),
188
+ this._zoomStart = new three$1.Vector2();
189
+ this._zoomEnd = new three$1.Vector2();
181
190
 
182
- _movePrev = new three$1.Vector2(),
183
- _moveCurr = new three$1.Vector2(),
191
+ this._panStart = new three$1.Vector2();
192
+ this._panEnd = new three$1.Vector2();
184
193
 
185
- _lastAxis = new three$1.Vector3(),
194
+ this._pointers = [];
195
+ this._pointerPositions = {};
186
196
 
187
- _zoomStart = new three$1.Vector2(),
188
- _zoomEnd = new three$1.Vector2(),
197
+ // event listeners
189
198
 
190
- _panStart = new three$1.Vector2(),
191
- _panEnd = new three$1.Vector2(),
199
+ this._onPointerMove = onPointerMove$2.bind( this );
200
+ this._onPointerDown = onPointerDown$2.bind( this );
201
+ this._onPointerUp = onPointerUp$2.bind( this );
202
+ this._onPointerCancel = onPointerCancel$1.bind( this );
203
+ this._onContextMenu = onContextMenu$2.bind( this );
204
+ this._onMouseWheel = onMouseWheel$1.bind( this );
205
+ this._onKeyDown = onKeyDown$2.bind( this );
206
+ this._onKeyUp = onKeyUp$1.bind( this );
192
207
 
193
- _pointers = [],
194
- _pointerPositions = {};
208
+ this._onTouchStart = onTouchStart$1.bind( this );
209
+ this._onTouchMove = onTouchMove$1.bind( this );
210
+ this._onTouchEnd = onTouchEnd.bind( this );
195
211
 
196
- // for reset
212
+ this._onMouseDown = onMouseDown$1.bind( this );
213
+ this._onMouseMove = onMouseMove$1.bind( this );
214
+ this._onMouseUp = onMouseUp.bind( this );
197
215
 
198
- this.target0 = this.target.clone();
199
- this.position0 = this.object.position.clone();
200
- this.up0 = this.object.up.clone();
201
- this.zoom0 = this.object.zoom;
202
-
203
- // methods
204
-
205
- this.handleResize = function () {
206
-
207
- const box = scope.domElement.getBoundingClientRect();
208
- // adjustments come from similar code in the jquery offset() function
209
- const d = scope.domElement.ownerDocument.documentElement;
210
- scope.screen.left = box.left + window.pageXOffset - d.clientLeft;
211
- scope.screen.top = box.top + window.pageYOffset - d.clientTop;
212
- scope.screen.width = box.width;
213
- scope.screen.height = box.height;
216
+ // for reset
214
217
 
215
- };
218
+ this._target0 = this.target.clone();
219
+ this._position0 = this.object.position.clone();
220
+ this._up0 = this.object.up.clone();
221
+ this._zoom0 = this.object.zoom;
216
222
 
217
- const getMouseOnScreen = ( function () {
223
+ if ( domElement !== null ) {
218
224
 
219
- const vector = new three$1.Vector2();
225
+ this.connect();
220
226
 
221
- return function getMouseOnScreen( pageX, pageY ) {
227
+ this.handleResize();
222
228
 
223
- vector.set(
224
- ( pageX - scope.screen.left ) / scope.screen.width,
225
- ( pageY - scope.screen.top ) / scope.screen.height
226
- );
229
+ }
227
230
 
228
- return vector;
231
+ // force an update at start
232
+ this.update();
229
233
 
230
- };
234
+ }
231
235
 
232
- }() );
236
+ connect() {
233
237
 
234
- const getMouseOnCircle = ( function () {
238
+ window.addEventListener( 'keydown', this._onKeyDown );
239
+ window.addEventListener( 'keyup', this._onKeyUp );
235
240
 
236
- const vector = new three$1.Vector2();
241
+ this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
242
+ this.domElement.addEventListener( 'pointercancel', this._onPointerCancel );
243
+ this.domElement.addEventListener( 'wheel', this._onMouseWheel, { passive: false } );
244
+ this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
237
245
 
238
- return function getMouseOnCircle( pageX, pageY ) {
246
+ this.domElement.style.touchAction = 'none'; // disable touch scroll
239
247
 
240
- vector.set(
241
- ( ( pageX - scope.screen.width * 0.5 - scope.screen.left ) / ( scope.screen.width * 0.5 ) ),
242
- ( ( scope.screen.height + 2 * ( scope.screen.top - pageY ) ) / scope.screen.width ) // screen.width intentional
243
- );
248
+ }
244
249
 
245
- return vector;
250
+ disconnect() {
246
251
 
247
- };
252
+ window.removeEventListener( 'keydown', this._onKeyDown );
253
+ window.removeEventListener( 'keyup', this._onKeyUp );
248
254
 
249
- }() );
255
+ this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
256
+ this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
257
+ this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
258
+ this.domElement.removeEventListener( 'pointercancel', this._onPointerCancel );
259
+ this.domElement.removeEventListener( 'wheel', this._onMouseWheel );
260
+ this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
250
261
 
251
- this.rotateCamera = ( function () {
262
+ this.domElement.style.touchAction = 'auto'; // disable touch scroll
252
263
 
253
- const axis = new three$1.Vector3(),
254
- quaternion = new three$1.Quaternion(),
255
- eyeDirection = new three$1.Vector3(),
256
- objectUpDirection = new three$1.Vector3(),
257
- objectSidewaysDirection = new three$1.Vector3(),
258
- moveDirection = new three$1.Vector3();
264
+ }
259
265
 
260
- return function rotateCamera() {
266
+ dispose() {
261
267
 
262
- moveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 );
263
- let angle = moveDirection.length();
268
+ this.disconnect();
264
269
 
265
- if ( angle ) {
270
+ }
266
271
 
267
- _eye.copy( scope.object.position ).sub( scope.target );
272
+ handleResize() {
268
273
 
269
- eyeDirection.copy( _eye ).normalize();
270
- objectUpDirection.copy( scope.object.up ).normalize();
271
- objectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize();
274
+ const box = this.domElement.getBoundingClientRect();
275
+ // adjustments come from similar code in the jquery offset() function
276
+ const d = this.domElement.ownerDocument.documentElement;
272
277
 
273
- objectUpDirection.setLength( _moveCurr.y - _movePrev.y );
274
- objectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x );
278
+ this.screen.left = box.left + window.pageXOffset - d.clientLeft;
279
+ this.screen.top = box.top + window.pageYOffset - d.clientTop;
280
+ this.screen.width = box.width;
281
+ this.screen.height = box.height;
275
282
 
276
- moveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) );
283
+ }
277
284
 
278
- axis.crossVectors( moveDirection, _eye ).normalize();
285
+ update() {
279
286
 
280
- angle *= scope.rotateSpeed;
281
- quaternion.setFromAxisAngle( axis, angle );
287
+ this._eye.subVectors( this.object.position, this.target );
282
288
 
283
- _eye.applyQuaternion( quaternion );
284
- scope.object.up.applyQuaternion( quaternion );
289
+ if ( ! this.noRotate ) {
285
290
 
286
- _lastAxis.copy( axis );
287
- _lastAngle = angle;
291
+ this._rotateCamera();
288
292
 
289
- } else if ( ! scope.staticMoving && _lastAngle ) {
293
+ }
290
294
 
291
- _lastAngle *= Math.sqrt( 1.0 - scope.dynamicDampingFactor );
292
- _eye.copy( scope.object.position ).sub( scope.target );
293
- quaternion.setFromAxisAngle( _lastAxis, _lastAngle );
294
- _eye.applyQuaternion( quaternion );
295
- scope.object.up.applyQuaternion( quaternion );
295
+ if ( ! this.noZoom ) {
296
296
 
297
- }
297
+ this._zoomCamera();
298
298
 
299
- _movePrev.copy( _moveCurr );
299
+ }
300
300
 
301
- };
301
+ if ( ! this.noPan ) {
302
302
 
303
- }() );
303
+ this._panCamera();
304
304
 
305
+ }
305
306
 
306
- this.zoomCamera = function () {
307
+ this.object.position.addVectors( this.target, this._eye );
307
308
 
308
- let factor;
309
+ if ( this.object.isPerspectiveCamera ) {
309
310
 
310
- if ( _state === STATE.TOUCH_ZOOM_PAN ) {
311
+ this._checkDistances();
311
312
 
312
- factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
313
- _touchZoomDistanceStart = _touchZoomDistanceEnd;
313
+ this.object.lookAt( this.target );
314
314
 
315
- if ( scope.object.isPerspectiveCamera ) {
315
+ if ( this._lastPosition.distanceToSquared( this.object.position ) > _EPS$2 ) {
316
316
 
317
- _eye.multiplyScalar( factor );
317
+ this.dispatchEvent( _changeEvent$2 );
318
318
 
319
- } else if ( scope.object.isOrthographicCamera ) {
319
+ this._lastPosition.copy( this.object.position );
320
320
 
321
- scope.object.zoom = three$1.MathUtils.clamp( scope.object.zoom / factor, scope.minZoom, scope.maxZoom );
321
+ }
322
322
 
323
- if ( lastZoom !== scope.object.zoom ) {
323
+ } else if ( this.object.isOrthographicCamera ) {
324
324
 
325
- scope.object.updateProjectionMatrix();
325
+ this.object.lookAt( this.target );
326
326
 
327
- }
327
+ if ( this._lastPosition.distanceToSquared( this.object.position ) > _EPS$2 || this._lastZoom !== this.object.zoom ) {
328
328
 
329
- } else {
329
+ this.dispatchEvent( _changeEvent$2 );
330
330
 
331
- console.warn( 'THREE.TrackballControls: Unsupported camera type' );
331
+ this._lastPosition.copy( this.object.position );
332
+ this._lastZoom = this.object.zoom;
332
333
 
333
- }
334
+ }
334
335
 
335
- } else {
336
+ } else {
336
337
 
337
- factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * scope.zoomSpeed;
338
+ console.warn( 'THREE.TrackballControls: Unsupported camera type.' );
338
339
 
339
- if ( factor !== 1.0 && factor > 0.0 ) {
340
+ }
340
341
 
341
- if ( scope.object.isPerspectiveCamera ) {
342
+ }
342
343
 
343
- _eye.multiplyScalar( factor );
344
+ reset() {
344
345
 
345
- } else if ( scope.object.isOrthographicCamera ) {
346
+ this.state = _STATE$1.NONE;
347
+ this.keyState = _STATE$1.NONE;
346
348
 
347
- scope.object.zoom = three$1.MathUtils.clamp( scope.object.zoom / factor, scope.minZoom, scope.maxZoom );
349
+ this.target.copy( this._target0 );
350
+ this.object.position.copy( this._position0 );
351
+ this.object.up.copy( this._up0 );
352
+ this.object.zoom = this._zoom0;
348
353
 
349
- if ( lastZoom !== scope.object.zoom ) {
354
+ this.object.updateProjectionMatrix();
350
355
 
351
- scope.object.updateProjectionMatrix();
356
+ this._eye.subVectors( this.object.position, this.target );
352
357
 
353
- }
358
+ this.object.lookAt( this.target );
354
359
 
355
- } else {
360
+ this.dispatchEvent( _changeEvent$2 );
356
361
 
357
- console.warn( 'THREE.TrackballControls: Unsupported camera type' );
362
+ this._lastPosition.copy( this.object.position );
363
+ this._lastZoom = this.object.zoom;
358
364
 
359
- }
365
+ }
360
366
 
361
- }
367
+ _panCamera() {
362
368
 
363
- if ( scope.staticMoving ) {
369
+ _mouseChange.copy( this._panEnd ).sub( this._panStart );
364
370
 
365
- _zoomStart.copy( _zoomEnd );
371
+ if ( _mouseChange.lengthSq() ) {
366
372
 
367
- } else {
373
+ if ( this.object.isOrthographicCamera ) {
368
374
 
369
- _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
375
+ const scale_x = ( this.object.right - this.object.left ) / this.object.zoom / this.domElement.clientWidth;
376
+ const scale_y = ( this.object.top - this.object.bottom ) / this.object.zoom / this.domElement.clientWidth;
370
377
 
371
- }
378
+ _mouseChange.x *= scale_x;
379
+ _mouseChange.y *= scale_y;
372
380
 
373
381
  }
374
382
 
375
- };
383
+ _mouseChange.multiplyScalar( this._eye.length() * this.panSpeed );
376
384
 
377
- this.panCamera = ( function () {
385
+ _pan.copy( this._eye ).cross( this.object.up ).setLength( _mouseChange.x );
386
+ _pan.add( _objectUp.copy( this.object.up ).setLength( _mouseChange.y ) );
378
387
 
379
- const mouseChange = new three$1.Vector2(),
380
- objectUp = new three$1.Vector3(),
381
- pan = new three$1.Vector3();
388
+ this.object.position.add( _pan );
389
+ this.target.add( _pan );
382
390
 
383
- return function panCamera() {
391
+ if ( this.staticMoving ) {
384
392
 
385
- mouseChange.copy( _panEnd ).sub( _panStart );
393
+ this._panStart.copy( this._panEnd );
386
394
 
387
- if ( mouseChange.lengthSq() ) {
388
-
389
- if ( scope.object.isOrthographicCamera ) {
390
-
391
- const scale_x = ( scope.object.right - scope.object.left ) / scope.object.zoom / scope.domElement.clientWidth;
392
- const scale_y = ( scope.object.top - scope.object.bottom ) / scope.object.zoom / scope.domElement.clientWidth;
395
+ } else {
393
396
 
394
- mouseChange.x *= scale_x;
395
- mouseChange.y *= scale_y;
397
+ this._panStart.add( _mouseChange.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.dynamicDampingFactor ) );
396
398
 
397
- }
399
+ }
398
400
 
399
- mouseChange.multiplyScalar( _eye.length() * scope.panSpeed );
401
+ }
400
402
 
401
- pan.copy( _eye ).cross( scope.object.up ).setLength( mouseChange.x );
402
- pan.add( objectUp.copy( scope.object.up ).setLength( mouseChange.y ) );
403
+ }
403
404
 
404
- scope.object.position.add( pan );
405
- scope.target.add( pan );
405
+ _rotateCamera() {
406
406
 
407
- if ( scope.staticMoving ) {
407
+ _moveDirection.set( this._moveCurr.x - this._movePrev.x, this._moveCurr.y - this._movePrev.y, 0 );
408
+ let angle = _moveDirection.length();
408
409
 
409
- _panStart.copy( _panEnd );
410
+ if ( angle ) {
410
411
 
411
- } else {
412
+ this._eye.copy( this.object.position ).sub( this.target );
412
413
 
413
- _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( scope.dynamicDampingFactor ) );
414
+ _eyeDirection.copy( this._eye ).normalize();
415
+ _objectUpDirection.copy( this.object.up ).normalize();
416
+ _objectSidewaysDirection.crossVectors( _objectUpDirection, _eyeDirection ).normalize();
414
417
 
415
- }
418
+ _objectUpDirection.setLength( this._moveCurr.y - this._movePrev.y );
419
+ _objectSidewaysDirection.setLength( this._moveCurr.x - this._movePrev.x );
416
420
 
417
- }
421
+ _moveDirection.copy( _objectUpDirection.add( _objectSidewaysDirection ) );
418
422
 
419
- };
423
+ _axis.crossVectors( _moveDirection, this._eye ).normalize();
420
424
 
421
- }() );
425
+ angle *= this.rotateSpeed;
426
+ _quaternion.setFromAxisAngle( _axis, angle );
422
427
 
423
- this.checkDistances = function () {
428
+ this._eye.applyQuaternion( _quaternion );
429
+ this.object.up.applyQuaternion( _quaternion );
424
430
 
425
- if ( ! scope.noZoom || ! scope.noPan ) {
431
+ this._lastAxis.copy( _axis );
432
+ this._lastAngle = angle;
426
433
 
427
- if ( _eye.lengthSq() > scope.maxDistance * scope.maxDistance ) {
434
+ } else if ( ! this.staticMoving && this._lastAngle ) {
428
435
 
429
- scope.object.position.addVectors( scope.target, _eye.setLength( scope.maxDistance ) );
430
- _zoomStart.copy( _zoomEnd );
436
+ this._lastAngle *= Math.sqrt( 1.0 - this.dynamicDampingFactor );
437
+ this._eye.copy( this.object.position ).sub( this.target );
438
+ _quaternion.setFromAxisAngle( this._lastAxis, this._lastAngle );
439
+ this._eye.applyQuaternion( _quaternion );
440
+ this.object.up.applyQuaternion( _quaternion );
431
441
 
432
- }
442
+ }
433
443
 
434
- if ( _eye.lengthSq() < scope.minDistance * scope.minDistance ) {
444
+ this._movePrev.copy( this._moveCurr );
435
445
 
436
- scope.object.position.addVectors( scope.target, _eye.setLength( scope.minDistance ) );
437
- _zoomStart.copy( _zoomEnd );
446
+ }
438
447
 
439
- }
448
+ _zoomCamera() {
440
449
 
441
- }
450
+ let factor;
442
451
 
443
- };
452
+ if ( this.state === _STATE$1.TOUCH_ZOOM_PAN ) {
444
453
 
445
- this.update = function () {
454
+ factor = this._touchZoomDistanceStart / this._touchZoomDistanceEnd;
455
+ this._touchZoomDistanceStart = this._touchZoomDistanceEnd;
446
456
 
447
- _eye.subVectors( scope.object.position, scope.target );
457
+ if ( this.object.isPerspectiveCamera ) {
448
458
 
449
- if ( ! scope.noRotate ) {
459
+ this._eye.multiplyScalar( factor );
450
460
 
451
- scope.rotateCamera();
461
+ } else if ( this.object.isOrthographicCamera ) {
452
462
 
453
- }
463
+ this.object.zoom = three$1.MathUtils.clamp( this.object.zoom / factor, this.minZoom, this.maxZoom );
454
464
 
455
- if ( ! scope.noZoom ) {
465
+ if ( this._lastZoom !== this.object.zoom ) {
456
466
 
457
- scope.zoomCamera();
467
+ this.object.updateProjectionMatrix();
458
468
 
459
- }
469
+ }
460
470
 
461
- if ( ! scope.noPan ) {
471
+ } else {
462
472
 
463
- scope.panCamera();
473
+ console.warn( 'THREE.TrackballControls: Unsupported camera type' );
464
474
 
465
475
  }
466
476
 
467
- scope.object.position.addVectors( scope.target, _eye );
468
-
469
- if ( scope.object.isPerspectiveCamera ) {
477
+ } else {
470
478
 
471
- scope.checkDistances();
479
+ factor = 1.0 + ( this._zoomEnd.y - this._zoomStart.y ) * this.zoomSpeed;
472
480
 
473
- scope.object.lookAt( scope.target );
481
+ if ( factor !== 1.0 && factor > 0.0 ) {
474
482
 
475
- if ( lastPosition.distanceToSquared( scope.object.position ) > EPS ) {
483
+ if ( this.object.isPerspectiveCamera ) {
476
484
 
477
- scope.dispatchEvent( _changeEvent$2 );
485
+ this._eye.multiplyScalar( factor );
478
486
 
479
- lastPosition.copy( scope.object.position );
487
+ } else if ( this.object.isOrthographicCamera ) {
480
488
 
481
- }
489
+ this.object.zoom = three$1.MathUtils.clamp( this.object.zoom / factor, this.minZoom, this.maxZoom );
482
490
 
483
- } else if ( scope.object.isOrthographicCamera ) {
491
+ if ( this._lastZoom !== this.object.zoom ) {
484
492
 
485
- scope.object.lookAt( scope.target );
493
+ this.object.updateProjectionMatrix();
486
494
 
487
- if ( lastPosition.distanceToSquared( scope.object.position ) > EPS || lastZoom !== scope.object.zoom ) {
495
+ }
488
496
 
489
- scope.dispatchEvent( _changeEvent$2 );
497
+ } else {
490
498
 
491
- lastPosition.copy( scope.object.position );
492
- lastZoom = scope.object.zoom;
499
+ console.warn( 'THREE.TrackballControls: Unsupported camera type' );
493
500
 
494
501
  }
495
502
 
496
- } else {
497
-
498
- console.warn( 'THREE.TrackballControls: Unsupported camera type' );
499
-
500
503
  }
501
504
 
502
- };
505
+ if ( this.staticMoving ) {
503
506
 
504
- this.reset = function () {
507
+ this._zoomStart.copy( this._zoomEnd );
505
508
 
506
- _state = STATE.NONE;
507
- _keyState = STATE.NONE;
509
+ } else {
508
510
 
509
- scope.target.copy( scope.target0 );
510
- scope.object.position.copy( scope.position0 );
511
- scope.object.up.copy( scope.up0 );
512
- scope.object.zoom = scope.zoom0;
511
+ this._zoomStart.y += ( this._zoomEnd.y - this._zoomStart.y ) * this.dynamicDampingFactor;
513
512
 
514
- scope.object.updateProjectionMatrix();
513
+ }
515
514
 
516
- _eye.subVectors( scope.object.position, scope.target );
515
+ }
517
516
 
518
- scope.object.lookAt( scope.target );
517
+ }
519
518
 
520
- scope.dispatchEvent( _changeEvent$2 );
519
+ _getMouseOnScreen( pageX, pageY ) {
521
520
 
522
- lastPosition.copy( scope.object.position );
523
- lastZoom = scope.object.zoom;
521
+ _v2.set(
522
+ ( pageX - this.screen.left ) / this.screen.width,
523
+ ( pageY - this.screen.top ) / this.screen.height
524
+ );
524
525
 
525
- };
526
+ return _v2;
526
527
 
527
- // listeners
528
+ }
528
529
 
529
- function onPointerDown( event ) {
530
+ _getMouseOnCircle( pageX, pageY ) {
530
531
 
531
- if ( scope.enabled === false ) return;
532
+ _v2.set(
533
+ ( ( pageX - this.screen.width * 0.5 - this.screen.left ) / ( this.screen.width * 0.5 ) ),
534
+ ( ( this.screen.height + 2 * ( this.screen.top - pageY ) ) / this.screen.width ) // screen.width intentional
535
+ );
532
536
 
533
- if ( _pointers.length === 0 ) {
537
+ return _v2;
534
538
 
535
- scope.domElement.setPointerCapture( event.pointerId );
539
+ }
536
540
 
537
- scope.domElement.addEventListener( 'pointermove', onPointerMove );
538
- scope.domElement.addEventListener( 'pointerup', onPointerUp );
541
+ _addPointer( event ) {
539
542
 
540
- }
543
+ this._pointers.push( event );
541
544
 
542
- //
545
+ }
543
546
 
544
- addPointer( event );
547
+ _removePointer( event ) {
545
548
 
546
- if ( event.pointerType === 'touch' ) {
549
+ delete this._pointerPositions[ event.pointerId ];
547
550
 
548
- onTouchStart( event );
551
+ for ( let i = 0; i < this._pointers.length; i ++ ) {
549
552
 
550
- } else {
553
+ if ( this._pointers[ i ].pointerId == event.pointerId ) {
551
554
 
552
- onMouseDown( event );
555
+ this._pointers.splice( i, 1 );
556
+ return;
553
557
 
554
558
  }
555
559
 
556
560
  }
557
561
 
558
- function onPointerMove( event ) {
559
-
560
- if ( scope.enabled === false ) return;
561
-
562
- if ( event.pointerType === 'touch' ) {
562
+ }
563
563
 
564
- onTouchMove( event );
564
+ _trackPointer( event ) {
565
565
 
566
- } else {
566
+ let position = this._pointerPositions[ event.pointerId ];
567
567
 
568
- onMouseMove( event );
568
+ if ( position === undefined ) {
569
569
 
570
- }
570
+ position = new three$1.Vector2();
571
+ this._pointerPositions[ event.pointerId ] = position;
571
572
 
572
573
  }
573
574
 
574
- function onPointerUp( event ) {
575
+ position.set( event.pageX, event.pageY );
575
576
 
576
- if ( scope.enabled === false ) return;
577
+ }
577
578
 
578
- if ( event.pointerType === 'touch' ) {
579
+ _getSecondPointerPosition( event ) {
579
580
 
580
- onTouchEnd( event );
581
+ const pointer = ( event.pointerId === this._pointers[ 0 ].pointerId ) ? this._pointers[ 1 ] : this._pointers[ 0 ];
581
582
 
582
- } else {
583
+ return this._pointerPositions[ pointer.pointerId ];
583
584
 
584
- onMouseUp();
585
+ }
585
586
 
586
- }
587
+ _checkDistances() {
587
588
 
588
- //
589
+ if ( ! this.noZoom || ! this.noPan ) {
589
590
 
590
- removePointer( event );
591
+ if ( this._eye.lengthSq() > this.maxDistance * this.maxDistance ) {
591
592
 
592
- if ( _pointers.length === 0 ) {
593
+ this.object.position.addVectors( this.target, this._eye.setLength( this.maxDistance ) );
594
+ this._zoomStart.copy( this._zoomEnd );
593
595
 
594
- scope.domElement.releasePointerCapture( event.pointerId );
596
+ }
595
597
 
596
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
597
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
598
+ if ( this._eye.lengthSq() < this.minDistance * this.minDistance ) {
598
599
 
599
- }
600
+ this.object.position.addVectors( this.target, this._eye.setLength( this.minDistance ) );
601
+ this._zoomStart.copy( this._zoomEnd );
600
602
 
603
+ }
601
604
 
602
605
  }
603
606
 
604
- function onPointerCancel( event ) {
607
+ }
605
608
 
606
- removePointer( event );
609
+ }
607
610
 
608
- }
611
+ function onPointerDown$2( event ) {
609
612
 
610
- function keydown( event ) {
613
+ if ( this.enabled === false ) return;
611
614
 
612
- if ( scope.enabled === false ) return;
615
+ if ( this._pointers.length === 0 ) {
613
616
 
614
- window.removeEventListener( 'keydown', keydown );
617
+ this.domElement.setPointerCapture( event.pointerId );
615
618
 
616
- if ( _keyState !== STATE.NONE ) {
619
+ this.domElement.addEventListener( 'pointermove', this._onPointerMove );
620
+ this.domElement.addEventListener( 'pointerup', this._onPointerUp );
617
621
 
618
- return;
622
+ }
619
623
 
620
- } else if ( event.code === scope.keys[ STATE.ROTATE ] && ! scope.noRotate ) {
624
+ //
621
625
 
622
- _keyState = STATE.ROTATE;
626
+ this._addPointer( event );
623
627
 
624
- } else if ( event.code === scope.keys[ STATE.ZOOM ] && ! scope.noZoom ) {
628
+ if ( event.pointerType === 'touch' ) {
625
629
 
626
- _keyState = STATE.ZOOM;
630
+ this._onTouchStart( event );
627
631
 
628
- } else if ( event.code === scope.keys[ STATE.PAN ] && ! scope.noPan ) {
632
+ } else {
629
633
 
630
- _keyState = STATE.PAN;
634
+ this._onMouseDown( event );
631
635
 
632
- }
636
+ }
633
637
 
634
- }
638
+ }
635
639
 
636
- function keyup() {
640
+ function onPointerMove$2( event ) {
637
641
 
638
- if ( scope.enabled === false ) return;
642
+ if ( this.enabled === false ) return;
639
643
 
640
- _keyState = STATE.NONE;
644
+ if ( event.pointerType === 'touch' ) {
641
645
 
642
- window.addEventListener( 'keydown', keydown );
646
+ this._onTouchMove( event );
643
647
 
644
- }
648
+ } else {
645
649
 
646
- function onMouseDown( event ) {
650
+ this._onMouseMove( event );
647
651
 
648
- if ( _state === STATE.NONE ) {
652
+ }
649
653
 
650
- switch ( event.button ) {
654
+ }
651
655
 
652
- case scope.mouseButtons.LEFT:
653
- _state = STATE.ROTATE;
654
- break;
656
+ function onPointerUp$2( event ) {
655
657
 
656
- case scope.mouseButtons.MIDDLE:
657
- _state = STATE.ZOOM;
658
- break;
658
+ if ( this.enabled === false ) return;
659
659
 
660
- case scope.mouseButtons.RIGHT:
661
- _state = STATE.PAN;
662
- break;
660
+ if ( event.pointerType === 'touch' ) {
663
661
 
664
- }
662
+ this._onTouchEnd( event );
665
663
 
666
- }
664
+ } else {
667
665
 
668
- const state = ( _keyState !== STATE.NONE ) ? _keyState : _state;
666
+ this._onMouseUp();
669
667
 
670
- if ( state === STATE.ROTATE && ! scope.noRotate ) {
668
+ }
671
669
 
672
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
673
- _movePrev.copy( _moveCurr );
670
+ //
674
671
 
675
- } else if ( state === STATE.ZOOM && ! scope.noZoom ) {
672
+ this._removePointer( event );
676
673
 
677
- _zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
678
- _zoomEnd.copy( _zoomStart );
674
+ if ( this._pointers.length === 0 ) {
679
675
 
680
- } else if ( state === STATE.PAN && ! scope.noPan ) {
676
+ this.domElement.releasePointerCapture( event.pointerId );
681
677
 
682
- _panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );
683
- _panEnd.copy( _panStart );
678
+ this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
679
+ this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
684
680
 
685
- }
681
+ }
686
682
 
687
- scope.dispatchEvent( _startEvent$1 );
683
+ }
688
684
 
689
- }
685
+ function onPointerCancel$1( event ) {
690
686
 
691
- function onMouseMove( event ) {
687
+ this._removePointer( event );
692
688
 
693
- const state = ( _keyState !== STATE.NONE ) ? _keyState : _state;
689
+ }
694
690
 
695
- if ( state === STATE.ROTATE && ! scope.noRotate ) {
691
+ function onKeyUp$1() {
696
692
 
697
- _movePrev.copy( _moveCurr );
698
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
693
+ if ( this.enabled === false ) return;
699
694
 
700
- } else if ( state === STATE.ZOOM && ! scope.noZoom ) {
695
+ this.keyState = _STATE$1.NONE;
701
696
 
702
- _zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
697
+ window.addEventListener( 'keydown', this._onKeyDown );
703
698
 
704
- } else if ( state === STATE.PAN && ! scope.noPan ) {
699
+ }
705
700
 
706
- _panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );
701
+ function onKeyDown$2( event ) {
707
702
 
708
- }
703
+ if ( this.enabled === false ) return;
709
704
 
710
- }
705
+ window.removeEventListener( 'keydown', this._onKeyDown );
711
706
 
712
- function onMouseUp() {
707
+ if ( this.keyState !== _STATE$1.NONE ) {
713
708
 
714
- _state = STATE.NONE;
709
+ return;
715
710
 
716
- scope.dispatchEvent( _endEvent$1 );
711
+ } else if ( event.code === this.keys[ _STATE$1.ROTATE ] && ! this.noRotate ) {
717
712
 
718
- }
713
+ this.keyState = _STATE$1.ROTATE;
719
714
 
720
- function onMouseWheel( event ) {
715
+ } else if ( event.code === this.keys[ _STATE$1.ZOOM ] && ! this.noZoom ) {
721
716
 
722
- if ( scope.enabled === false ) return;
717
+ this.keyState = _STATE$1.ZOOM;
723
718
 
724
- if ( scope.noZoom === true ) return;
719
+ } else if ( event.code === this.keys[ _STATE$1.PAN ] && ! this.noPan ) {
725
720
 
726
- event.preventDefault();
721
+ this.keyState = _STATE$1.PAN;
727
722
 
728
- switch ( event.deltaMode ) {
723
+ }
729
724
 
730
- case 2:
731
- // Zoom in pages
732
- _zoomStart.y -= event.deltaY * 0.025;
733
- break;
725
+ }
734
726
 
735
- case 1:
736
- // Zoom in lines
737
- _zoomStart.y -= event.deltaY * 0.01;
738
- break;
727
+ function onMouseDown$1( event ) {
739
728
 
740
- default:
741
- // undefined, 0, assume pixels
742
- _zoomStart.y -= event.deltaY * 0.00025;
743
- break;
729
+ if ( this.state === _STATE$1.NONE ) {
744
730
 
745
- }
731
+ switch ( event.button ) {
746
732
 
747
- scope.dispatchEvent( _startEvent$1 );
748
- scope.dispatchEvent( _endEvent$1 );
733
+ case this.mouseButtons.LEFT:
734
+ this.state = _STATE$1.ROTATE;
735
+ break;
749
736
 
750
- }
737
+ case this.mouseButtons.MIDDLE:
738
+ this.state = _STATE$1.ZOOM;
739
+ break;
751
740
 
752
- function onTouchStart( event ) {
741
+ case this.mouseButtons.RIGHT:
742
+ this.state = _STATE$1.PAN;
743
+ break;
753
744
 
754
- trackPointer( event );
745
+ }
755
746
 
756
- switch ( _pointers.length ) {
747
+ }
757
748
 
758
- case 1:
759
- _state = STATE.TOUCH_ROTATE;
760
- _moveCurr.copy( getMouseOnCircle( _pointers[ 0 ].pageX, _pointers[ 0 ].pageY ) );
761
- _movePrev.copy( _moveCurr );
762
- break;
749
+ const state = ( this.keyState !== _STATE$1.NONE ) ? this.keyState : this.state;
763
750
 
764
- default: // 2 or more
765
- _state = STATE.TOUCH_ZOOM_PAN;
766
- const dx = _pointers[ 0 ].pageX - _pointers[ 1 ].pageX;
767
- const dy = _pointers[ 0 ].pageY - _pointers[ 1 ].pageY;
768
- _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
751
+ if ( state === _STATE$1.ROTATE && ! this.noRotate ) {
769
752
 
770
- const x = ( _pointers[ 0 ].pageX + _pointers[ 1 ].pageX ) / 2;
771
- const y = ( _pointers[ 0 ].pageY + _pointers[ 1 ].pageY ) / 2;
772
- _panStart.copy( getMouseOnScreen( x, y ) );
773
- _panEnd.copy( _panStart );
774
- break;
753
+ this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
754
+ this._movePrev.copy( this._moveCurr );
775
755
 
776
- }
756
+ } else if ( state === _STATE$1.ZOOM && ! this.noZoom ) {
777
757
 
778
- scope.dispatchEvent( _startEvent$1 );
758
+ this._zoomStart.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
759
+ this._zoomEnd.copy( this._zoomStart );
779
760
 
780
- }
761
+ } else if ( state === _STATE$1.PAN && ! this.noPan ) {
781
762
 
782
- function onTouchMove( event ) {
763
+ this._panStart.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
764
+ this._panEnd.copy( this._panStart );
783
765
 
784
- trackPointer( event );
766
+ }
785
767
 
786
- switch ( _pointers.length ) {
768
+ this.dispatchEvent( _startEvent$1 );
787
769
 
788
- case 1:
789
- _movePrev.copy( _moveCurr );
790
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
791
- break;
770
+ }
792
771
 
793
- default: // 2 or more
772
+ function onMouseMove$1( event ) {
794
773
 
795
- const position = getSecondPointerPosition( event );
774
+ const state = ( this.keyState !== _STATE$1.NONE ) ? this.keyState : this.state;
796
775
 
797
- const dx = event.pageX - position.x;
798
- const dy = event.pageY - position.y;
799
- _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
776
+ if ( state === _STATE$1.ROTATE && ! this.noRotate ) {
800
777
 
801
- const x = ( event.pageX + position.x ) / 2;
802
- const y = ( event.pageY + position.y ) / 2;
803
- _panEnd.copy( getMouseOnScreen( x, y ) );
804
- break;
778
+ this._movePrev.copy( this._moveCurr );
779
+ this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
805
780
 
806
- }
781
+ } else if ( state === _STATE$1.ZOOM && ! this.noZoom ) {
807
782
 
808
- }
783
+ this._zoomEnd.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
809
784
 
810
- function onTouchEnd( event ) {
785
+ } else if ( state === _STATE$1.PAN && ! this.noPan ) {
811
786
 
812
- switch ( _pointers.length ) {
787
+ this._panEnd.copy( this._getMouseOnScreen( event.pageX, event.pageY ) );
813
788
 
814
- case 0:
815
- _state = STATE.NONE;
816
- break;
789
+ }
817
790
 
818
- case 1:
819
- _state = STATE.TOUCH_ROTATE;
820
- _moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );
821
- _movePrev.copy( _moveCurr );
822
- break;
791
+ }
823
792
 
824
- case 2:
825
- _state = STATE.TOUCH_ZOOM_PAN;
793
+ function onMouseUp() {
826
794
 
827
- for ( let i = 0; i < _pointers.length; i ++ ) {
795
+ this.state = _STATE$1.NONE;
828
796
 
829
- if ( _pointers[ i ].pointerId !== event.pointerId ) {
797
+ this.dispatchEvent( _endEvent$1 );
830
798
 
831
- const position = _pointerPositions[ _pointers[ i ].pointerId ];
832
- _moveCurr.copy( getMouseOnCircle( position.x, position.y ) );
833
- _movePrev.copy( _moveCurr );
834
- break;
799
+ }
835
800
 
836
- }
801
+ function onMouseWheel$1( event ) {
837
802
 
838
- }
803
+ if ( this.enabled === false ) return;
839
804
 
840
- break;
805
+ if ( this.noZoom === true ) return;
841
806
 
842
- }
807
+ event.preventDefault();
843
808
 
844
- scope.dispatchEvent( _endEvent$1 );
809
+ switch ( event.deltaMode ) {
845
810
 
846
- }
811
+ case 2:
812
+ // Zoom in pages
813
+ this._zoomStart.y -= event.deltaY * 0.025;
814
+ break;
847
815
 
848
- function contextmenu( event ) {
816
+ case 1:
817
+ // Zoom in lines
818
+ this._zoomStart.y -= event.deltaY * 0.01;
819
+ break;
849
820
 
850
- if ( scope.enabled === false ) return;
821
+ default:
822
+ // undefined, 0, assume pixels
823
+ this._zoomStart.y -= event.deltaY * 0.00025;
824
+ break;
851
825
 
852
- event.preventDefault();
826
+ }
853
827
 
854
- }
828
+ this.dispatchEvent( _startEvent$1 );
829
+ this.dispatchEvent( _endEvent$1 );
855
830
 
856
- function addPointer( event ) {
831
+ }
857
832
 
858
- _pointers.push( event );
833
+ function onContextMenu$2( event ) {
859
834
 
860
- }
835
+ if ( this.enabled === false ) return;
861
836
 
862
- function removePointer( event ) {
837
+ event.preventDefault();
863
838
 
864
- delete _pointerPositions[ event.pointerId ];
839
+ }
865
840
 
866
- for ( let i = 0; i < _pointers.length; i ++ ) {
841
+ function onTouchStart$1( event ) {
867
842
 
868
- if ( _pointers[ i ].pointerId == event.pointerId ) {
843
+ this._trackPointer( event );
869
844
 
870
- _pointers.splice( i, 1 );
871
- return;
845
+ switch ( this._pointers.length ) {
872
846
 
873
- }
847
+ case 1:
848
+ this.state = _STATE$1.TOUCH_ROTATE;
849
+ this._moveCurr.copy( this._getMouseOnCircle( this._pointers[ 0 ].pageX, this._pointers[ 0 ].pageY ) );
850
+ this._movePrev.copy( this._moveCurr );
851
+ break;
874
852
 
875
- }
853
+ default: // 2 or more
854
+ this.state = _STATE$1.TOUCH_ZOOM_PAN;
855
+ const dx = this._pointers[ 0 ].pageX - this._pointers[ 1 ].pageX;
856
+ const dy = this._pointers[ 0 ].pageY - this._pointers[ 1 ].pageY;
857
+ this._touchZoomDistanceEnd = this._touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
876
858
 
877
- }
859
+ const x = ( this._pointers[ 0 ].pageX + this._pointers[ 1 ].pageX ) / 2;
860
+ const y = ( this._pointers[ 0 ].pageY + this._pointers[ 1 ].pageY ) / 2;
861
+ this._panStart.copy( this._getMouseOnScreen( x, y ) );
862
+ this._panEnd.copy( this._panStart );
863
+ break;
878
864
 
879
- function trackPointer( event ) {
865
+ }
880
866
 
881
- let position = _pointerPositions[ event.pointerId ];
867
+ this.dispatchEvent( _startEvent$1 );
882
868
 
883
- if ( position === undefined ) {
869
+ }
884
870
 
885
- position = new three$1.Vector2();
886
- _pointerPositions[ event.pointerId ] = position;
871
+ function onTouchMove$1( event ) {
887
872
 
888
- }
873
+ this._trackPointer( event );
889
874
 
890
- position.set( event.pageX, event.pageY );
875
+ switch ( this._pointers.length ) {
891
876
 
892
- }
877
+ case 1:
878
+ this._movePrev.copy( this._moveCurr );
879
+ this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
880
+ break;
893
881
 
894
- function getSecondPointerPosition( event ) {
882
+ default: // 2 or more
895
883
 
896
- const pointer = ( event.pointerId === _pointers[ 0 ].pointerId ) ? _pointers[ 1 ] : _pointers[ 0 ];
884
+ const position = this._getSecondPointerPosition( event );
897
885
 
898
- return _pointerPositions[ pointer.pointerId ];
886
+ const dx = event.pageX - position.x;
887
+ const dy = event.pageY - position.y;
888
+ this._touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );
899
889
 
900
- }
890
+ const x = ( event.pageX + position.x ) / 2;
891
+ const y = ( event.pageY + position.y ) / 2;
892
+ this._panEnd.copy( this._getMouseOnScreen( x, y ) );
893
+ break;
901
894
 
902
- this.dispose = function () {
895
+ }
903
896
 
904
- scope.domElement.removeEventListener( 'contextmenu', contextmenu );
897
+ }
905
898
 
906
- scope.domElement.removeEventListener( 'pointerdown', onPointerDown );
907
- scope.domElement.removeEventListener( 'pointercancel', onPointerCancel );
908
- scope.domElement.removeEventListener( 'wheel', onMouseWheel );
899
+ function onTouchEnd( event ) {
909
900
 
910
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
911
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
901
+ switch ( this._pointers.length ) {
912
902
 
913
- window.removeEventListener( 'keydown', keydown );
914
- window.removeEventListener( 'keyup', keyup );
903
+ case 0:
904
+ this.state = _STATE$1.NONE;
905
+ break;
915
906
 
916
- };
907
+ case 1:
908
+ this.state = _STATE$1.TOUCH_ROTATE;
909
+ this._moveCurr.copy( this._getMouseOnCircle( event.pageX, event.pageY ) );
910
+ this._movePrev.copy( this._moveCurr );
911
+ break;
912
+
913
+ case 2:
914
+ this.state = _STATE$1.TOUCH_ZOOM_PAN;
917
915
 
918
- this.domElement.addEventListener( 'contextmenu', contextmenu );
916
+ for ( let i = 0; i < this._pointers.length; i ++ ) {
919
917
 
920
- this.domElement.addEventListener( 'pointerdown', onPointerDown );
921
- this.domElement.addEventListener( 'pointercancel', onPointerCancel );
922
- this.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );
918
+ if ( this._pointers[ i ].pointerId !== event.pointerId ) {
923
919
 
920
+ const position = this._pointerPositions[ this._pointers[ i ].pointerId ];
921
+ this._moveCurr.copy( this._getMouseOnCircle( position.x, position.y ) );
922
+ this._movePrev.copy( this._moveCurr );
923
+ break;
924
924
 
925
- window.addEventListener( 'keydown', keydown );
926
- window.addEventListener( 'keyup', keyup );
925
+ }
927
926
 
928
- this.handleResize();
927
+ }
929
928
 
930
- // force an update at start
931
- this.update();
929
+ break;
932
930
 
933
931
  }
934
932
 
933
+ this.dispatchEvent( _endEvent$1 );
934
+
935
935
  }
936
936
 
937
937
  // OrbitControls performs orbiting, dollying (zooming), and panning.
@@ -946,17 +946,30 @@
946
946
  const _endEvent = { type: 'end' };
947
947
  const _ray = new three$1.Ray();
948
948
  const _plane = new three$1.Plane();
949
- const TILT_LIMIT = Math.cos( 70 * three$1.MathUtils.DEG2RAD );
949
+ const _TILT_LIMIT = Math.cos( 70 * three$1.MathUtils.DEG2RAD );
950
+
951
+ const _v = new three$1.Vector3();
952
+ const _twoPI = 2 * Math.PI;
953
+
954
+ const _STATE = {
955
+ NONE: - 1,
956
+ ROTATE: 0,
957
+ DOLLY: 1,
958
+ PAN: 2,
959
+ TOUCH_ROTATE: 3,
960
+ TOUCH_PAN: 4,
961
+ TOUCH_DOLLY_PAN: 5,
962
+ TOUCH_DOLLY_ROTATE: 6
963
+ };
964
+ const _EPS$1 = 0.000001;
950
965
 
951
- class OrbitControls extends three$1.EventDispatcher {
966
+ class OrbitControls extends three$1.Controls {
952
967
 
953
- constructor( object, domElement ) {
968
+ constructor( object, domElement = null ) {
954
969
 
955
- super();
970
+ super( object, domElement );
956
971
 
957
- this.object = object;
958
- this.domElement = domElement;
959
- this.domElement.style.touchAction = 'none'; // disable touch scroll
972
+ this.state = _STATE.NONE;
960
973
 
961
974
  // Set to false to disable this control
962
975
  this.enabled = true;
@@ -1032,1421 +1045,1399 @@
1032
1045
  // the target DOM element for key events
1033
1046
  this._domElementKeyEvents = null;
1034
1047
 
1035
- //
1036
- // public methods
1037
- //
1048
+ // internals
1038
1049
 
1039
- this.getPolarAngle = function () {
1050
+ this._lastPosition = new three$1.Vector3();
1051
+ this._lastQuaternion = new three$1.Quaternion();
1052
+ this._lastTargetPosition = new three$1.Vector3();
1040
1053
 
1041
- return spherical.phi;
1054
+ // so camera.up is the orbit axis
1055
+ this._quat = new three$1.Quaternion().setFromUnitVectors( object.up, new three$1.Vector3( 0, 1, 0 ) );
1056
+ this._quatInverse = this._quat.clone().invert();
1042
1057
 
1043
- };
1058
+ // current position in spherical coordinates
1059
+ this._spherical = new three$1.Spherical();
1060
+ this._sphericalDelta = new three$1.Spherical();
1044
1061
 
1045
- this.getAzimuthalAngle = function () {
1062
+ this._scale = 1;
1063
+ this._panOffset = new three$1.Vector3();
1046
1064
 
1047
- return spherical.theta;
1065
+ this._rotateStart = new three$1.Vector2();
1066
+ this._rotateEnd = new three$1.Vector2();
1067
+ this._rotateDelta = new three$1.Vector2();
1048
1068
 
1049
- };
1069
+ this._panStart = new three$1.Vector2();
1070
+ this._panEnd = new three$1.Vector2();
1071
+ this._panDelta = new three$1.Vector2();
1050
1072
 
1051
- this.getDistance = function () {
1073
+ this._dollyStart = new three$1.Vector2();
1074
+ this._dollyEnd = new three$1.Vector2();
1075
+ this._dollyDelta = new three$1.Vector2();
1052
1076
 
1053
- return this.object.position.distanceTo( this.target );
1077
+ this._dollyDirection = new three$1.Vector3();
1078
+ this._mouse = new three$1.Vector2();
1079
+ this._performCursorZoom = false;
1054
1080
 
1055
- };
1081
+ this._pointers = [];
1082
+ this._pointerPositions = {};
1056
1083
 
1057
- this.listenToKeyEvents = function ( domElement ) {
1084
+ this._controlActive = false;
1058
1085
 
1059
- domElement.addEventListener( 'keydown', onKeyDown );
1060
- this._domElementKeyEvents = domElement;
1086
+ // event listeners
1061
1087
 
1062
- };
1088
+ this._onPointerMove = onPointerMove$1.bind( this );
1089
+ this._onPointerDown = onPointerDown$1.bind( this );
1090
+ this._onPointerUp = onPointerUp$1.bind( this );
1091
+ this._onContextMenu = onContextMenu$1.bind( this );
1092
+ this._onMouseWheel = onMouseWheel.bind( this );
1093
+ this._onKeyDown = onKeyDown$1.bind( this );
1063
1094
 
1064
- this.stopListenToKeyEvents = function () {
1095
+ this._onTouchStart = onTouchStart.bind( this );
1096
+ this._onTouchMove = onTouchMove.bind( this );
1065
1097
 
1066
- this._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );
1067
- this._domElementKeyEvents = null;
1098
+ this._onMouseDown = onMouseDown.bind( this );
1099
+ this._onMouseMove = onMouseMove.bind( this );
1068
1100
 
1069
- };
1101
+ this._interceptControlDown = interceptControlDown.bind( this );
1102
+ this._interceptControlUp = interceptControlUp.bind( this );
1070
1103
 
1071
- this.saveState = function () {
1104
+ //
1072
1105
 
1073
- scope.target0.copy( scope.target );
1074
- scope.position0.copy( scope.object.position );
1075
- scope.zoom0 = scope.object.zoom;
1106
+ if ( this.domElement !== null ) {
1076
1107
 
1077
- };
1108
+ this.connect();
1078
1109
 
1079
- this.reset = function () {
1110
+ }
1080
1111
 
1081
- scope.target.copy( scope.target0 );
1082
- scope.object.position.copy( scope.position0 );
1083
- scope.object.zoom = scope.zoom0;
1112
+ this.update();
1084
1113
 
1085
- scope.object.updateProjectionMatrix();
1086
- scope.dispatchEvent( _changeEvent$1 );
1114
+ }
1087
1115
 
1088
- scope.update();
1116
+ connect() {
1089
1117
 
1090
- state = STATE.NONE;
1118
+ this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
1119
+ this.domElement.addEventListener( 'pointercancel', this._onPointerUp );
1091
1120
 
1092
- };
1121
+ this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
1122
+ this.domElement.addEventListener( 'wheel', this._onMouseWheel, { passive: false } );
1093
1123
 
1094
- // this method is exposed, but perhaps it would be better if we can make it private...
1095
- this.update = function () {
1124
+ const document = this.domElement.getRootNode(); // offscreen canvas compatibility
1125
+ document.addEventListener( 'keydown', this._interceptControlDown, { passive: true, capture: true } );
1096
1126
 
1097
- const offset = new three$1.Vector3();
1127
+ this.domElement.style.touchAction = 'none'; // disable touch scroll
1098
1128
 
1099
- // so camera.up is the orbit axis
1100
- const quat = new three$1.Quaternion().setFromUnitVectors( object.up, new three$1.Vector3( 0, 1, 0 ) );
1101
- const quatInverse = quat.clone().invert();
1129
+ }
1102
1130
 
1103
- const lastPosition = new three$1.Vector3();
1104
- const lastQuaternion = new three$1.Quaternion();
1105
- const lastTargetPosition = new three$1.Vector3();
1131
+ disconnect() {
1106
1132
 
1107
- const twoPI = 2 * Math.PI;
1133
+ this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
1134
+ this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
1135
+ this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
1136
+ this.domElement.removeEventListener( 'pointercancel', this._onPointerUp );
1108
1137
 
1109
- return function update( deltaTime = null ) {
1138
+ this.domElement.removeEventListener( 'wheel', this._onMouseWheel );
1139
+ this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
1110
1140
 
1111
- const position = scope.object.position;
1141
+ this.stopListenToKeyEvents();
1112
1142
 
1113
- offset.copy( position ).sub( scope.target );
1143
+ const document = this.domElement.getRootNode(); // offscreen canvas compatibility
1144
+ document.removeEventListener( 'keydown', this._interceptControlDown, { capture: true } );
1114
1145
 
1115
- // rotate offset to "y-axis-is-up" space
1116
- offset.applyQuaternion( quat );
1146
+ this.domElement.style.touchAction = 'auto';
1117
1147
 
1118
- // angle from z-axis around y-axis
1119
- spherical.setFromVector3( offset );
1148
+ }
1120
1149
 
1121
- if ( scope.autoRotate && state === STATE.NONE ) {
1150
+ dispose() {
1122
1151
 
1123
- rotateLeft( getAutoRotationAngle( deltaTime ) );
1152
+ this.disconnect();
1124
1153
 
1125
- }
1154
+ }
1126
1155
 
1127
- if ( scope.enableDamping ) {
1156
+ getPolarAngle() {
1128
1157
 
1129
- spherical.theta += sphericalDelta.theta * scope.dampingFactor;
1130
- spherical.phi += sphericalDelta.phi * scope.dampingFactor;
1158
+ return this._spherical.phi;
1131
1159
 
1132
- } else {
1160
+ }
1133
1161
 
1134
- spherical.theta += sphericalDelta.theta;
1135
- spherical.phi += sphericalDelta.phi;
1162
+ getAzimuthalAngle() {
1136
1163
 
1137
- }
1164
+ return this._spherical.theta;
1138
1165
 
1139
- // restrict theta to be between desired limits
1166
+ }
1140
1167
 
1141
- let min = scope.minAzimuthAngle;
1142
- let max = scope.maxAzimuthAngle;
1168
+ getDistance() {
1143
1169
 
1144
- if ( isFinite( min ) && isFinite( max ) ) {
1170
+ return this.object.position.distanceTo( this.target );
1145
1171
 
1146
- if ( min < - Math.PI ) min += twoPI; else if ( min > Math.PI ) min -= twoPI;
1172
+ }
1147
1173
 
1148
- if ( max < - Math.PI ) max += twoPI; else if ( max > Math.PI ) max -= twoPI;
1174
+ listenToKeyEvents( domElement ) {
1149
1175
 
1150
- if ( min <= max ) {
1176
+ domElement.addEventListener( 'keydown', this._onKeyDown );
1177
+ this._domElementKeyEvents = domElement;
1151
1178
 
1152
- spherical.theta = Math.max( min, Math.min( max, spherical.theta ) );
1179
+ }
1153
1180
 
1154
- } else {
1181
+ stopListenToKeyEvents() {
1155
1182
 
1156
- spherical.theta = ( spherical.theta > ( min + max ) / 2 ) ?
1157
- Math.max( min, spherical.theta ) :
1158
- Math.min( max, spherical.theta );
1183
+ if ( this._domElementKeyEvents !== null ) {
1159
1184
 
1160
- }
1185
+ this._domElementKeyEvents.removeEventListener( 'keydown', this._onKeyDown );
1186
+ this._domElementKeyEvents = null;
1161
1187
 
1162
- }
1188
+ }
1163
1189
 
1164
- // restrict phi to be between desired limits
1165
- spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
1190
+ }
1166
1191
 
1167
- spherical.makeSafe();
1192
+ saveState() {
1168
1193
 
1194
+ this.target0.copy( this.target );
1195
+ this.position0.copy( this.object.position );
1196
+ this.zoom0 = this.object.zoom;
1169
1197
 
1170
- // move target to panned location
1198
+ }
1171
1199
 
1172
- if ( scope.enableDamping === true ) {
1200
+ reset() {
1173
1201
 
1174
- scope.target.addScaledVector( panOffset, scope.dampingFactor );
1202
+ this.target.copy( this.target0 );
1203
+ this.object.position.copy( this.position0 );
1204
+ this.object.zoom = this.zoom0;
1175
1205
 
1176
- } else {
1206
+ this.object.updateProjectionMatrix();
1207
+ this.dispatchEvent( _changeEvent$1 );
1177
1208
 
1178
- scope.target.add( panOffset );
1209
+ this.update();
1179
1210
 
1180
- }
1211
+ this.state = _STATE.NONE;
1181
1212
 
1182
- // Limit the target distance from the cursor to create a sphere around the center of interest
1183
- scope.target.sub( scope.cursor );
1184
- scope.target.clampLength( scope.minTargetRadius, scope.maxTargetRadius );
1185
- scope.target.add( scope.cursor );
1213
+ }
1186
1214
 
1187
- let zoomChanged = false;
1188
- // adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera
1189
- // we adjust zoom later in these cases
1190
- if ( scope.zoomToCursor && performCursorZoom || scope.object.isOrthographicCamera ) {
1215
+ update( deltaTime = null ) {
1191
1216
 
1192
- spherical.radius = clampDistance( spherical.radius );
1217
+ const position = this.object.position;
1193
1218
 
1194
- } else {
1219
+ _v.copy( position ).sub( this.target );
1195
1220
 
1196
- const prevRadius = spherical.radius;
1197
- spherical.radius = clampDistance( spherical.radius * scale );
1198
- zoomChanged = prevRadius != spherical.radius;
1221
+ // rotate offset to "y-axis-is-up" space
1222
+ _v.applyQuaternion( this._quat );
1199
1223
 
1200
- }
1224
+ // angle from z-axis around y-axis
1225
+ this._spherical.setFromVector3( _v );
1201
1226
 
1202
- offset.setFromSpherical( spherical );
1227
+ if ( this.autoRotate && this.state === _STATE.NONE ) {
1203
1228
 
1204
- // rotate offset back to "camera-up-vector-is-up" space
1205
- offset.applyQuaternion( quatInverse );
1229
+ this._rotateLeft( this._getAutoRotationAngle( deltaTime ) );
1206
1230
 
1207
- position.copy( scope.target ).add( offset );
1231
+ }
1208
1232
 
1209
- scope.object.lookAt( scope.target );
1233
+ if ( this.enableDamping ) {
1210
1234
 
1211
- if ( scope.enableDamping === true ) {
1235
+ this._spherical.theta += this._sphericalDelta.theta * this.dampingFactor;
1236
+ this._spherical.phi += this._sphericalDelta.phi * this.dampingFactor;
1212
1237
 
1213
- sphericalDelta.theta *= ( 1 - scope.dampingFactor );
1214
- sphericalDelta.phi *= ( 1 - scope.dampingFactor );
1238
+ } else {
1215
1239
 
1216
- panOffset.multiplyScalar( 1 - scope.dampingFactor );
1240
+ this._spherical.theta += this._sphericalDelta.theta;
1241
+ this._spherical.phi += this._sphericalDelta.phi;
1217
1242
 
1218
- } else {
1243
+ }
1219
1244
 
1220
- sphericalDelta.set( 0, 0, 0 );
1245
+ // restrict theta to be between desired limits
1221
1246
 
1222
- panOffset.set( 0, 0, 0 );
1247
+ let min = this.minAzimuthAngle;
1248
+ let max = this.maxAzimuthAngle;
1223
1249
 
1224
- }
1250
+ if ( isFinite( min ) && isFinite( max ) ) {
1225
1251
 
1226
- // adjust camera position
1227
- if ( scope.zoomToCursor && performCursorZoom ) {
1252
+ if ( min < - Math.PI ) min += _twoPI; else if ( min > Math.PI ) min -= _twoPI;
1228
1253
 
1229
- let newRadius = null;
1230
- if ( scope.object.isPerspectiveCamera ) {
1254
+ if ( max < - Math.PI ) max += _twoPI; else if ( max > Math.PI ) max -= _twoPI;
1231
1255
 
1232
- // move the camera down the pointer ray
1233
- // this method avoids floating point error
1234
- const prevRadius = offset.length();
1235
- newRadius = clampDistance( prevRadius * scale );
1256
+ if ( min <= max ) {
1236
1257
 
1237
- const radiusDelta = prevRadius - newRadius;
1238
- scope.object.position.addScaledVector( dollyDirection, radiusDelta );
1239
- scope.object.updateMatrixWorld();
1258
+ this._spherical.theta = Math.max( min, Math.min( max, this._spherical.theta ) );
1240
1259
 
1241
- zoomChanged = !! radiusDelta;
1260
+ } else {
1242
1261
 
1243
- } else if ( scope.object.isOrthographicCamera ) {
1262
+ this._spherical.theta = ( this._spherical.theta > ( min + max ) / 2 ) ?
1263
+ Math.max( min, this._spherical.theta ) :
1264
+ Math.min( max, this._spherical.theta );
1244
1265
 
1245
- // adjust the ortho camera position based on zoom changes
1246
- const mouseBefore = new three$1.Vector3( mouse.x, mouse.y, 0 );
1247
- mouseBefore.unproject( scope.object );
1266
+ }
1248
1267
 
1249
- const prevZoom = scope.object.zoom;
1250
- scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
1251
- scope.object.updateProjectionMatrix();
1268
+ }
1252
1269
 
1253
- zoomChanged = prevZoom !== scope.object.zoom;
1270
+ // restrict phi to be between desired limits
1271
+ this._spherical.phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, this._spherical.phi ) );
1254
1272
 
1255
- const mouseAfter = new three$1.Vector3( mouse.x, mouse.y, 0 );
1256
- mouseAfter.unproject( scope.object );
1273
+ this._spherical.makeSafe();
1257
1274
 
1258
- scope.object.position.sub( mouseAfter ).add( mouseBefore );
1259
- scope.object.updateMatrixWorld();
1260
1275
 
1261
- newRadius = offset.length();
1276
+ // move target to panned location
1262
1277
 
1263
- } else {
1278
+ if ( this.enableDamping === true ) {
1264
1279
 
1265
- console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled.' );
1266
- scope.zoomToCursor = false;
1280
+ this.target.addScaledVector( this._panOffset, this.dampingFactor );
1267
1281
 
1268
- }
1282
+ } else {
1283
+
1284
+ this.target.add( this._panOffset );
1269
1285
 
1270
- // handle the placement of the target
1271
- if ( newRadius !== null ) {
1286
+ }
1272
1287
 
1273
- if ( this.screenSpacePanning ) {
1288
+ // Limit the target distance from the cursor to create a sphere around the center of interest
1289
+ this.target.sub( this.cursor );
1290
+ this.target.clampLength( this.minTargetRadius, this.maxTargetRadius );
1291
+ this.target.add( this.cursor );
1274
1292
 
1275
- // position the orbit target in front of the new camera position
1276
- scope.target.set( 0, 0, - 1 )
1277
- .transformDirection( scope.object.matrix )
1278
- .multiplyScalar( newRadius )
1279
- .add( scope.object.position );
1293
+ let zoomChanged = false;
1294
+ // adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera
1295
+ // we adjust zoom later in these cases
1296
+ if ( this.zoomToCursor && this._performCursorZoom || this.object.isOrthographicCamera ) {
1280
1297
 
1281
- } else {
1298
+ this._spherical.radius = this._clampDistance( this._spherical.radius );
1282
1299
 
1283
- // get the ray and translation plane to compute target
1284
- _ray.origin.copy( scope.object.position );
1285
- _ray.direction.set( 0, 0, - 1 ).transformDirection( scope.object.matrix );
1300
+ } else {
1286
1301
 
1287
- // if the camera is 20 degrees above the horizon then don't adjust the focus target to avoid
1288
- // extremely large values
1289
- if ( Math.abs( scope.object.up.dot( _ray.direction ) ) < TILT_LIMIT ) {
1302
+ const prevRadius = this._spherical.radius;
1303
+ this._spherical.radius = this._clampDistance( this._spherical.radius * this._scale );
1304
+ zoomChanged = prevRadius != this._spherical.radius;
1290
1305
 
1291
- object.lookAt( scope.target );
1306
+ }
1292
1307
 
1293
- } else {
1308
+ _v.setFromSpherical( this._spherical );
1294
1309
 
1295
- _plane.setFromNormalAndCoplanarPoint( scope.object.up, scope.target );
1296
- _ray.intersectPlane( _plane, scope.target );
1310
+ // rotate offset back to "camera-up-vector-is-up" space
1311
+ _v.applyQuaternion( this._quatInverse );
1297
1312
 
1298
- }
1313
+ position.copy( this.target ).add( _v );
1299
1314
 
1300
- }
1315
+ this.object.lookAt( this.target );
1301
1316
 
1302
- }
1317
+ if ( this.enableDamping === true ) {
1303
1318
 
1304
- } else if ( scope.object.isOrthographicCamera ) {
1319
+ this._sphericalDelta.theta *= ( 1 - this.dampingFactor );
1320
+ this._sphericalDelta.phi *= ( 1 - this.dampingFactor );
1305
1321
 
1306
- const prevZoom = scope.object.zoom;
1307
- scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
1322
+ this._panOffset.multiplyScalar( 1 - this.dampingFactor );
1308
1323
 
1309
- if ( prevZoom !== scope.object.zoom ) {
1324
+ } else {
1310
1325
 
1311
- scope.object.updateProjectionMatrix();
1312
- zoomChanged = true;
1326
+ this._sphericalDelta.set( 0, 0, 0 );
1313
1327
 
1314
- }
1328
+ this._panOffset.set( 0, 0, 0 );
1315
1329
 
1316
- }
1330
+ }
1317
1331
 
1318
- scale = 1;
1319
- performCursorZoom = false;
1332
+ // adjust camera position
1333
+ if ( this.zoomToCursor && this._performCursorZoom ) {
1320
1334
 
1321
- // update condition is:
1322
- // min(camera displacement, camera rotation in radians)^2 > EPS
1323
- // using small-angle approximation cos(x/2) = 1 - x^2 / 8
1335
+ let newRadius = null;
1336
+ if ( this.object.isPerspectiveCamera ) {
1324
1337
 
1325
- if ( zoomChanged ||
1326
- lastPosition.distanceToSquared( scope.object.position ) > EPS ||
1327
- 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ||
1328
- lastTargetPosition.distanceToSquared( scope.target ) > EPS ) {
1338
+ // move the camera down the pointer ray
1339
+ // this method avoids floating point error
1340
+ const prevRadius = _v.length();
1341
+ newRadius = this._clampDistance( prevRadius * this._scale );
1329
1342
 
1330
- scope.dispatchEvent( _changeEvent$1 );
1343
+ const radiusDelta = prevRadius - newRadius;
1344
+ this.object.position.addScaledVector( this._dollyDirection, radiusDelta );
1345
+ this.object.updateMatrixWorld();
1331
1346
 
1332
- lastPosition.copy( scope.object.position );
1333
- lastQuaternion.copy( scope.object.quaternion );
1334
- lastTargetPosition.copy( scope.target );
1347
+ zoomChanged = !! radiusDelta;
1335
1348
 
1336
- return true;
1349
+ } else if ( this.object.isOrthographicCamera ) {
1337
1350
 
1338
- }
1351
+ // adjust the ortho camera position based on zoom changes
1352
+ const mouseBefore = new three$1.Vector3( this._mouse.x, this._mouse.y, 0 );
1353
+ mouseBefore.unproject( this.object );
1339
1354
 
1340
- return false;
1355
+ const prevZoom = this.object.zoom;
1356
+ this.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / this._scale ) );
1357
+ this.object.updateProjectionMatrix();
1341
1358
 
1342
- };
1359
+ zoomChanged = prevZoom !== this.object.zoom;
1343
1360
 
1344
- }();
1361
+ const mouseAfter = new three$1.Vector3( this._mouse.x, this._mouse.y, 0 );
1362
+ mouseAfter.unproject( this.object );
1345
1363
 
1346
- this.dispose = function () {
1364
+ this.object.position.sub( mouseAfter ).add( mouseBefore );
1365
+ this.object.updateMatrixWorld();
1347
1366
 
1348
- scope.domElement.removeEventListener( 'contextmenu', onContextMenu );
1367
+ newRadius = _v.length();
1349
1368
 
1350
- scope.domElement.removeEventListener( 'pointerdown', onPointerDown );
1351
- scope.domElement.removeEventListener( 'pointercancel', onPointerUp );
1352
- scope.domElement.removeEventListener( 'wheel', onMouseWheel );
1369
+ } else {
1353
1370
 
1354
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
1355
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
1371
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled.' );
1372
+ this.zoomToCursor = false;
1356
1373
 
1357
- const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
1374
+ }
1358
1375
 
1359
- document.removeEventListener( 'keydown', interceptControlDown, { capture: true } );
1376
+ // handle the placement of the target
1377
+ if ( newRadius !== null ) {
1360
1378
 
1361
- if ( scope._domElementKeyEvents !== null ) {
1379
+ if ( this.screenSpacePanning ) {
1362
1380
 
1363
- scope._domElementKeyEvents.removeEventListener( 'keydown', onKeyDown );
1364
- scope._domElementKeyEvents = null;
1381
+ // position the orbit target in front of the new camera position
1382
+ this.target.set( 0, 0, - 1 )
1383
+ .transformDirection( this.object.matrix )
1384
+ .multiplyScalar( newRadius )
1385
+ .add( this.object.position );
1365
1386
 
1366
- }
1387
+ } else {
1367
1388
 
1368
- //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
1389
+ // get the ray and translation plane to compute target
1390
+ _ray.origin.copy( this.object.position );
1391
+ _ray.direction.set( 0, 0, - 1 ).transformDirection( this.object.matrix );
1369
1392
 
1370
- };
1393
+ // if the camera is 20 degrees above the horizon then don't adjust the focus target to avoid
1394
+ // extremely large values
1395
+ if ( Math.abs( this.object.up.dot( _ray.direction ) ) < _TILT_LIMIT ) {
1371
1396
 
1372
- //
1373
- // internals
1374
- //
1397
+ this.object.lookAt( this.target );
1375
1398
 
1376
- const scope = this;
1377
-
1378
- const STATE = {
1379
- NONE: - 1,
1380
- ROTATE: 0,
1381
- DOLLY: 1,
1382
- PAN: 2,
1383
- TOUCH_ROTATE: 3,
1384
- TOUCH_PAN: 4,
1385
- TOUCH_DOLLY_PAN: 5,
1386
- TOUCH_DOLLY_ROTATE: 6
1387
- };
1399
+ } else {
1388
1400
 
1389
- let state = STATE.NONE;
1401
+ _plane.setFromNormalAndCoplanarPoint( this.object.up, this.target );
1402
+ _ray.intersectPlane( _plane, this.target );
1390
1403
 
1391
- const EPS = 0.000001;
1404
+ }
1392
1405
 
1393
- // current position in spherical coordinates
1394
- const spherical = new three$1.Spherical();
1395
- const sphericalDelta = new three$1.Spherical();
1406
+ }
1396
1407
 
1397
- let scale = 1;
1398
- const panOffset = new three$1.Vector3();
1408
+ }
1399
1409
 
1400
- const rotateStart = new three$1.Vector2();
1401
- const rotateEnd = new three$1.Vector2();
1402
- const rotateDelta = new three$1.Vector2();
1410
+ } else if ( this.object.isOrthographicCamera ) {
1403
1411
 
1404
- const panStart = new three$1.Vector2();
1405
- const panEnd = new three$1.Vector2();
1406
- const panDelta = new three$1.Vector2();
1412
+ const prevZoom = this.object.zoom;
1413
+ this.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / this._scale ) );
1407
1414
 
1408
- const dollyStart = new three$1.Vector2();
1409
- const dollyEnd = new three$1.Vector2();
1410
- const dollyDelta = new three$1.Vector2();
1415
+ if ( prevZoom !== this.object.zoom ) {
1411
1416
 
1412
- const dollyDirection = new three$1.Vector3();
1413
- const mouse = new three$1.Vector2();
1414
- let performCursorZoom = false;
1417
+ this.object.updateProjectionMatrix();
1418
+ zoomChanged = true;
1415
1419
 
1416
- const pointers = [];
1417
- const pointerPositions = {};
1420
+ }
1418
1421
 
1419
- let controlActive = false;
1422
+ }
1420
1423
 
1421
- function getAutoRotationAngle( deltaTime ) {
1424
+ this._scale = 1;
1425
+ this._performCursorZoom = false;
1422
1426
 
1423
- if ( deltaTime !== null ) {
1427
+ // update condition is:
1428
+ // min(camera displacement, camera rotation in radians)^2 > EPS
1429
+ // using small-angle approximation cos(x/2) = 1 - x^2 / 8
1424
1430
 
1425
- return ( 2 * Math.PI / 60 * scope.autoRotateSpeed ) * deltaTime;
1431
+ if ( zoomChanged ||
1432
+ this._lastPosition.distanceToSquared( this.object.position ) > _EPS$1 ||
1433
+ 8 * ( 1 - this._lastQuaternion.dot( this.object.quaternion ) ) > _EPS$1 ||
1434
+ this._lastTargetPosition.distanceToSquared( this.target ) > _EPS$1 ) {
1426
1435
 
1427
- } else {
1436
+ this.dispatchEvent( _changeEvent$1 );
1428
1437
 
1429
- return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
1438
+ this._lastPosition.copy( this.object.position );
1439
+ this._lastQuaternion.copy( this.object.quaternion );
1440
+ this._lastTargetPosition.copy( this.target );
1430
1441
 
1431
- }
1442
+ return true;
1432
1443
 
1433
1444
  }
1434
1445
 
1435
- function getZoomScale( delta ) {
1436
-
1437
- const normalizedDelta = Math.abs( delta * 0.01 );
1438
- return Math.pow( 0.95, scope.zoomSpeed * normalizedDelta );
1446
+ return false;
1439
1447
 
1440
- }
1448
+ }
1441
1449
 
1442
- function rotateLeft( angle ) {
1450
+ _getAutoRotationAngle( deltaTime ) {
1443
1451
 
1444
- sphericalDelta.theta -= angle;
1452
+ if ( deltaTime !== null ) {
1445
1453
 
1446
- }
1454
+ return ( _twoPI / 60 * this.autoRotateSpeed ) * deltaTime;
1447
1455
 
1448
- function rotateUp( angle ) {
1456
+ } else {
1449
1457
 
1450
- sphericalDelta.phi -= angle;
1458
+ return _twoPI / 60 / 60 * this.autoRotateSpeed;
1451
1459
 
1452
1460
  }
1453
1461
 
1454
- const panLeft = function () {
1462
+ }
1455
1463
 
1456
- const v = new three$1.Vector3();
1464
+ _getZoomScale( delta ) {
1457
1465
 
1458
- return function panLeft( distance, objectMatrix ) {
1466
+ const normalizedDelta = Math.abs( delta * 0.01 );
1467
+ return Math.pow( 0.95, this.zoomSpeed * normalizedDelta );
1459
1468
 
1460
- v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
1461
- v.multiplyScalar( - distance );
1469
+ }
1462
1470
 
1463
- panOffset.add( v );
1471
+ _rotateLeft( angle ) {
1464
1472
 
1465
- };
1473
+ this._sphericalDelta.theta -= angle;
1466
1474
 
1467
- }();
1475
+ }
1468
1476
 
1469
- const panUp = function () {
1477
+ _rotateUp( angle ) {
1470
1478
 
1471
- const v = new three$1.Vector3();
1479
+ this._sphericalDelta.phi -= angle;
1472
1480
 
1473
- return function panUp( distance, objectMatrix ) {
1481
+ }
1474
1482
 
1475
- if ( scope.screenSpacePanning === true ) {
1483
+ _panLeft( distance, objectMatrix ) {
1476
1484
 
1477
- v.setFromMatrixColumn( objectMatrix, 1 );
1485
+ _v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
1486
+ _v.multiplyScalar( - distance );
1478
1487
 
1479
- } else {
1488
+ this._panOffset.add( _v );
1480
1489
 
1481
- v.setFromMatrixColumn( objectMatrix, 0 );
1482
- v.crossVectors( scope.object.up, v );
1490
+ }
1483
1491
 
1484
- }
1492
+ _panUp( distance, objectMatrix ) {
1485
1493
 
1486
- v.multiplyScalar( distance );
1494
+ if ( this.screenSpacePanning === true ) {
1487
1495
 
1488
- panOffset.add( v );
1496
+ _v.setFromMatrixColumn( objectMatrix, 1 );
1489
1497
 
1490
- };
1498
+ } else {
1491
1499
 
1492
- }();
1500
+ _v.setFromMatrixColumn( objectMatrix, 0 );
1501
+ _v.crossVectors( this.object.up, _v );
1493
1502
 
1494
- // deltaX and deltaY are in pixels; right and down are positive
1495
- const pan = function () {
1503
+ }
1496
1504
 
1497
- const offset = new three$1.Vector3();
1505
+ _v.multiplyScalar( distance );
1498
1506
 
1499
- return function pan( deltaX, deltaY ) {
1507
+ this._panOffset.add( _v );
1500
1508
 
1501
- const element = scope.domElement;
1509
+ }
1502
1510
 
1503
- if ( scope.object.isPerspectiveCamera ) {
1511
+ // deltaX and deltaY are in pixels; right and down are positive
1512
+ _pan( deltaX, deltaY ) {
1504
1513
 
1505
- // perspective
1506
- const position = scope.object.position;
1507
- offset.copy( position ).sub( scope.target );
1508
- let targetDistance = offset.length();
1514
+ const element = this.domElement;
1509
1515
 
1510
- // half of the fov is center to top of screen
1511
- targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
1516
+ if ( this.object.isPerspectiveCamera ) {
1512
1517
 
1513
- // we use only clientHeight here so aspect ratio does not distort speed
1514
- panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
1515
- panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
1518
+ // perspective
1519
+ const position = this.object.position;
1520
+ _v.copy( position ).sub( this.target );
1521
+ let targetDistance = _v.length();
1516
1522
 
1517
- } else if ( scope.object.isOrthographicCamera ) {
1523
+ // half of the fov is center to top of screen
1524
+ targetDistance *= Math.tan( ( this.object.fov / 2 ) * Math.PI / 180.0 );
1518
1525
 
1519
- // orthographic
1520
- panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
1521
- panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
1526
+ // we use only clientHeight here so aspect ratio does not distort speed
1527
+ this._panLeft( 2 * deltaX * targetDistance / element.clientHeight, this.object.matrix );
1528
+ this._panUp( 2 * deltaY * targetDistance / element.clientHeight, this.object.matrix );
1522
1529
 
1523
- } else {
1530
+ } else if ( this.object.isOrthographicCamera ) {
1524
1531
 
1525
- // camera neither orthographic nor perspective
1526
- console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
1527
- scope.enablePan = false;
1532
+ // orthographic
1533
+ this._panLeft( deltaX * ( this.object.right - this.object.left ) / this.object.zoom / element.clientWidth, this.object.matrix );
1534
+ this._panUp( deltaY * ( this.object.top - this.object.bottom ) / this.object.zoom / element.clientHeight, this.object.matrix );
1528
1535
 
1529
- }
1536
+ } else {
1530
1537
 
1531
- };
1538
+ // camera neither orthographic nor perspective
1539
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
1540
+ this.enablePan = false;
1532
1541
 
1533
- }();
1542
+ }
1534
1543
 
1535
- function dollyOut( dollyScale ) {
1544
+ }
1536
1545
 
1537
- if ( scope.object.isPerspectiveCamera || scope.object.isOrthographicCamera ) {
1546
+ _dollyOut( dollyScale ) {
1538
1547
 
1539
- scale /= dollyScale;
1548
+ if ( this.object.isPerspectiveCamera || this.object.isOrthographicCamera ) {
1540
1549
 
1541
- } else {
1550
+ this._scale /= dollyScale;
1542
1551
 
1543
- console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
1544
- scope.enableZoom = false;
1552
+ } else {
1545
1553
 
1546
- }
1554
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
1555
+ this.enableZoom = false;
1547
1556
 
1548
1557
  }
1549
1558
 
1550
- function dollyIn( dollyScale ) {
1559
+ }
1551
1560
 
1552
- if ( scope.object.isPerspectiveCamera || scope.object.isOrthographicCamera ) {
1561
+ _dollyIn( dollyScale ) {
1553
1562
 
1554
- scale *= dollyScale;
1563
+ if ( this.object.isPerspectiveCamera || this.object.isOrthographicCamera ) {
1555
1564
 
1556
- } else {
1565
+ this._scale *= dollyScale;
1557
1566
 
1558
- console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
1559
- scope.enableZoom = false;
1567
+ } else {
1560
1568
 
1561
- }
1569
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
1570
+ this.enableZoom = false;
1562
1571
 
1563
1572
  }
1564
1573
 
1565
- function updateZoomParameters( x, y ) {
1566
-
1567
- if ( ! scope.zoomToCursor ) {
1568
-
1569
- return;
1574
+ }
1570
1575
 
1571
- }
1576
+ _updateZoomParameters( x, y ) {
1572
1577
 
1573
- performCursorZoom = true;
1578
+ if ( ! this.zoomToCursor ) {
1574
1579
 
1575
- const rect = scope.domElement.getBoundingClientRect();
1576
- const dx = x - rect.left;
1577
- const dy = y - rect.top;
1578
- const w = rect.width;
1579
- const h = rect.height;
1580
+ return;
1580
1581
 
1581
- mouse.x = ( dx / w ) * 2 - 1;
1582
- mouse.y = - ( dy / h ) * 2 + 1;
1582
+ }
1583
1583
 
1584
- dollyDirection.set( mouse.x, mouse.y, 1 ).unproject( scope.object ).sub( scope.object.position ).normalize();
1584
+ this._performCursorZoom = true;
1585
1585
 
1586
- }
1586
+ const rect = this.domElement.getBoundingClientRect();
1587
+ const dx = x - rect.left;
1588
+ const dy = y - rect.top;
1589
+ const w = rect.width;
1590
+ const h = rect.height;
1587
1591
 
1588
- function clampDistance( dist ) {
1592
+ this._mouse.x = ( dx / w ) * 2 - 1;
1593
+ this._mouse.y = - ( dy / h ) * 2 + 1;
1589
1594
 
1590
- return Math.max( scope.minDistance, Math.min( scope.maxDistance, dist ) );
1595
+ this._dollyDirection.set( this._mouse.x, this._mouse.y, 1 ).unproject( this.object ).sub( this.object.position ).normalize();
1591
1596
 
1592
- }
1597
+ }
1593
1598
 
1594
- //
1595
- // event callbacks - update the object state
1596
- //
1599
+ _clampDistance( dist ) {
1597
1600
 
1598
- function handleMouseDownRotate( event ) {
1601
+ return Math.max( this.minDistance, Math.min( this.maxDistance, dist ) );
1599
1602
 
1600
- rotateStart.set( event.clientX, event.clientY );
1603
+ }
1601
1604
 
1602
- }
1605
+ //
1606
+ // event callbacks - update the object state
1607
+ //
1603
1608
 
1604
- function handleMouseDownDolly( event ) {
1609
+ _handleMouseDownRotate( event ) {
1605
1610
 
1606
- updateZoomParameters( event.clientX, event.clientX );
1607
- dollyStart.set( event.clientX, event.clientY );
1611
+ this._rotateStart.set( event.clientX, event.clientY );
1608
1612
 
1609
- }
1613
+ }
1610
1614
 
1611
- function handleMouseDownPan( event ) {
1615
+ _handleMouseDownDolly( event ) {
1612
1616
 
1613
- panStart.set( event.clientX, event.clientY );
1617
+ this._updateZoomParameters( event.clientX, event.clientX );
1618
+ this._dollyStart.set( event.clientX, event.clientY );
1614
1619
 
1615
- }
1620
+ }
1616
1621
 
1617
- function handleMouseMoveRotate( event ) {
1622
+ _handleMouseDownPan( event ) {
1618
1623
 
1619
- rotateEnd.set( event.clientX, event.clientY );
1624
+ this._panStart.set( event.clientX, event.clientY );
1620
1625
 
1621
- rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
1626
+ }
1622
1627
 
1623
- const element = scope.domElement;
1628
+ _handleMouseMoveRotate( event ) {
1624
1629
 
1625
- rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height
1630
+ this._rotateEnd.set( event.clientX, event.clientY );
1626
1631
 
1627
- rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
1632
+ this._rotateDelta.subVectors( this._rotateEnd, this._rotateStart ).multiplyScalar( this.rotateSpeed );
1628
1633
 
1629
- rotateStart.copy( rotateEnd );
1634
+ const element = this.domElement;
1630
1635
 
1631
- scope.update();
1636
+ this._rotateLeft( _twoPI * this._rotateDelta.x / element.clientHeight ); // yes, height
1632
1637
 
1633
- }
1638
+ this._rotateUp( _twoPI * this._rotateDelta.y / element.clientHeight );
1634
1639
 
1635
- function handleMouseMoveDolly( event ) {
1640
+ this._rotateStart.copy( this._rotateEnd );
1636
1641
 
1637
- dollyEnd.set( event.clientX, event.clientY );
1642
+ this.update();
1638
1643
 
1639
- dollyDelta.subVectors( dollyEnd, dollyStart );
1644
+ }
1640
1645
 
1641
- if ( dollyDelta.y > 0 ) {
1646
+ _handleMouseMoveDolly( event ) {
1642
1647
 
1643
- dollyOut( getZoomScale( dollyDelta.y ) );
1648
+ this._dollyEnd.set( event.clientX, event.clientY );
1644
1649
 
1645
- } else if ( dollyDelta.y < 0 ) {
1650
+ this._dollyDelta.subVectors( this._dollyEnd, this._dollyStart );
1646
1651
 
1647
- dollyIn( getZoomScale( dollyDelta.y ) );
1652
+ if ( this._dollyDelta.y > 0 ) {
1648
1653
 
1649
- }
1654
+ this._dollyOut( this._getZoomScale( this._dollyDelta.y ) );
1650
1655
 
1651
- dollyStart.copy( dollyEnd );
1656
+ } else if ( this._dollyDelta.y < 0 ) {
1652
1657
 
1653
- scope.update();
1658
+ this._dollyIn( this._getZoomScale( this._dollyDelta.y ) );
1654
1659
 
1655
1660
  }
1656
1661
 
1657
- function handleMouseMovePan( event ) {
1662
+ this._dollyStart.copy( this._dollyEnd );
1658
1663
 
1659
- panEnd.set( event.clientX, event.clientY );
1664
+ this.update();
1660
1665
 
1661
- panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
1666
+ }
1662
1667
 
1663
- pan( panDelta.x, panDelta.y );
1668
+ _handleMouseMovePan( event ) {
1664
1669
 
1665
- panStart.copy( panEnd );
1670
+ this._panEnd.set( event.clientX, event.clientY );
1666
1671
 
1667
- scope.update();
1672
+ this._panDelta.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.panSpeed );
1668
1673
 
1669
- }
1674
+ this._pan( this._panDelta.x, this._panDelta.y );
1670
1675
 
1671
- function handleMouseWheel( event ) {
1676
+ this._panStart.copy( this._panEnd );
1672
1677
 
1673
- updateZoomParameters( event.clientX, event.clientY );
1678
+ this.update();
1674
1679
 
1675
- if ( event.deltaY < 0 ) {
1680
+ }
1676
1681
 
1677
- dollyIn( getZoomScale( event.deltaY ) );
1682
+ _handleMouseWheel( event ) {
1678
1683
 
1679
- } else if ( event.deltaY > 0 ) {
1684
+ this._updateZoomParameters( event.clientX, event.clientY );
1680
1685
 
1681
- dollyOut( getZoomScale( event.deltaY ) );
1686
+ if ( event.deltaY < 0 ) {
1682
1687
 
1683
- }
1688
+ this._dollyIn( this._getZoomScale( event.deltaY ) );
1689
+
1690
+ } else if ( event.deltaY > 0 ) {
1684
1691
 
1685
- scope.update();
1692
+ this._dollyOut( this._getZoomScale( event.deltaY ) );
1686
1693
 
1687
1694
  }
1688
1695
 
1689
- function handleKeyDown( event ) {
1696
+ this.update();
1690
1697
 
1691
- let needsUpdate = false;
1698
+ }
1692
1699
 
1693
- switch ( event.code ) {
1700
+ _handleKeyDown( event ) {
1694
1701
 
1695
- case scope.keys.UP:
1702
+ let needsUpdate = false;
1696
1703
 
1697
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1704
+ switch ( event.code ) {
1698
1705
 
1699
- rotateUp( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
1706
+ case this.keys.UP:
1700
1707
 
1701
- } else {
1708
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1702
1709
 
1703
- pan( 0, scope.keyPanSpeed );
1710
+ this._rotateUp( _twoPI * this.rotateSpeed / this.domElement.clientHeight );
1704
1711
 
1705
- }
1712
+ } else {
1706
1713
 
1707
- needsUpdate = true;
1708
- break;
1714
+ this._pan( 0, this.keyPanSpeed );
1709
1715
 
1710
- case scope.keys.BOTTOM:
1716
+ }
1711
1717
 
1712
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1718
+ needsUpdate = true;
1719
+ break;
1713
1720
 
1714
- rotateUp( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
1721
+ case this.keys.BOTTOM:
1715
1722
 
1716
- } else {
1723
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1717
1724
 
1718
- pan( 0, - scope.keyPanSpeed );
1725
+ this._rotateUp( - _twoPI * this.rotateSpeed / this.domElement.clientHeight );
1719
1726
 
1720
- }
1727
+ } else {
1721
1728
 
1722
- needsUpdate = true;
1723
- break;
1729
+ this._pan( 0, - this.keyPanSpeed );
1724
1730
 
1725
- case scope.keys.LEFT:
1731
+ }
1726
1732
 
1727
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1733
+ needsUpdate = true;
1734
+ break;
1728
1735
 
1729
- rotateLeft( 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
1736
+ case this.keys.LEFT:
1730
1737
 
1731
- } else {
1738
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1732
1739
 
1733
- pan( scope.keyPanSpeed, 0 );
1740
+ this._rotateLeft( _twoPI * this.rotateSpeed / this.domElement.clientHeight );
1734
1741
 
1735
- }
1742
+ } else {
1736
1743
 
1737
- needsUpdate = true;
1738
- break;
1744
+ this._pan( this.keyPanSpeed, 0 );
1739
1745
 
1740
- case scope.keys.RIGHT:
1746
+ }
1741
1747
 
1742
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1748
+ needsUpdate = true;
1749
+ break;
1743
1750
 
1744
- rotateLeft( - 2 * Math.PI * scope.rotateSpeed / scope.domElement.clientHeight );
1751
+ case this.keys.RIGHT:
1745
1752
 
1746
- } else {
1753
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
1747
1754
 
1748
- pan( - scope.keyPanSpeed, 0 );
1755
+ this._rotateLeft( - _twoPI * this.rotateSpeed / this.domElement.clientHeight );
1749
1756
 
1750
- }
1757
+ } else {
1751
1758
 
1752
- needsUpdate = true;
1753
- break;
1759
+ this._pan( - this.keyPanSpeed, 0 );
1754
1760
 
1755
- }
1761
+ }
1756
1762
 
1757
- if ( needsUpdate ) {
1763
+ needsUpdate = true;
1764
+ break;
1758
1765
 
1759
- // prevent the browser from scrolling on cursor keys
1760
- event.preventDefault();
1766
+ }
1761
1767
 
1762
- scope.update();
1768
+ if ( needsUpdate ) {
1763
1769
 
1764
- }
1770
+ // prevent the browser from scrolling on cursor keys
1771
+ event.preventDefault();
1765
1772
 
1773
+ this.update();
1766
1774
 
1767
1775
  }
1768
1776
 
1769
- function handleTouchStartRotate( event ) {
1770
1777
 
1771
- if ( pointers.length === 1 ) {
1778
+ }
1772
1779
 
1773
- rotateStart.set( event.pageX, event.pageY );
1780
+ _handleTouchStartRotate( event ) {
1774
1781
 
1775
- } else {
1782
+ if ( this._pointers.length === 1 ) {
1776
1783
 
1777
- const position = getSecondPointerPosition( event );
1784
+ this._rotateStart.set( event.pageX, event.pageY );
1778
1785
 
1779
- const x = 0.5 * ( event.pageX + position.x );
1780
- const y = 0.5 * ( event.pageY + position.y );
1786
+ } else {
1781
1787
 
1782
- rotateStart.set( x, y );
1788
+ const position = this._getSecondPointerPosition( event );
1783
1789
 
1784
- }
1790
+ const x = 0.5 * ( event.pageX + position.x );
1791
+ const y = 0.5 * ( event.pageY + position.y );
1792
+
1793
+ this._rotateStart.set( x, y );
1785
1794
 
1786
1795
  }
1787
1796
 
1788
- function handleTouchStartPan( event ) {
1797
+ }
1789
1798
 
1790
- if ( pointers.length === 1 ) {
1799
+ _handleTouchStartPan( event ) {
1791
1800
 
1792
- panStart.set( event.pageX, event.pageY );
1801
+ if ( this._pointers.length === 1 ) {
1793
1802
 
1794
- } else {
1803
+ this._panStart.set( event.pageX, event.pageY );
1795
1804
 
1796
- const position = getSecondPointerPosition( event );
1805
+ } else {
1797
1806
 
1798
- const x = 0.5 * ( event.pageX + position.x );
1799
- const y = 0.5 * ( event.pageY + position.y );
1807
+ const position = this._getSecondPointerPosition( event );
1800
1808
 
1801
- panStart.set( x, y );
1809
+ const x = 0.5 * ( event.pageX + position.x );
1810
+ const y = 0.5 * ( event.pageY + position.y );
1802
1811
 
1803
- }
1812
+ this._panStart.set( x, y );
1804
1813
 
1805
1814
  }
1806
1815
 
1807
- function handleTouchStartDolly( event ) {
1808
-
1809
- const position = getSecondPointerPosition( event );
1810
-
1811
- const dx = event.pageX - position.x;
1812
- const dy = event.pageY - position.y;
1813
-
1814
- const distance = Math.sqrt( dx * dx + dy * dy );
1815
-
1816
- dollyStart.set( 0, distance );
1817
-
1818
- }
1816
+ }
1819
1817
 
1820
- function handleTouchStartDollyPan( event ) {
1818
+ _handleTouchStartDolly( event ) {
1821
1819
 
1822
- if ( scope.enableZoom ) handleTouchStartDolly( event );
1820
+ const position = this._getSecondPointerPosition( event );
1823
1821
 
1824
- if ( scope.enablePan ) handleTouchStartPan( event );
1822
+ const dx = event.pageX - position.x;
1823
+ const dy = event.pageY - position.y;
1825
1824
 
1826
- }
1825
+ const distance = Math.sqrt( dx * dx + dy * dy );
1827
1826
 
1828
- function handleTouchStartDollyRotate( event ) {
1827
+ this._dollyStart.set( 0, distance );
1829
1828
 
1830
- if ( scope.enableZoom ) handleTouchStartDolly( event );
1829
+ }
1831
1830
 
1832
- if ( scope.enableRotate ) handleTouchStartRotate( event );
1831
+ _handleTouchStartDollyPan( event ) {
1833
1832
 
1834
- }
1833
+ if ( this.enableZoom ) this._handleTouchStartDolly( event );
1835
1834
 
1836
- function handleTouchMoveRotate( event ) {
1835
+ if ( this.enablePan ) this._handleTouchStartPan( event );
1837
1836
 
1838
- if ( pointers.length == 1 ) {
1837
+ }
1839
1838
 
1840
- rotateEnd.set( event.pageX, event.pageY );
1839
+ _handleTouchStartDollyRotate( event ) {
1841
1840
 
1842
- } else {
1841
+ if ( this.enableZoom ) this._handleTouchStartDolly( event );
1843
1842
 
1844
- const position = getSecondPointerPosition( event );
1843
+ if ( this.enableRotate ) this._handleTouchStartRotate( event );
1845
1844
 
1846
- const x = 0.5 * ( event.pageX + position.x );
1847
- const y = 0.5 * ( event.pageY + position.y );
1845
+ }
1848
1846
 
1849
- rotateEnd.set( x, y );
1847
+ _handleTouchMoveRotate( event ) {
1850
1848
 
1851
- }
1849
+ if ( this._pointers.length == 1 ) {
1852
1850
 
1853
- rotateDelta.subVectors( rotateEnd, rotateStart ).multiplyScalar( scope.rotateSpeed );
1851
+ this._rotateEnd.set( event.pageX, event.pageY );
1854
1852
 
1855
- const element = scope.domElement;
1853
+ } else {
1856
1854
 
1857
- rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientHeight ); // yes, height
1855
+ const position = this._getSecondPointerPosition( event );
1858
1856
 
1859
- rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight );
1857
+ const x = 0.5 * ( event.pageX + position.x );
1858
+ const y = 0.5 * ( event.pageY + position.y );
1860
1859
 
1861
- rotateStart.copy( rotateEnd );
1860
+ this._rotateEnd.set( x, y );
1862
1861
 
1863
1862
  }
1864
1863
 
1865
- function handleTouchMovePan( event ) {
1864
+ this._rotateDelta.subVectors( this._rotateEnd, this._rotateStart ).multiplyScalar( this.rotateSpeed );
1866
1865
 
1867
- if ( pointers.length === 1 ) {
1866
+ const element = this.domElement;
1868
1867
 
1869
- panEnd.set( event.pageX, event.pageY );
1868
+ this._rotateLeft( _twoPI * this._rotateDelta.x / element.clientHeight ); // yes, height
1870
1869
 
1871
- } else {
1870
+ this._rotateUp( _twoPI * this._rotateDelta.y / element.clientHeight );
1872
1871
 
1873
- const position = getSecondPointerPosition( event );
1872
+ this._rotateStart.copy( this._rotateEnd );
1874
1873
 
1875
- const x = 0.5 * ( event.pageX + position.x );
1876
- const y = 0.5 * ( event.pageY + position.y );
1874
+ }
1877
1875
 
1878
- panEnd.set( x, y );
1876
+ _handleTouchMovePan( event ) {
1879
1877
 
1880
- }
1878
+ if ( this._pointers.length === 1 ) {
1881
1879
 
1882
- panDelta.subVectors( panEnd, panStart ).multiplyScalar( scope.panSpeed );
1880
+ this._panEnd.set( event.pageX, event.pageY );
1883
1881
 
1884
- pan( panDelta.x, panDelta.y );
1882
+ } else {
1885
1883
 
1886
- panStart.copy( panEnd );
1884
+ const position = this._getSecondPointerPosition( event );
1887
1885
 
1888
- }
1886
+ const x = 0.5 * ( event.pageX + position.x );
1887
+ const y = 0.5 * ( event.pageY + position.y );
1889
1888
 
1890
- function handleTouchMoveDolly( event ) {
1889
+ this._panEnd.set( x, y );
1891
1890
 
1892
- const position = getSecondPointerPosition( event );
1891
+ }
1893
1892
 
1894
- const dx = event.pageX - position.x;
1895
- const dy = event.pageY - position.y;
1893
+ this._panDelta.subVectors( this._panEnd, this._panStart ).multiplyScalar( this.panSpeed );
1896
1894
 
1897
- const distance = Math.sqrt( dx * dx + dy * dy );
1895
+ this._pan( this._panDelta.x, this._panDelta.y );
1898
1896
 
1899
- dollyEnd.set( 0, distance );
1897
+ this._panStart.copy( this._panEnd );
1900
1898
 
1901
- dollyDelta.set( 0, Math.pow( dollyEnd.y / dollyStart.y, scope.zoomSpeed ) );
1899
+ }
1902
1900
 
1903
- dollyOut( dollyDelta.y );
1901
+ _handleTouchMoveDolly( event ) {
1904
1902
 
1905
- dollyStart.copy( dollyEnd );
1903
+ const position = this._getSecondPointerPosition( event );
1906
1904
 
1907
- const centerX = ( event.pageX + position.x ) * 0.5;
1908
- const centerY = ( event.pageY + position.y ) * 0.5;
1905
+ const dx = event.pageX - position.x;
1906
+ const dy = event.pageY - position.y;
1909
1907
 
1910
- updateZoomParameters( centerX, centerY );
1908
+ const distance = Math.sqrt( dx * dx + dy * dy );
1911
1909
 
1912
- }
1910
+ this._dollyEnd.set( 0, distance );
1913
1911
 
1914
- function handleTouchMoveDollyPan( event ) {
1912
+ this._dollyDelta.set( 0, Math.pow( this._dollyEnd.y / this._dollyStart.y, this.zoomSpeed ) );
1915
1913
 
1916
- if ( scope.enableZoom ) handleTouchMoveDolly( event );
1914
+ this._dollyOut( this._dollyDelta.y );
1917
1915
 
1918
- if ( scope.enablePan ) handleTouchMovePan( event );
1916
+ this._dollyStart.copy( this._dollyEnd );
1919
1917
 
1920
- }
1918
+ const centerX = ( event.pageX + position.x ) * 0.5;
1919
+ const centerY = ( event.pageY + position.y ) * 0.5;
1921
1920
 
1922
- function handleTouchMoveDollyRotate( event ) {
1921
+ this._updateZoomParameters( centerX, centerY );
1923
1922
 
1924
- if ( scope.enableZoom ) handleTouchMoveDolly( event );
1923
+ }
1925
1924
 
1926
- if ( scope.enableRotate ) handleTouchMoveRotate( event );
1925
+ _handleTouchMoveDollyPan( event ) {
1927
1926
 
1928
- }
1927
+ if ( this.enableZoom ) this._handleTouchMoveDolly( event );
1929
1928
 
1930
- //
1931
- // event handlers - FSM: listen for events and reset state
1932
- //
1929
+ if ( this.enablePan ) this._handleTouchMovePan( event );
1933
1930
 
1934
- function onPointerDown( event ) {
1931
+ }
1935
1932
 
1936
- if ( scope.enabled === false ) return;
1933
+ _handleTouchMoveDollyRotate( event ) {
1937
1934
 
1938
- if ( pointers.length === 0 ) {
1935
+ if ( this.enableZoom ) this._handleTouchMoveDolly( event );
1939
1936
 
1940
- scope.domElement.setPointerCapture( event.pointerId );
1937
+ if ( this.enableRotate ) this._handleTouchMoveRotate( event );
1941
1938
 
1942
- scope.domElement.addEventListener( 'pointermove', onPointerMove );
1943
- scope.domElement.addEventListener( 'pointerup', onPointerUp );
1939
+ }
1944
1940
 
1945
- }
1941
+ // pointers
1946
1942
 
1947
- //
1943
+ _addPointer( event ) {
1948
1944
 
1949
- if ( isTrackingPointer( event ) ) return;
1945
+ this._pointers.push( event.pointerId );
1950
1946
 
1951
- //
1947
+ }
1952
1948
 
1953
- addPointer( event );
1949
+ _removePointer( event ) {
1954
1950
 
1955
- if ( event.pointerType === 'touch' ) {
1951
+ delete this._pointerPositions[ event.pointerId ];
1956
1952
 
1957
- onTouchStart( event );
1953
+ for ( let i = 0; i < this._pointers.length; i ++ ) {
1958
1954
 
1959
- } else {
1955
+ if ( this._pointers[ i ] == event.pointerId ) {
1960
1956
 
1961
- onMouseDown( event );
1957
+ this._pointers.splice( i, 1 );
1958
+ return;
1962
1959
 
1963
1960
  }
1964
1961
 
1965
1962
  }
1966
1963
 
1967
- function onPointerMove( event ) {
1968
-
1969
- if ( scope.enabled === false ) return;
1964
+ }
1970
1965
 
1971
- if ( event.pointerType === 'touch' ) {
1966
+ _isTrackingPointer( event ) {
1972
1967
 
1973
- onTouchMove( event );
1968
+ for ( let i = 0; i < this._pointers.length; i ++ ) {
1974
1969
 
1975
- } else {
1970
+ if ( this._pointers[ i ] == event.pointerId ) return true;
1976
1971
 
1977
- onMouseMove( event );
1972
+ }
1978
1973
 
1979
- }
1974
+ return false;
1980
1975
 
1981
- }
1976
+ }
1982
1977
 
1983
- function onPointerUp( event ) {
1978
+ _trackPointer( event ) {
1984
1979
 
1985
- removePointer( event );
1980
+ let position = this._pointerPositions[ event.pointerId ];
1986
1981
 
1987
- switch ( pointers.length ) {
1982
+ if ( position === undefined ) {
1988
1983
 
1989
- case 0:
1984
+ position = new three$1.Vector2();
1985
+ this._pointerPositions[ event.pointerId ] = position;
1990
1986
 
1991
- scope.domElement.releasePointerCapture( event.pointerId );
1987
+ }
1992
1988
 
1993
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
1994
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
1989
+ position.set( event.pageX, event.pageY );
1995
1990
 
1996
- scope.dispatchEvent( _endEvent );
1991
+ }
1997
1992
 
1998
- state = STATE.NONE;
1993
+ _getSecondPointerPosition( event ) {
1999
1994
 
2000
- break;
1995
+ const pointerId = ( event.pointerId === this._pointers[ 0 ] ) ? this._pointers[ 1 ] : this._pointers[ 0 ];
2001
1996
 
2002
- case 1:
1997
+ return this._pointerPositions[ pointerId ];
2003
1998
 
2004
- const pointerId = pointers[ 0 ];
2005
- const position = pointerPositions[ pointerId ];
1999
+ }
2006
2000
 
2007
- // minimal placeholder event - allows state correction on pointer-up
2008
- onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );
2001
+ //
2009
2002
 
2010
- break;
2003
+ _customWheelEvent( event ) {
2011
2004
 
2012
- }
2005
+ const mode = event.deltaMode;
2013
2006
 
2014
- }
2007
+ // minimal wheel event altered to meet delta-zoom demand
2008
+ const newEvent = {
2009
+ clientX: event.clientX,
2010
+ clientY: event.clientY,
2011
+ deltaY: event.deltaY,
2012
+ };
2015
2013
 
2016
- function onMouseDown( event ) {
2014
+ switch ( mode ) {
2017
2015
 
2018
- let mouseAction;
2016
+ case 1: // LINE_MODE
2017
+ newEvent.deltaY *= 16;
2018
+ break;
2019
2019
 
2020
- switch ( event.button ) {
2020
+ case 2: // PAGE_MODE
2021
+ newEvent.deltaY *= 100;
2022
+ break;
2021
2023
 
2022
- case 0:
2024
+ }
2023
2025
 
2024
- mouseAction = scope.mouseButtons.LEFT;
2025
- break;
2026
+ // detect if event was triggered by pinching
2027
+ if ( event.ctrlKey && ! this._controlActive ) {
2026
2028
 
2027
- case 1:
2029
+ newEvent.deltaY *= 10;
2028
2030
 
2029
- mouseAction = scope.mouseButtons.MIDDLE;
2030
- break;
2031
+ }
2031
2032
 
2032
- case 2:
2033
+ return newEvent;
2033
2034
 
2034
- mouseAction = scope.mouseButtons.RIGHT;
2035
- break;
2035
+ }
2036
2036
 
2037
- default:
2037
+ }
2038
2038
 
2039
- mouseAction = - 1;
2039
+ function onPointerDown$1( event ) {
2040
2040
 
2041
- }
2041
+ if ( this.enabled === false ) return;
2042
2042
 
2043
- switch ( mouseAction ) {
2043
+ if ( this._pointers.length === 0 ) {
2044
2044
 
2045
- case three$1.MOUSE.DOLLY:
2045
+ this.domElement.setPointerCapture( event.pointerId );
2046
2046
 
2047
- if ( scope.enableZoom === false ) return;
2047
+ this.domElement.addEventListener( 'pointermove', this._onPointerMove );
2048
+ this.domElement.addEventListener( 'pointerup', this._onPointerUp );
2048
2049
 
2049
- handleMouseDownDolly( event );
2050
+ }
2050
2051
 
2051
- state = STATE.DOLLY;
2052
+ //
2052
2053
 
2053
- break;
2054
+ if ( this._isTrackingPointer( event ) ) return;
2054
2055
 
2055
- case three$1.MOUSE.ROTATE:
2056
+ //
2056
2057
 
2057
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
2058
+ this._addPointer( event );
2058
2059
 
2059
- if ( scope.enablePan === false ) return;
2060
+ if ( event.pointerType === 'touch' ) {
2060
2061
 
2061
- handleMouseDownPan( event );
2062
+ this._onTouchStart( event );
2062
2063
 
2063
- state = STATE.PAN;
2064
+ } else {
2064
2065
 
2065
- } else {
2066
+ this._onMouseDown( event );
2066
2067
 
2067
- if ( scope.enableRotate === false ) return;
2068
+ }
2068
2069
 
2069
- handleMouseDownRotate( event );
2070
+ }
2070
2071
 
2071
- state = STATE.ROTATE;
2072
+ function onPointerMove$1( event ) {
2072
2073
 
2073
- }
2074
+ if ( this.enabled === false ) return;
2074
2075
 
2075
- break;
2076
+ if ( event.pointerType === 'touch' ) {
2076
2077
 
2077
- case three$1.MOUSE.PAN:
2078
+ this._onTouchMove( event );
2078
2079
 
2079
- if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
2080
+ } else {
2080
2081
 
2081
- if ( scope.enableRotate === false ) return;
2082
+ this._onMouseMove( event );
2082
2083
 
2083
- handleMouseDownRotate( event );
2084
+ }
2084
2085
 
2085
- state = STATE.ROTATE;
2086
+ }
2086
2087
 
2087
- } else {
2088
+ function onPointerUp$1( event ) {
2088
2089
 
2089
- if ( scope.enablePan === false ) return;
2090
+ this._removePointer( event );
2090
2091
 
2091
- handleMouseDownPan( event );
2092
+ switch ( this._pointers.length ) {
2092
2093
 
2093
- state = STATE.PAN;
2094
+ case 0:
2094
2095
 
2095
- }
2096
+ this.domElement.releasePointerCapture( event.pointerId );
2096
2097
 
2097
- break;
2098
+ this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
2099
+ this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
2098
2100
 
2099
- default:
2101
+ this.dispatchEvent( _endEvent );
2100
2102
 
2101
- state = STATE.NONE;
2103
+ this.state = _STATE.NONE;
2102
2104
 
2103
- }
2105
+ break;
2104
2106
 
2105
- if ( state !== STATE.NONE ) {
2107
+ case 1:
2106
2108
 
2107
- scope.dispatchEvent( _startEvent );
2109
+ const pointerId = this._pointers[ 0 ];
2110
+ const position = this._pointerPositions[ pointerId ];
2108
2111
 
2109
- }
2112
+ // minimal placeholder event - allows state correction on pointer-up
2113
+ this._onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );
2110
2114
 
2111
- }
2115
+ break;
2112
2116
 
2113
- function onMouseMove( event ) {
2117
+ }
2114
2118
 
2115
- switch ( state ) {
2119
+ }
2116
2120
 
2117
- case STATE.ROTATE:
2121
+ function onMouseDown( event ) {
2118
2122
 
2119
- if ( scope.enableRotate === false ) return;
2123
+ let mouseAction;
2120
2124
 
2121
- handleMouseMoveRotate( event );
2125
+ switch ( event.button ) {
2122
2126
 
2123
- break;
2127
+ case 0:
2124
2128
 
2125
- case STATE.DOLLY:
2129
+ mouseAction = this.mouseButtons.LEFT;
2130
+ break;
2126
2131
 
2127
- if ( scope.enableZoom === false ) return;
2132
+ case 1:
2128
2133
 
2129
- handleMouseMoveDolly( event );
2134
+ mouseAction = this.mouseButtons.MIDDLE;
2135
+ break;
2130
2136
 
2131
- break;
2137
+ case 2:
2132
2138
 
2133
- case STATE.PAN:
2139
+ mouseAction = this.mouseButtons.RIGHT;
2140
+ break;
2134
2141
 
2135
- if ( scope.enablePan === false ) return;
2142
+ default:
2136
2143
 
2137
- handleMouseMovePan( event );
2144
+ mouseAction = - 1;
2138
2145
 
2139
- break;
2146
+ }
2140
2147
 
2141
- }
2148
+ switch ( mouseAction ) {
2142
2149
 
2143
- }
2150
+ case three$1.MOUSE.DOLLY:
2144
2151
 
2145
- function onMouseWheel( event ) {
2152
+ if ( this.enableZoom === false ) return;
2146
2153
 
2147
- if ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;
2154
+ this._handleMouseDownDolly( event );
2148
2155
 
2149
- event.preventDefault();
2156
+ this.state = _STATE.DOLLY;
2150
2157
 
2151
- scope.dispatchEvent( _startEvent );
2158
+ break;
2152
2159
 
2153
- handleMouseWheel( customWheelEvent( event ) );
2160
+ case three$1.MOUSE.ROTATE:
2154
2161
 
2155
- scope.dispatchEvent( _endEvent );
2162
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
2156
2163
 
2157
- }
2164
+ if ( this.enablePan === false ) return;
2158
2165
 
2159
- function customWheelEvent( event ) {
2166
+ this._handleMouseDownPan( event );
2160
2167
 
2161
- const mode = event.deltaMode;
2168
+ this.state = _STATE.PAN;
2162
2169
 
2163
- // minimal wheel event altered to meet delta-zoom demand
2164
- const newEvent = {
2165
- clientX: event.clientX,
2166
- clientY: event.clientY,
2167
- deltaY: event.deltaY,
2168
- };
2170
+ } else {
2169
2171
 
2170
- switch ( mode ) {
2172
+ if ( this.enableRotate === false ) return;
2171
2173
 
2172
- case 1: // LINE_MODE
2173
- newEvent.deltaY *= 16;
2174
- break;
2174
+ this._handleMouseDownRotate( event );
2175
2175
 
2176
- case 2: // PAGE_MODE
2177
- newEvent.deltaY *= 100;
2178
- break;
2176
+ this.state = _STATE.ROTATE;
2179
2177
 
2180
2178
  }
2181
2179
 
2182
- // detect if event was triggered by pinching
2183
- if ( event.ctrlKey && ! controlActive ) {
2184
-
2185
- newEvent.deltaY *= 10;
2180
+ break;
2186
2181
 
2187
- }
2182
+ case three$1.MOUSE.PAN:
2188
2183
 
2189
- return newEvent;
2184
+ if ( event.ctrlKey || event.metaKey || event.shiftKey ) {
2190
2185
 
2191
- }
2186
+ if ( this.enableRotate === false ) return;
2192
2187
 
2193
- function interceptControlDown( event ) {
2188
+ this._handleMouseDownRotate( event );
2194
2189
 
2195
- if ( event.key === 'Control' ) {
2190
+ this.state = _STATE.ROTATE;
2196
2191
 
2197
- controlActive = true;
2192
+ } else {
2198
2193
 
2194
+ if ( this.enablePan === false ) return;
2199
2195
 
2200
- const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
2196
+ this._handleMouseDownPan( event );
2201
2197
 
2202
- document.addEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
2198
+ this.state = _STATE.PAN;
2203
2199
 
2204
2200
  }
2205
2201
 
2206
- }
2207
-
2208
- function interceptControlUp( event ) {
2202
+ break;
2209
2203
 
2210
- if ( event.key === 'Control' ) {
2204
+ default:
2211
2205
 
2212
- controlActive = false;
2206
+ this.state = _STATE.NONE;
2213
2207
 
2208
+ }
2214
2209
 
2215
- const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
2210
+ if ( this.state !== _STATE.NONE ) {
2216
2211
 
2217
- document.removeEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
2212
+ this.dispatchEvent( _startEvent );
2218
2213
 
2219
- }
2214
+ }
2220
2215
 
2221
- }
2216
+ }
2222
2217
 
2223
- function onKeyDown( event ) {
2218
+ function onMouseMove( event ) {
2224
2219
 
2225
- if ( scope.enabled === false || scope.enablePan === false ) return;
2220
+ switch ( this.state ) {
2226
2221
 
2227
- handleKeyDown( event );
2222
+ case _STATE.ROTATE:
2228
2223
 
2229
- }
2224
+ if ( this.enableRotate === false ) return;
2230
2225
 
2231
- function onTouchStart( event ) {
2226
+ this._handleMouseMoveRotate( event );
2232
2227
 
2233
- trackPointer( event );
2228
+ break;
2234
2229
 
2235
- switch ( pointers.length ) {
2230
+ case _STATE.DOLLY:
2236
2231
 
2237
- case 1:
2232
+ if ( this.enableZoom === false ) return;
2238
2233
 
2239
- switch ( scope.touches.ONE ) {
2234
+ this._handleMouseMoveDolly( event );
2240
2235
 
2241
- case three$1.TOUCH.ROTATE:
2236
+ break;
2242
2237
 
2243
- if ( scope.enableRotate === false ) return;
2238
+ case _STATE.PAN:
2244
2239
 
2245
- handleTouchStartRotate( event );
2240
+ if ( this.enablePan === false ) return;
2246
2241
 
2247
- state = STATE.TOUCH_ROTATE;
2242
+ this._handleMouseMovePan( event );
2248
2243
 
2249
- break;
2244
+ break;
2250
2245
 
2251
- case three$1.TOUCH.PAN:
2246
+ }
2252
2247
 
2253
- if ( scope.enablePan === false ) return;
2248
+ }
2254
2249
 
2255
- handleTouchStartPan( event );
2250
+ function onMouseWheel( event ) {
2256
2251
 
2257
- state = STATE.TOUCH_PAN;
2252
+ if ( this.enabled === false || this.enableZoom === false || this.state !== _STATE.NONE ) return;
2258
2253
 
2259
- break;
2254
+ event.preventDefault();
2260
2255
 
2261
- default:
2256
+ this.dispatchEvent( _startEvent );
2262
2257
 
2263
- state = STATE.NONE;
2258
+ this._handleMouseWheel( this._customWheelEvent( event ) );
2264
2259
 
2265
- }
2260
+ this.dispatchEvent( _endEvent );
2266
2261
 
2267
- break;
2262
+ }
2268
2263
 
2269
- case 2:
2264
+ function onKeyDown$1( event ) {
2270
2265
 
2271
- switch ( scope.touches.TWO ) {
2266
+ if ( this.enabled === false || this.enablePan === false ) return;
2272
2267
 
2273
- case three$1.TOUCH.DOLLY_PAN:
2268
+ this._handleKeyDown( event );
2274
2269
 
2275
- if ( scope.enableZoom === false && scope.enablePan === false ) return;
2270
+ }
2276
2271
 
2277
- handleTouchStartDollyPan( event );
2272
+ function onTouchStart( event ) {
2278
2273
 
2279
- state = STATE.TOUCH_DOLLY_PAN;
2274
+ this._trackPointer( event );
2280
2275
 
2281
- break;
2276
+ switch ( this._pointers.length ) {
2282
2277
 
2283
- case three$1.TOUCH.DOLLY_ROTATE:
2278
+ case 1:
2284
2279
 
2285
- if ( scope.enableZoom === false && scope.enableRotate === false ) return;
2280
+ switch ( this.touches.ONE ) {
2286
2281
 
2287
- handleTouchStartDollyRotate( event );
2282
+ case three$1.TOUCH.ROTATE:
2288
2283
 
2289
- state = STATE.TOUCH_DOLLY_ROTATE;
2284
+ if ( this.enableRotate === false ) return;
2290
2285
 
2291
- break;
2286
+ this._handleTouchStartRotate( event );
2292
2287
 
2293
- default:
2288
+ this.state = _STATE.TOUCH_ROTATE;
2294
2289
 
2295
- state = STATE.NONE;
2290
+ break;
2296
2291
 
2297
- }
2292
+ case three$1.TOUCH.PAN:
2298
2293
 
2299
- break;
2294
+ if ( this.enablePan === false ) return;
2300
2295
 
2301
- default:
2296
+ this._handleTouchStartPan( event );
2302
2297
 
2303
- state = STATE.NONE;
2298
+ this.state = _STATE.TOUCH_PAN;
2304
2299
 
2305
- }
2300
+ break;
2306
2301
 
2307
- if ( state !== STATE.NONE ) {
2302
+ default:
2308
2303
 
2309
- scope.dispatchEvent( _startEvent );
2304
+ this.state = _STATE.NONE;
2310
2305
 
2311
2306
  }
2312
2307
 
2313
- }
2314
-
2315
- function onTouchMove( event ) {
2308
+ break;
2316
2309
 
2317
- trackPointer( event );
2310
+ case 2:
2318
2311
 
2319
- switch ( state ) {
2312
+ switch ( this.touches.TWO ) {
2320
2313
 
2321
- case STATE.TOUCH_ROTATE:
2314
+ case three$1.TOUCH.DOLLY_PAN:
2322
2315
 
2323
- if ( scope.enableRotate === false ) return;
2316
+ if ( this.enableZoom === false && this.enablePan === false ) return;
2324
2317
 
2325
- handleTouchMoveRotate( event );
2318
+ this._handleTouchStartDollyPan( event );
2326
2319
 
2327
- scope.update();
2320
+ this.state = _STATE.TOUCH_DOLLY_PAN;
2328
2321
 
2329
2322
  break;
2330
2323
 
2331
- case STATE.TOUCH_PAN:
2324
+ case three$1.TOUCH.DOLLY_ROTATE:
2332
2325
 
2333
- if ( scope.enablePan === false ) return;
2326
+ if ( this.enableZoom === false && this.enableRotate === false ) return;
2334
2327
 
2335
- handleTouchMovePan( event );
2328
+ this._handleTouchStartDollyRotate( event );
2336
2329
 
2337
- scope.update();
2330
+ this.state = _STATE.TOUCH_DOLLY_ROTATE;
2338
2331
 
2339
2332
  break;
2340
2333
 
2341
- case STATE.TOUCH_DOLLY_PAN:
2334
+ default:
2342
2335
 
2343
- if ( scope.enableZoom === false && scope.enablePan === false ) return;
2336
+ this.state = _STATE.NONE;
2344
2337
 
2345
- handleTouchMoveDollyPan( event );
2338
+ }
2346
2339
 
2347
- scope.update();
2340
+ break;
2348
2341
 
2349
- break;
2342
+ default:
2350
2343
 
2351
- case STATE.TOUCH_DOLLY_ROTATE:
2344
+ this.state = _STATE.NONE;
2352
2345
 
2353
- if ( scope.enableZoom === false && scope.enableRotate === false ) return;
2346
+ }
2354
2347
 
2355
- handleTouchMoveDollyRotate( event );
2348
+ if ( this.state !== _STATE.NONE ) {
2356
2349
 
2357
- scope.update();
2350
+ this.dispatchEvent( _startEvent );
2358
2351
 
2359
- break;
2352
+ }
2360
2353
 
2361
- default:
2354
+ }
2362
2355
 
2363
- state = STATE.NONE;
2356
+ function onTouchMove( event ) {
2364
2357
 
2365
- }
2358
+ this._trackPointer( event );
2366
2359
 
2367
- }
2360
+ switch ( this.state ) {
2368
2361
 
2369
- function onContextMenu( event ) {
2362
+ case _STATE.TOUCH_ROTATE:
2370
2363
 
2371
- if ( scope.enabled === false ) return;
2364
+ if ( this.enableRotate === false ) return;
2372
2365
 
2373
- event.preventDefault();
2366
+ this._handleTouchMoveRotate( event );
2374
2367
 
2375
- }
2368
+ this.update();
2376
2369
 
2377
- function addPointer( event ) {
2370
+ break;
2378
2371
 
2379
- pointers.push( event.pointerId );
2372
+ case _STATE.TOUCH_PAN:
2380
2373
 
2381
- }
2374
+ if ( this.enablePan === false ) return;
2382
2375
 
2383
- function removePointer( event ) {
2376
+ this._handleTouchMovePan( event );
2384
2377
 
2385
- delete pointerPositions[ event.pointerId ];
2378
+ this.update();
2386
2379
 
2387
- for ( let i = 0; i < pointers.length; i ++ ) {
2380
+ break;
2388
2381
 
2389
- if ( pointers[ i ] == event.pointerId ) {
2382
+ case _STATE.TOUCH_DOLLY_PAN:
2390
2383
 
2391
- pointers.splice( i, 1 );
2392
- return;
2384
+ if ( this.enableZoom === false && this.enablePan === false ) return;
2393
2385
 
2394
- }
2386
+ this._handleTouchMoveDollyPan( event );
2395
2387
 
2396
- }
2388
+ this.update();
2397
2389
 
2398
- }
2390
+ break;
2399
2391
 
2400
- function isTrackingPointer( event ) {
2392
+ case _STATE.TOUCH_DOLLY_ROTATE:
2401
2393
 
2402
- for ( let i = 0; i < pointers.length; i ++ ) {
2394
+ if ( this.enableZoom === false && this.enableRotate === false ) return;
2403
2395
 
2404
- if ( pointers[ i ] == event.pointerId ) return true;
2396
+ this._handleTouchMoveDollyRotate( event );
2405
2397
 
2406
- }
2398
+ this.update();
2407
2399
 
2408
- return false;
2400
+ break;
2409
2401
 
2410
- }
2402
+ default:
2411
2403
 
2412
- function trackPointer( event ) {
2404
+ this.state = _STATE.NONE;
2413
2405
 
2414
- let position = pointerPositions[ event.pointerId ];
2406
+ }
2415
2407
 
2416
- if ( position === undefined ) {
2408
+ }
2417
2409
 
2418
- position = new three$1.Vector2();
2419
- pointerPositions[ event.pointerId ] = position;
2410
+ function onContextMenu$1( event ) {
2420
2411
 
2421
- }
2412
+ if ( this.enabled === false ) return;
2422
2413
 
2423
- position.set( event.pageX, event.pageY );
2414
+ event.preventDefault();
2424
2415
 
2425
- }
2416
+ }
2426
2417
 
2427
- function getSecondPointerPosition( event ) {
2418
+ function interceptControlDown( event ) {
2428
2419
 
2429
- const pointerId = ( event.pointerId === pointers[ 0 ] ) ? pointers[ 1 ] : pointers[ 0 ];
2420
+ if ( event.key === 'Control' ) {
2430
2421
 
2431
- return pointerPositions[ pointerId ];
2422
+ this._controlActive = true;
2432
2423
 
2433
- }
2424
+ const document = this.domElement.getRootNode(); // offscreen canvas compatibility
2434
2425
 
2435
- //
2426
+ document.addEventListener( 'keyup', this._interceptControlUp, { passive: true, capture: true } );
2427
+
2428
+ }
2436
2429
 
2437
- scope.domElement.addEventListener( 'contextmenu', onContextMenu );
2430
+ }
2438
2431
 
2439
- scope.domElement.addEventListener( 'pointerdown', onPointerDown );
2440
- scope.domElement.addEventListener( 'pointercancel', onPointerUp );
2441
- scope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );
2432
+ function interceptControlUp( event ) {
2442
2433
 
2443
- const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
2434
+ if ( event.key === 'Control' ) {
2444
2435
 
2445
- document.addEventListener( 'keydown', interceptControlDown, { passive: true, capture: true } );
2436
+ this._controlActive = false;
2446
2437
 
2447
- // force an update at start
2438
+ const document = this.domElement.getRootNode(); // offscreen canvas compatibility
2448
2439
 
2449
- this.update();
2440
+ document.removeEventListener( 'keyup', this._interceptControlUp, { passive: true, capture: true } );
2450
2441
 
2451
2442
  }
2452
2443
 
@@ -2454,19 +2445,14 @@
2454
2445
 
2455
2446
  const _changeEvent = { type: 'change' };
2456
2447
 
2457
- class FlyControls extends three$1.EventDispatcher {
2458
-
2459
- constructor( object, domElement ) {
2448
+ const _EPS = 0.000001;
2449
+ const _tmpQuaternion = new three$1.Quaternion();
2460
2450
 
2461
- super();
2462
-
2463
- this.object = object;
2464
- this.domElement = domElement;
2451
+ class FlyControls extends three$1.Controls {
2465
2452
 
2466
- // API
2453
+ constructor( object, domElement = null ) {
2467
2454
 
2468
- // Set to false to disable this control
2469
- this.enabled = true;
2455
+ super( object, domElement );
2470
2456
 
2471
2457
  this.movementSpeed = 1.0;
2472
2458
  this.rollSpeed = 0.005;
@@ -2474,301 +2460,312 @@
2474
2460
  this.dragToLook = false;
2475
2461
  this.autoForward = false;
2476
2462
 
2477
- // disable default target object behavior
2478
-
2479
2463
  // internals
2480
2464
 
2481
- const scope = this;
2465
+ this._moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 };
2466
+ this._moveVector = new three$1.Vector3( 0, 0, 0 );
2467
+ this._rotationVector = new three$1.Vector3( 0, 0, 0 );
2468
+ this._lastQuaternion = new three$1.Quaternion();
2469
+ this._lastPosition = new three$1.Vector3();
2470
+ this._status = 0;
2482
2471
 
2483
- const EPS = 0.000001;
2472
+ // event listeners
2484
2473
 
2485
- const lastQuaternion = new three$1.Quaternion();
2486
- const lastPosition = new three$1.Vector3();
2474
+ this._onKeyDown = onKeyDown.bind( this );
2475
+ this._onKeyUp = onKeyUp.bind( this );
2476
+ this._onPointerMove = onPointerMove.bind( this );
2477
+ this._onPointerDown = onPointerDown.bind( this );
2478
+ this._onPointerUp = onPointerUp.bind( this );
2479
+ this._onPointerCancel = onPointerCancel.bind( this );
2480
+ this._onContextMenu = onContextMenu.bind( this );
2481
+
2482
+ //
2487
2483
 
2488
- this.tmpQuaternion = new three$1.Quaternion();
2484
+ if ( domElement !== null ) {
2489
2485
 
2490
- this.status = 0;
2486
+ this.connect();
2491
2487
 
2492
- this.moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 };
2493
- this.moveVector = new three$1.Vector3( 0, 0, 0 );
2494
- this.rotationVector = new three$1.Vector3( 0, 0, 0 );
2488
+ }
2495
2489
 
2496
- this.keydown = function ( event ) {
2490
+ }
2497
2491
 
2498
- if ( event.altKey || this.enabled === false ) {
2492
+ connect() {
2499
2493
 
2500
- return;
2494
+ window.addEventListener( 'keydown', this._onKeyDown );
2495
+ window.addEventListener( 'keyup', this._onKeyUp );
2501
2496
 
2502
- }
2497
+ this.domElement.addEventListener( 'pointermove', this._onPointerMove );
2498
+ this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
2499
+ this.domElement.addEventListener( 'pointerup', this._onPointerUp );
2500
+ this.domElement.addEventListener( 'pointercancel', this._onPointerCancel );
2501
+ this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
2503
2502
 
2504
- switch ( event.code ) {
2503
+ }
2505
2504
 
2506
- case 'ShiftLeft':
2507
- case 'ShiftRight': this.movementSpeedMultiplier = .1; break;
2505
+ disconnect() {
2508
2506
 
2509
- case 'KeyW': this.moveState.forward = 1; break;
2510
- case 'KeyS': this.moveState.back = 1; break;
2507
+ window.removeEventListener( 'keydown', this._onKeyDown );
2508
+ window.removeEventListener( 'keyup', this._onKeyUp );
2511
2509
 
2512
- case 'KeyA': this.moveState.left = 1; break;
2513
- case 'KeyD': this.moveState.right = 1; break;
2510
+ this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
2511
+ this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
2512
+ this.domElement.removeEventListener( 'pointerup', this._onPointerUp );
2513
+ this.domElement.removeEventListener( 'pointercancel', this._onPointerCancel );
2514
+ this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
2514
2515
 
2515
- case 'KeyR': this.moveState.up = 1; break;
2516
- case 'KeyF': this.moveState.down = 1; break;
2516
+ }
2517
2517
 
2518
- case 'ArrowUp': this.moveState.pitchUp = 1; break;
2519
- case 'ArrowDown': this.moveState.pitchDown = 1; break;
2518
+ dispose() {
2520
2519
 
2521
- case 'ArrowLeft': this.moveState.yawLeft = 1; break;
2522
- case 'ArrowRight': this.moveState.yawRight = 1; break;
2520
+ this.disconnect();
2523
2521
 
2524
- case 'KeyQ': this.moveState.rollLeft = 1; break;
2525
- case 'KeyE': this.moveState.rollRight = 1; break;
2522
+ }
2526
2523
 
2527
- }
2524
+ update( delta ) {
2528
2525
 
2529
- this.updateMovementVector();
2530
- this.updateRotationVector();
2526
+ if ( this.enabled === false ) return;
2531
2527
 
2532
- };
2528
+ const object = this.object;
2533
2529
 
2534
- this.keyup = function ( event ) {
2530
+ const moveMult = delta * this.movementSpeed;
2531
+ const rotMult = delta * this.rollSpeed;
2535
2532
 
2536
- if ( this.enabled === false ) return;
2533
+ object.translateX( this._moveVector.x * moveMult );
2534
+ object.translateY( this._moveVector.y * moveMult );
2535
+ object.translateZ( this._moveVector.z * moveMult );
2537
2536
 
2538
- switch ( event.code ) {
2537
+ _tmpQuaternion.set( this._rotationVector.x * rotMult, this._rotationVector.y * rotMult, this._rotationVector.z * rotMult, 1 ).normalize();
2538
+ object.quaternion.multiply( _tmpQuaternion );
2539
2539
 
2540
- case 'ShiftLeft':
2541
- case 'ShiftRight': this.movementSpeedMultiplier = 1; break;
2540
+ if (
2541
+ this._lastPosition.distanceToSquared( object.position ) > _EPS ||
2542
+ 8 * ( 1 - this._lastQuaternion.dot( object.quaternion ) ) > _EPS
2543
+ ) {
2542
2544
 
2543
- case 'KeyW': this.moveState.forward = 0; break;
2544
- case 'KeyS': this.moveState.back = 0; break;
2545
+ this.dispatchEvent( _changeEvent );
2546
+ this._lastQuaternion.copy( object.quaternion );
2547
+ this._lastPosition.copy( object.position );
2545
2548
 
2546
- case 'KeyA': this.moveState.left = 0; break;
2547
- case 'KeyD': this.moveState.right = 0; break;
2549
+ }
2548
2550
 
2549
- case 'KeyR': this.moveState.up = 0; break;
2550
- case 'KeyF': this.moveState.down = 0; break;
2551
+ }
2551
2552
 
2552
- case 'ArrowUp': this.moveState.pitchUp = 0; break;
2553
- case 'ArrowDown': this.moveState.pitchDown = 0; break;
2553
+ // private
2554
2554
 
2555
- case 'ArrowLeft': this.moveState.yawLeft = 0; break;
2556
- case 'ArrowRight': this.moveState.yawRight = 0; break;
2555
+ _updateMovementVector() {
2557
2556
 
2558
- case 'KeyQ': this.moveState.rollLeft = 0; break;
2559
- case 'KeyE': this.moveState.rollRight = 0; break;
2557
+ const forward = ( this._moveState.forward || ( this.autoForward && ! this._moveState.back ) ) ? 1 : 0;
2560
2558
 
2561
- }
2559
+ this._moveVector.x = ( - this._moveState.left + this._moveState.right );
2560
+ this._moveVector.y = ( - this._moveState.down + this._moveState.up );
2561
+ this._moveVector.z = ( - forward + this._moveState.back );
2562
2562
 
2563
- this.updateMovementVector();
2564
- this.updateRotationVector();
2563
+ //console.log( 'move:', [ this._moveVector.x, this._moveVector.y, this._moveVector.z ] );
2565
2564
 
2566
- };
2565
+ }
2567
2566
 
2568
- this.pointerdown = function ( event ) {
2567
+ _updateRotationVector() {
2569
2568
 
2570
- if ( this.enabled === false ) return;
2569
+ this._rotationVector.x = ( - this._moveState.pitchDown + this._moveState.pitchUp );
2570
+ this._rotationVector.y = ( - this._moveState.yawRight + this._moveState.yawLeft );
2571
+ this._rotationVector.z = ( - this._moveState.rollRight + this._moveState.rollLeft );
2571
2572
 
2572
- if ( this.dragToLook ) {
2573
+ //console.log( 'rotate:', [ this._rotationVector.x, this._rotationVector.y, this._rotationVector.z ] );
2573
2574
 
2574
- this.status ++;
2575
+ }
2575
2576
 
2576
- } else {
2577
+ _getContainerDimensions() {
2577
2578
 
2578
- switch ( event.button ) {
2579
+ if ( this.domElement != document ) {
2579
2580
 
2580
- case 0: this.moveState.forward = 1; break;
2581
- case 2: this.moveState.back = 1; break;
2581
+ return {
2582
+ size: [ this.domElement.offsetWidth, this.domElement.offsetHeight ],
2583
+ offset: [ this.domElement.offsetLeft, this.domElement.offsetTop ]
2584
+ };
2582
2585
 
2583
- }
2586
+ } else {
2584
2587
 
2585
- this.updateMovementVector();
2588
+ return {
2589
+ size: [ window.innerWidth, window.innerHeight ],
2590
+ offset: [ 0, 0 ]
2591
+ };
2586
2592
 
2587
- }
2593
+ }
2588
2594
 
2589
- };
2595
+ }
2590
2596
 
2591
- this.pointermove = function ( event ) {
2597
+ }
2592
2598
 
2593
- if ( this.enabled === false ) return;
2599
+ function onKeyDown( event ) {
2594
2600
 
2595
- if ( ! this.dragToLook || this.status > 0 ) {
2601
+ if ( event.altKey || this.enabled === false ) {
2596
2602
 
2597
- const container = this.getContainerDimensions();
2598
- const halfWidth = container.size[ 0 ] / 2;
2599
- const halfHeight = container.size[ 1 ] / 2;
2603
+ return;
2600
2604
 
2601
- this.moveState.yawLeft = - ( ( event.pageX - container.offset[ 0 ] ) - halfWidth ) / halfWidth;
2602
- this.moveState.pitchDown = ( ( event.pageY - container.offset[ 1 ] ) - halfHeight ) / halfHeight;
2605
+ }
2603
2606
 
2604
- this.updateRotationVector();
2607
+ switch ( event.code ) {
2605
2608
 
2606
- }
2609
+ case 'ShiftLeft':
2610
+ case 'ShiftRight': this.movementSpeedMultiplier = .1; break;
2607
2611
 
2608
- };
2612
+ case 'KeyW': this._moveState.forward = 1; break;
2613
+ case 'KeyS': this._moveState.back = 1; break;
2609
2614
 
2610
- this.pointerup = function ( event ) {
2615
+ case 'KeyA': this._moveState.left = 1; break;
2616
+ case 'KeyD': this._moveState.right = 1; break;
2611
2617
 
2612
- if ( this.enabled === false ) return;
2618
+ case 'KeyR': this._moveState.up = 1; break;
2619
+ case 'KeyF': this._moveState.down = 1; break;
2613
2620
 
2614
- if ( this.dragToLook ) {
2621
+ case 'ArrowUp': this._moveState.pitchUp = 1; break;
2622
+ case 'ArrowDown': this._moveState.pitchDown = 1; break;
2615
2623
 
2616
- this.status --;
2624
+ case 'ArrowLeft': this._moveState.yawLeft = 1; break;
2625
+ case 'ArrowRight': this._moveState.yawRight = 1; break;
2617
2626
 
2618
- this.moveState.yawLeft = this.moveState.pitchDown = 0;
2627
+ case 'KeyQ': this._moveState.rollLeft = 1; break;
2628
+ case 'KeyE': this._moveState.rollRight = 1; break;
2619
2629
 
2620
- } else {
2630
+ }
2621
2631
 
2622
- switch ( event.button ) {
2632
+ this._updateMovementVector();
2633
+ this._updateRotationVector();
2623
2634
 
2624
- case 0: this.moveState.forward = 0; break;
2625
- case 2: this.moveState.back = 0; break;
2635
+ }
2626
2636
 
2627
- }
2637
+ function onKeyUp( event ) {
2628
2638
 
2629
- this.updateMovementVector();
2639
+ if ( this.enabled === false ) return;
2630
2640
 
2631
- }
2641
+ switch ( event.code ) {
2632
2642
 
2633
- this.updateRotationVector();
2643
+ case 'ShiftLeft':
2644
+ case 'ShiftRight': this.movementSpeedMultiplier = 1; break;
2634
2645
 
2635
- };
2646
+ case 'KeyW': this._moveState.forward = 0; break;
2647
+ case 'KeyS': this._moveState.back = 0; break;
2636
2648
 
2637
- this.pointercancel = function () {
2649
+ case 'KeyA': this._moveState.left = 0; break;
2650
+ case 'KeyD': this._moveState.right = 0; break;
2638
2651
 
2639
- if ( this.enabled === false ) return;
2652
+ case 'KeyR': this._moveState.up = 0; break;
2653
+ case 'KeyF': this._moveState.down = 0; break;
2640
2654
 
2641
- if ( this.dragToLook ) {
2655
+ case 'ArrowUp': this._moveState.pitchUp = 0; break;
2656
+ case 'ArrowDown': this._moveState.pitchDown = 0; break;
2642
2657
 
2643
- this.status = 0;
2658
+ case 'ArrowLeft': this._moveState.yawLeft = 0; break;
2659
+ case 'ArrowRight': this._moveState.yawRight = 0; break;
2644
2660
 
2645
- this.moveState.yawLeft = this.moveState.pitchDown = 0;
2661
+ case 'KeyQ': this._moveState.rollLeft = 0; break;
2662
+ case 'KeyE': this._moveState.rollRight = 0; break;
2646
2663
 
2647
- } else {
2664
+ }
2648
2665
 
2649
- this.moveState.forward = 0;
2650
- this.moveState.back = 0;
2666
+ this._updateMovementVector();
2667
+ this._updateRotationVector();
2651
2668
 
2652
- this.updateMovementVector();
2669
+ }
2653
2670
 
2654
- }
2671
+ function onPointerDown( event ) {
2655
2672
 
2656
- this.updateRotationVector();
2673
+ if ( this.enabled === false ) return;
2657
2674
 
2658
- };
2675
+ if ( this.dragToLook ) {
2659
2676
 
2660
- this.contextMenu = function ( event ) {
2677
+ this._status ++;
2661
2678
 
2662
- if ( this.enabled === false ) return;
2679
+ } else {
2663
2680
 
2664
- event.preventDefault();
2681
+ switch ( event.button ) {
2665
2682
 
2666
- };
2683
+ case 0: this._moveState.forward = 1; break;
2684
+ case 2: this._moveState.back = 1; break;
2667
2685
 
2668
- this.update = function ( delta ) {
2686
+ }
2669
2687
 
2670
- if ( this.enabled === false ) return;
2688
+ this._updateMovementVector();
2671
2689
 
2672
- const moveMult = delta * scope.movementSpeed;
2673
- const rotMult = delta * scope.rollSpeed;
2690
+ }
2674
2691
 
2675
- scope.object.translateX( scope.moveVector.x * moveMult );
2676
- scope.object.translateY( scope.moveVector.y * moveMult );
2677
- scope.object.translateZ( scope.moveVector.z * moveMult );
2692
+ }
2678
2693
 
2679
- scope.tmpQuaternion.set( scope.rotationVector.x * rotMult, scope.rotationVector.y * rotMult, scope.rotationVector.z * rotMult, 1 ).normalize();
2680
- scope.object.quaternion.multiply( scope.tmpQuaternion );
2694
+ function onPointerMove( event ) {
2681
2695
 
2682
- if (
2683
- lastPosition.distanceToSquared( scope.object.position ) > EPS ||
2684
- 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS
2685
- ) {
2696
+ if ( this.enabled === false ) return;
2686
2697
 
2687
- scope.dispatchEvent( _changeEvent );
2688
- lastQuaternion.copy( scope.object.quaternion );
2689
- lastPosition.copy( scope.object.position );
2698
+ if ( ! this.dragToLook || this._status > 0 ) {
2690
2699
 
2691
- }
2700
+ const container = this._getContainerDimensions();
2701
+ const halfWidth = container.size[ 0 ] / 2;
2702
+ const halfHeight = container.size[ 1 ] / 2;
2692
2703
 
2693
- };
2704
+ this._moveState.yawLeft = - ( ( event.pageX - container.offset[ 0 ] ) - halfWidth ) / halfWidth;
2705
+ this._moveState.pitchDown = ( ( event.pageY - container.offset[ 1 ] ) - halfHeight ) / halfHeight;
2694
2706
 
2695
- this.updateMovementVector = function () {
2707
+ this._updateRotationVector();
2696
2708
 
2697
- const forward = ( this.moveState.forward || ( this.autoForward && ! this.moveState.back ) ) ? 1 : 0;
2709
+ }
2698
2710
 
2699
- this.moveVector.x = ( - this.moveState.left + this.moveState.right );
2700
- this.moveVector.y = ( - this.moveState.down + this.moveState.up );
2701
- this.moveVector.z = ( - forward + this.moveState.back );
2711
+ }
2702
2712
 
2703
- //console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] );
2713
+ function onPointerUp( event ) {
2704
2714
 
2705
- };
2715
+ if ( this.enabled === false ) return;
2706
2716
 
2707
- this.updateRotationVector = function () {
2717
+ if ( this.dragToLook ) {
2708
2718
 
2709
- this.rotationVector.x = ( - this.moveState.pitchDown + this.moveState.pitchUp );
2710
- this.rotationVector.y = ( - this.moveState.yawRight + this.moveState.yawLeft );
2711
- this.rotationVector.z = ( - this.moveState.rollRight + this.moveState.rollLeft );
2719
+ this._status --;
2712
2720
 
2713
- //console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] );
2721
+ this._moveState.yawLeft = this._moveState.pitchDown = 0;
2714
2722
 
2715
- };
2723
+ } else {
2716
2724
 
2717
- this.getContainerDimensions = function () {
2725
+ switch ( event.button ) {
2718
2726
 
2719
- if ( this.domElement != document ) {
2727
+ case 0: this._moveState.forward = 0; break;
2728
+ case 2: this._moveState.back = 0; break;
2720
2729
 
2721
- return {
2722
- size: [ this.domElement.offsetWidth, this.domElement.offsetHeight ],
2723
- offset: [ this.domElement.offsetLeft, this.domElement.offsetTop ]
2724
- };
2730
+ }
2725
2731
 
2726
- } else {
2732
+ this._updateMovementVector();
2727
2733
 
2728
- return {
2729
- size: [ window.innerWidth, window.innerHeight ],
2730
- offset: [ 0, 0 ]
2731
- };
2734
+ }
2732
2735
 
2733
- }
2736
+ this._updateRotationVector();
2734
2737
 
2735
- };
2738
+ }
2736
2739
 
2737
- this.dispose = function () {
2740
+ function onPointerCancel() {
2738
2741
 
2739
- this.domElement.removeEventListener( 'contextmenu', _contextmenu );
2740
- this.domElement.removeEventListener( 'pointerdown', _pointerdown );
2741
- this.domElement.removeEventListener( 'pointermove', _pointermove );
2742
- this.domElement.removeEventListener( 'pointerup', _pointerup );
2743
- this.domElement.removeEventListener( 'pointercancel', _pointercancel );
2742
+ if ( this.enabled === false ) return;
2744
2743
 
2745
- window.removeEventListener( 'keydown', _keydown );
2746
- window.removeEventListener( 'keyup', _keyup );
2744
+ if ( this.dragToLook ) {
2747
2745
 
2748
- };
2746
+ this._status = 0;
2749
2747
 
2750
- const _contextmenu = this.contextMenu.bind( this );
2751
- const _pointermove = this.pointermove.bind( this );
2752
- const _pointerdown = this.pointerdown.bind( this );
2753
- const _pointerup = this.pointerup.bind( this );
2754
- const _pointercancel = this.pointercancel.bind( this );
2755
- const _keydown = this.keydown.bind( this );
2756
- const _keyup = this.keyup.bind( this );
2748
+ this._moveState.yawLeft = this._moveState.pitchDown = 0;
2757
2749
 
2758
- this.domElement.addEventListener( 'contextmenu', _contextmenu );
2759
- this.domElement.addEventListener( 'pointerdown', _pointerdown );
2760
- this.domElement.addEventListener( 'pointermove', _pointermove );
2761
- this.domElement.addEventListener( 'pointerup', _pointerup );
2762
- this.domElement.addEventListener( 'pointercancel', _pointercancel );
2750
+ } else {
2763
2751
 
2764
- window.addEventListener( 'keydown', _keydown );
2765
- window.addEventListener( 'keyup', _keyup );
2752
+ this._moveState.forward = 0;
2753
+ this._moveState.back = 0;
2766
2754
 
2767
- this.updateMovementVector();
2768
- this.updateRotationVector();
2755
+ this._updateMovementVector();
2769
2756
 
2770
2757
  }
2771
2758
 
2759
+ this._updateRotationVector();
2760
+
2761
+ }
2762
+
2763
+ function onContextMenu( event ) {
2764
+
2765
+ if ( this.enabled === false ) return;
2766
+
2767
+ event.preventDefault();
2768
+
2772
2769
  }
2773
2770
 
2774
2771
  /**
@@ -3330,7 +3327,7 @@
3330
3327
  if ( this.clearColor !== null ) {
3331
3328
 
3332
3329
  renderer.getClearColor( this._oldClearColor );
3333
- renderer.setClearColor( this.clearColor );
3330
+ renderer.setClearColor( this.clearColor, renderer.getClearAlpha() );
3334
3331
 
3335
3332
  }
3336
3333
 
@@ -3385,53 +3382,41 @@
3385
3382
  }
3386
3383
 
3387
3384
  function _extends() {
3388
- _extends = Object.assign ? Object.assign.bind() : function (target) {
3389
- for (var i = 1; i < arguments.length; i++) {
3390
- var source = arguments[i];
3391
- for (var key in source) {
3392
- if (Object.prototype.hasOwnProperty.call(source, key)) {
3393
- target[key] = source[key];
3394
- }
3395
- }
3385
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
3386
+ for (var e = 1; e < arguments.length; e++) {
3387
+ var t = arguments[e];
3388
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
3396
3389
  }
3397
- return target;
3398
- };
3399
- return _extends.apply(this, arguments);
3390
+ return n;
3391
+ }, _extends.apply(null, arguments);
3400
3392
  }
3401
3393
 
3402
- function _assertThisInitialized(self) {
3403
- if (self === void 0) {
3404
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
3405
- }
3406
- return self;
3394
+ function _assertThisInitialized(e) {
3395
+ if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
3396
+ return e;
3407
3397
  }
3408
3398
 
3409
- function _setPrototypeOf(o, p) {
3410
- _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
3411
- o.__proto__ = p;
3412
- return o;
3413
- };
3414
- return _setPrototypeOf(o, p);
3399
+ function _setPrototypeOf(t, e) {
3400
+ return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
3401
+ return t.__proto__ = e, t;
3402
+ }, _setPrototypeOf(t, e);
3415
3403
  }
3416
3404
 
3417
- function _inheritsLoose(subClass, superClass) {
3418
- subClass.prototype = Object.create(superClass.prototype);
3419
- subClass.prototype.constructor = subClass;
3420
- _setPrototypeOf(subClass, superClass);
3405
+ function _inheritsLoose(t, o) {
3406
+ t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o);
3421
3407
  }
3422
3408
 
3423
- function _getPrototypeOf(o) {
3424
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
3425
- return o.__proto__ || Object.getPrototypeOf(o);
3426
- };
3427
- return _getPrototypeOf(o);
3409
+ function _getPrototypeOf(t) {
3410
+ return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
3411
+ return t.__proto__ || Object.getPrototypeOf(t);
3412
+ }, _getPrototypeOf(t);
3428
3413
  }
3429
3414
 
3430
- function _isNativeFunction(fn) {
3415
+ function _isNativeFunction(t) {
3431
3416
  try {
3432
- return Function.toString.call(fn).indexOf("[native code]") !== -1;
3433
- } catch (e) {
3434
- return typeof fn === "function";
3417
+ return -1 !== Function.toString.call(t).indexOf("[native code]");
3418
+ } catch (n) {
3419
+ return "function" == typeof t;
3435
3420
  }
3436
3421
  }
3437
3422
 
@@ -3452,31 +3437,27 @@
3452
3437
  return r && _setPrototypeOf(p, r.prototype), p;
3453
3438
  }
3454
3439
 
3455
- function _wrapNativeSuper(Class) {
3456
- var _cache = typeof Map === "function" ? new Map() : undefined;
3457
- _wrapNativeSuper = function _wrapNativeSuper(Class) {
3458
- if (Class === null || !_isNativeFunction(Class)) return Class;
3459
- if (typeof Class !== "function") {
3460
- throw new TypeError("Super expression must either be null or a function");
3461
- }
3462
- if (typeof _cache !== "undefined") {
3463
- if (_cache.has(Class)) return _cache.get(Class);
3464
- _cache.set(Class, Wrapper);
3440
+ function _wrapNativeSuper(t) {
3441
+ var r = "function" == typeof Map ? new Map() : void 0;
3442
+ return _wrapNativeSuper = function _wrapNativeSuper(t) {
3443
+ if (null === t || !_isNativeFunction(t)) return t;
3444
+ if ("function" != typeof t) throw new TypeError("Super expression must either be null or a function");
3445
+ if (void 0 !== r) {
3446
+ if (r.has(t)) return r.get(t);
3447
+ r.set(t, Wrapper);
3465
3448
  }
3466
3449
  function Wrapper() {
3467
- return _construct(Class, arguments, _getPrototypeOf(this).constructor);
3450
+ return _construct(t, arguments, _getPrototypeOf(this).constructor);
3468
3451
  }
3469
- Wrapper.prototype = Object.create(Class.prototype, {
3452
+ return Wrapper.prototype = Object.create(t.prototype, {
3470
3453
  constructor: {
3471
3454
  value: Wrapper,
3472
- enumerable: false,
3473
- writable: true,
3474
- configurable: true
3455
+ enumerable: !1,
3456
+ writable: !0,
3457
+ configurable: !0
3475
3458
  }
3476
- });
3477
- return _setPrototypeOf(Wrapper, Class);
3478
- };
3479
- return _wrapNativeSuper(Class);
3459
+ }), _setPrototypeOf(Wrapper, t);
3460
+ }, _wrapNativeSuper(t);
3480
3461
  }
3481
3462
 
3482
3463
  // based on https://github.com/styled-components/styled-components/blob/fcf6f3804c57a14dd7984dfab7bc06ee2edca044/src/utils/error.js
@@ -4086,7 +4067,7 @@
4086
4067
  */
4087
4068
  function hsla(value, saturation, lightness, alpha) {
4088
4069
  if (typeof value === 'number' && typeof saturation === 'number' && typeof lightness === 'number' && typeof alpha === 'number') {
4089
- return "rgba(" + hslToRgb(value, saturation, lightness) + "," + alpha + ")";
4070
+ return alpha >= 1 ? hslToHex(value, saturation, lightness) : "rgba(" + hslToRgb(value, saturation, lightness) + "," + alpha + ")";
4090
4071
  } else if (typeof value === 'object' && saturation === undefined && lightness === undefined && alpha === undefined) {
4091
4072
  return value.alpha >= 1 ? hslToHex(value.hue, value.saturation, value.lightness) : "rgba(" + hslToRgb(value.hue, value.saturation, value.lightness) + "," + value.alpha + ")";
4092
4073
  }
@@ -4164,7 +4145,7 @@
4164
4145
  var rgbValue = parseToRgb(firstValue);
4165
4146
  return "rgba(" + rgbValue.red + "," + rgbValue.green + "," + rgbValue.blue + "," + secondValue + ")";
4166
4147
  } else if (typeof firstValue === 'number' && typeof secondValue === 'number' && typeof thirdValue === 'number' && typeof fourthValue === 'number') {
4167
- return "rgba(" + firstValue + "," + secondValue + "," + thirdValue + "," + fourthValue + ")";
4148
+ return fourthValue >= 1 ? rgb(firstValue, secondValue, thirdValue) : "rgba(" + firstValue + "," + secondValue + "," + thirdValue + "," + fourthValue + ")";
4168
4149
  } else if (typeof firstValue === 'object' && secondValue === undefined && thirdValue === undefined && fourthValue === undefined) {
4169
4150
  return firstValue.alpha >= 1 ? rgb(firstValue.red, firstValue.green, firstValue.blue) : "rgba(" + firstValue.red + "," + firstValue.green + "," + firstValue.blue + "," + firstValue.alpha + ")";
4170
4151
  }
@@ -4731,13 +4712,13 @@
4731
4712
  return amount;
4732
4713
  },
4733
4714
  In: function (amount) {
4734
- return this.None(amount);
4715
+ return amount;
4735
4716
  },
4736
4717
  Out: function (amount) {
4737
- return this.None(amount);
4718
+ return amount;
4738
4719
  },
4739
4720
  InOut: function (amount) {
4740
- return this.None(amount);
4721
+ return amount;
4741
4722
  },
4742
4723
  }),
4743
4724
  Quadratic: Object.freeze({
@@ -4947,33 +4928,61 @@
4947
4928
  */
4948
4929
  var Group = /** @class */ (function () {
4949
4930
  function Group() {
4931
+ var tweens = [];
4932
+ for (var _i = 0; _i < arguments.length; _i++) {
4933
+ tweens[_i] = arguments[_i];
4934
+ }
4950
4935
  this._tweens = {};
4951
4936
  this._tweensAddedDuringUpdate = {};
4937
+ this.add.apply(this, tweens);
4952
4938
  }
4953
4939
  Group.prototype.getAll = function () {
4954
4940
  var _this = this;
4955
- return Object.keys(this._tweens).map(function (tweenId) {
4956
- return _this._tweens[tweenId];
4957
- });
4941
+ return Object.keys(this._tweens).map(function (tweenId) { return _this._tweens[tweenId]; });
4958
4942
  };
4959
4943
  Group.prototype.removeAll = function () {
4960
4944
  this._tweens = {};
4961
4945
  };
4962
- Group.prototype.add = function (tween) {
4963
- this._tweens[tween.getId()] = tween;
4964
- this._tweensAddedDuringUpdate[tween.getId()] = tween;
4946
+ Group.prototype.add = function () {
4947
+ var _a;
4948
+ var tweens = [];
4949
+ for (var _i = 0; _i < arguments.length; _i++) {
4950
+ tweens[_i] = arguments[_i];
4951
+ }
4952
+ for (var _b = 0, tweens_1 = tweens; _b < tweens_1.length; _b++) {
4953
+ var tween = tweens_1[_b];
4954
+ // Remove from any other group first, a tween can only be in one group at a time.
4955
+ // @ts-expect-error library internal access
4956
+ (_a = tween._group) === null || _a === void 0 ? void 0 : _a.remove(tween);
4957
+ // @ts-expect-error library internal access
4958
+ tween._group = this;
4959
+ this._tweens[tween.getId()] = tween;
4960
+ this._tweensAddedDuringUpdate[tween.getId()] = tween;
4961
+ }
4962
+ };
4963
+ Group.prototype.remove = function () {
4964
+ var tweens = [];
4965
+ for (var _i = 0; _i < arguments.length; _i++) {
4966
+ tweens[_i] = arguments[_i];
4967
+ }
4968
+ for (var _a = 0, tweens_2 = tweens; _a < tweens_2.length; _a++) {
4969
+ var tween = tweens_2[_a];
4970
+ // @ts-expect-error library internal access
4971
+ tween._group = undefined;
4972
+ delete this._tweens[tween.getId()];
4973
+ delete this._tweensAddedDuringUpdate[tween.getId()];
4974
+ }
4965
4975
  };
4966
- Group.prototype.remove = function (tween) {
4967
- delete this._tweens[tween.getId()];
4968
- delete this._tweensAddedDuringUpdate[tween.getId()];
4976
+ /** Return true if all tweens in the group are not paused or playing. */
4977
+ Group.prototype.allStopped = function () {
4978
+ return this.getAll().every(function (tween) { return !tween.isPlaying(); });
4969
4979
  };
4970
4980
  Group.prototype.update = function (time, preserve) {
4971
4981
  if (time === void 0) { time = now$1(); }
4972
- if (preserve === void 0) { preserve = false; }
4982
+ if (preserve === void 0) { preserve = true; }
4973
4983
  var tweenIds = Object.keys(this._tweens);
4974
- if (tweenIds.length === 0) {
4975
- return false;
4976
- }
4984
+ if (tweenIds.length === 0)
4985
+ return;
4977
4986
  // Tweens are updated in "batches". If you add a new tween during an
4978
4987
  // update, then the new tween will be updated in the next batch.
4979
4988
  // If you remove a tween during an update, it may or may not be updated.
@@ -4984,13 +4993,11 @@
4984
4993
  for (var i = 0; i < tweenIds.length; i++) {
4985
4994
  var tween = this._tweens[tweenIds[i]];
4986
4995
  var autoStart = !preserve;
4987
- if (tween && tween.update(time, autoStart) === false && !preserve) {
4988
- delete this._tweens[tweenIds[i]];
4989
- }
4996
+ if (tween && tween.update(time, autoStart) === false && !preserve)
4997
+ this.remove(tween);
4990
4998
  }
4991
4999
  tweenIds = Object.keys(this._tweensAddedDuringUpdate);
4992
5000
  }
4993
- return true;
4994
5001
  };
4995
5002
  return Group;
4996
5003
  }());
@@ -5099,10 +5106,7 @@
5099
5106
  * Thank you all, you're awesome!
5100
5107
  */
5101
5108
  var Tween = /** @class */ (function () {
5102
- function Tween(_object, _group) {
5103
- if (_group === void 0) { _group = mainGroup; }
5104
- this._object = _object;
5105
- this._group = _group;
5109
+ function Tween(object, group) {
5106
5110
  this._isPaused = false;
5107
5111
  this._pauseStart = 0;
5108
5112
  this._valuesStart = {};
@@ -5127,6 +5131,16 @@
5127
5131
  this._isChainStopped = false;
5128
5132
  this._propertiesAreSetUp = false;
5129
5133
  this._goToEnd = false;
5134
+ this._object = object;
5135
+ if (typeof group === 'object') {
5136
+ this._group = group;
5137
+ group.add(this);
5138
+ }
5139
+ // Use "true" to restore old behavior (will be removed in future release).
5140
+ else if (group === true) {
5141
+ this._group = mainGroup;
5142
+ mainGroup.add(this);
5143
+ }
5130
5144
  }
5131
5145
  Tween.prototype.getId = function () {
5132
5146
  return this._id;
@@ -5165,8 +5179,6 @@
5165
5179
  if (this._isPlaying) {
5166
5180
  return this;
5167
5181
  }
5168
- // eslint-disable-next-line
5169
- this._group && this._group.add(this);
5170
5182
  this._repeat = this._initialRepeat;
5171
5183
  if (this._reversed) {
5172
5184
  // If we were reversed (f.e. using the yoyo feature) then we need to
@@ -5283,8 +5295,6 @@
5283
5295
  if (!this._isPlaying) {
5284
5296
  return this;
5285
5297
  }
5286
- // eslint-disable-next-line
5287
- this._group && this._group.remove(this);
5288
5298
  this._isPlaying = false;
5289
5299
  this._isPaused = false;
5290
5300
  if (this._onStopCallback) {
@@ -5294,7 +5304,7 @@
5294
5304
  };
5295
5305
  Tween.prototype.end = function () {
5296
5306
  this._goToEnd = true;
5297
- this.update(Infinity);
5307
+ this.update(this._startTime + this._duration);
5298
5308
  return this;
5299
5309
  };
5300
5310
  Tween.prototype.pause = function (time) {
@@ -5304,8 +5314,6 @@
5304
5314
  }
5305
5315
  this._isPaused = true;
5306
5316
  this._pauseStart = time;
5307
- // eslint-disable-next-line
5308
- this._group && this._group.remove(this);
5309
5317
  return this;
5310
5318
  };
5311
5319
  Tween.prototype.resume = function (time) {
@@ -5316,8 +5324,6 @@
5316
5324
  this._isPaused = false;
5317
5325
  this._startTime += time - this._pauseStart;
5318
5326
  this._pauseStart = 0;
5319
- // eslint-disable-next-line
5320
- this._group && this._group.add(this);
5321
5327
  return this;
5322
5328
  };
5323
5329
  Tween.prototype.stopChainedTweens = function () {
@@ -5327,8 +5333,19 @@
5327
5333
  return this;
5328
5334
  };
5329
5335
  Tween.prototype.group = function (group) {
5330
- if (group === void 0) { group = mainGroup; }
5331
- this._group = group;
5336
+ if (!group) {
5337
+ console.warn('tween.group() without args has been removed, use group.add(tween) instead.');
5338
+ return this;
5339
+ }
5340
+ group.add(this);
5341
+ return this;
5342
+ };
5343
+ /**
5344
+ * Removes the tween from whichever group it is in.
5345
+ */
5346
+ Tween.prototype.remove = function () {
5347
+ var _a;
5348
+ (_a = this._group) === null || _a === void 0 ? void 0 : _a.remove(this);
5332
5349
  return this;
5333
5350
  };
5334
5351
  Tween.prototype.delay = function (amount) {
@@ -5398,21 +5415,24 @@
5398
5415
  * @returns true if the tween is still playing after the update, false
5399
5416
  * otherwise (calling update on a paused tween still returns true because
5400
5417
  * it is still playing, just paused).
5418
+ *
5419
+ * @param autoStart - When true, calling update will implicitly call start()
5420
+ * as well. Note, if you stop() or end() the tween, but are still calling
5421
+ * update(), it will start again!
5401
5422
  */
5402
5423
  Tween.prototype.update = function (time, autoStart) {
5403
5424
  var _this = this;
5404
5425
  var _a;
5405
5426
  if (time === void 0) { time = now$1(); }
5406
- if (autoStart === void 0) { autoStart = true; }
5427
+ if (autoStart === void 0) { autoStart = Tween.autoStartOnUpdate; }
5407
5428
  if (this._isPaused)
5408
5429
  return true;
5409
5430
  var property;
5410
- var endTime = this._startTime + this._duration;
5411
5431
  if (!this._goToEnd && !this._isPlaying) {
5412
- if (time > endTime)
5413
- return false;
5414
5432
  if (autoStart)
5415
5433
  this.start(time, true);
5434
+ else
5435
+ return false;
5416
5436
  }
5417
5437
  this._goToEnd = false;
5418
5438
  if (time < this._startTime) {
@@ -5551,6 +5571,7 @@
5551
5571
  }
5552
5572
  this._valuesEnd[property] = tmp;
5553
5573
  };
5574
+ Tween.autoStartOnUpdate = false;
5554
5575
  return Tween;
5555
5576
  }());
5556
5577
  /**
@@ -5564,11 +5585,246 @@
5564
5585
  // Modules and CommonJS, without build hacks, and so as not to break the
5565
5586
  // existing API.
5566
5587
  // https://github.com/rollup/rollup/issues/1961#issuecomment-423037881
5588
+ /**
5589
+ * @deprecated The global TWEEN Group will be removed in a following major
5590
+ * release. To migrate, create a `new Group()` instead of using `TWEEN` as a
5591
+ * group.
5592
+ *
5593
+ * Old code:
5594
+ *
5595
+ * ```js
5596
+ * import * as TWEEN from '@tweenjs/tween.js'
5597
+ *
5598
+ * //...
5599
+ *
5600
+ * const tween = new TWEEN.Tween(obj)
5601
+ * const tween2 = new TWEEN.Tween(obj2)
5602
+ *
5603
+ * //...
5604
+ *
5605
+ * requestAnimationFrame(function loop(time) {
5606
+ * TWEEN.update(time)
5607
+ * requestAnimationFrame(loop)
5608
+ * })
5609
+ * ```
5610
+ *
5611
+ * New code:
5612
+ *
5613
+ * ```js
5614
+ * import {Tween, Group} from '@tweenjs/tween.js'
5615
+ *
5616
+ * //...
5617
+ *
5618
+ * const tween = new Tween(obj)
5619
+ * const tween2 = new TWEEN.Tween(obj2)
5620
+ *
5621
+ * //...
5622
+ *
5623
+ * const group = new Group()
5624
+ * group.add(tween)
5625
+ * group.add(tween2)
5626
+ *
5627
+ * //...
5628
+ *
5629
+ * requestAnimationFrame(function loop(time) {
5630
+ * group.update(time)
5631
+ * requestAnimationFrame(loop)
5632
+ * })
5633
+ * ```
5634
+ */
5567
5635
  TWEEN.getAll.bind(TWEEN);
5636
+ /**
5637
+ * @deprecated The global TWEEN Group will be removed in a following major
5638
+ * release. To migrate, create a `new Group()` instead of using `TWEEN` as a
5639
+ * group.
5640
+ *
5641
+ * Old code:
5642
+ *
5643
+ * ```js
5644
+ * import * as TWEEN from '@tweenjs/tween.js'
5645
+ *
5646
+ * //...
5647
+ *
5648
+ * const tween = new TWEEN.Tween(obj)
5649
+ * const tween2 = new TWEEN.Tween(obj2)
5650
+ *
5651
+ * //...
5652
+ *
5653
+ * requestAnimationFrame(function loop(time) {
5654
+ * TWEEN.update(time)
5655
+ * requestAnimationFrame(loop)
5656
+ * })
5657
+ * ```
5658
+ *
5659
+ * New code:
5660
+ *
5661
+ * ```js
5662
+ * import {Tween, Group} from '@tweenjs/tween.js'
5663
+ *
5664
+ * //...
5665
+ *
5666
+ * const tween = new Tween(obj)
5667
+ * const tween2 = new TWEEN.Tween(obj2)
5668
+ *
5669
+ * //...
5670
+ *
5671
+ * const group = new Group()
5672
+ * group.add(tween)
5673
+ * group.add(tween2)
5674
+ *
5675
+ * //...
5676
+ *
5677
+ * requestAnimationFrame(function loop(time) {
5678
+ * group.update(time)
5679
+ * requestAnimationFrame(loop)
5680
+ * })
5681
+ * ```
5682
+ */
5568
5683
  TWEEN.removeAll.bind(TWEEN);
5684
+ /**
5685
+ * @deprecated The global TWEEN Group will be removed in a following major
5686
+ * release. To migrate, create a `new Group()` instead of using `TWEEN` as a
5687
+ * group.
5688
+ *
5689
+ * Old code:
5690
+ *
5691
+ * ```js
5692
+ * import * as TWEEN from '@tweenjs/tween.js'
5693
+ *
5694
+ * //...
5695
+ *
5696
+ * const tween = new TWEEN.Tween(obj)
5697
+ * const tween2 = new TWEEN.Tween(obj2)
5698
+ *
5699
+ * //...
5700
+ *
5701
+ * requestAnimationFrame(function loop(time) {
5702
+ * TWEEN.update(time)
5703
+ * requestAnimationFrame(loop)
5704
+ * })
5705
+ * ```
5706
+ *
5707
+ * New code:
5708
+ *
5709
+ * ```js
5710
+ * import {Tween, Group} from '@tweenjs/tween.js'
5711
+ *
5712
+ * //...
5713
+ *
5714
+ * const tween = new Tween(obj)
5715
+ * const tween2 = new TWEEN.Tween(obj2)
5716
+ *
5717
+ * //...
5718
+ *
5719
+ * const group = new Group()
5720
+ * group.add(tween)
5721
+ * group.add(tween2)
5722
+ *
5723
+ * //...
5724
+ *
5725
+ * requestAnimationFrame(function loop(time) {
5726
+ * group.update(time)
5727
+ * requestAnimationFrame(loop)
5728
+ * })
5729
+ * ```
5730
+ */
5569
5731
  TWEEN.add.bind(TWEEN);
5732
+ /**
5733
+ * @deprecated The global TWEEN Group will be removed in a following major
5734
+ * release. To migrate, create a `new Group()` instead of using `TWEEN` as a
5735
+ * group.
5736
+ *
5737
+ * Old code:
5738
+ *
5739
+ * ```js
5740
+ * import * as TWEEN from '@tweenjs/tween.js'
5741
+ *
5742
+ * //...
5743
+ *
5744
+ * const tween = new TWEEN.Tween(obj)
5745
+ * const tween2 = new TWEEN.Tween(obj2)
5746
+ *
5747
+ * //...
5748
+ *
5749
+ * requestAnimationFrame(function loop(time) {
5750
+ * TWEEN.update(time)
5751
+ * requestAnimationFrame(loop)
5752
+ * })
5753
+ * ```
5754
+ *
5755
+ * New code:
5756
+ *
5757
+ * ```js
5758
+ * import {Tween, Group} from '@tweenjs/tween.js'
5759
+ *
5760
+ * //...
5761
+ *
5762
+ * const tween = new Tween(obj)
5763
+ * const tween2 = new TWEEN.Tween(obj2)
5764
+ *
5765
+ * //...
5766
+ *
5767
+ * const group = new Group()
5768
+ * group.add(tween)
5769
+ * group.add(tween2)
5770
+ *
5771
+ * //...
5772
+ *
5773
+ * requestAnimationFrame(function loop(time) {
5774
+ * group.update(time)
5775
+ * requestAnimationFrame(loop)
5776
+ * })
5777
+ * ```
5778
+ */
5570
5779
  TWEEN.remove.bind(TWEEN);
5571
- var update = TWEEN.update.bind(TWEEN);
5780
+ /**
5781
+ * @deprecated The global TWEEN Group will be removed in a following major
5782
+ * release. To migrate, create a `new Group()` instead of using `TWEEN` as a
5783
+ * group.
5784
+ *
5785
+ * Old code:
5786
+ *
5787
+ * ```js
5788
+ * import * as TWEEN from '@tweenjs/tween.js'
5789
+ *
5790
+ * //...
5791
+ *
5792
+ * const tween = new TWEEN.Tween(obj)
5793
+ * const tween2 = new TWEEN.Tween(obj2)
5794
+ *
5795
+ * //...
5796
+ *
5797
+ * requestAnimationFrame(function loop(time) {
5798
+ * TWEEN.update(time)
5799
+ * requestAnimationFrame(loop)
5800
+ * })
5801
+ * ```
5802
+ *
5803
+ * New code:
5804
+ *
5805
+ * ```js
5806
+ * import {Tween, Group} from '@tweenjs/tween.js'
5807
+ *
5808
+ * //...
5809
+ *
5810
+ * const tween = new Tween(obj)
5811
+ * const tween2 = new TWEEN.Tween(obj2)
5812
+ *
5813
+ * //...
5814
+ *
5815
+ * const group = new Group()
5816
+ * group.add(tween)
5817
+ * group.add(tween2)
5818
+ *
5819
+ * //...
5820
+ *
5821
+ * requestAnimationFrame(function loop(time) {
5822
+ * group.update(time)
5823
+ * requestAnimationFrame(loop)
5824
+ * })
5825
+ * ```
5826
+ */
5827
+ TWEEN.update.bind(TWEEN);
5572
5828
 
5573
5829
  var index$1 = (function (p) {
5574
5830
  return typeof p === 'function' ? p // fn
@@ -6111,7 +6367,7 @@
6111
6367
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
6112
6368
  }
6113
6369
  function _arrayLikeToArray(arr, len) {
6114
- if (len > arr.length) len = arr.length;
6370
+ if (len == null || len > arr.length) len = arr.length;
6115
6371
  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
6116
6372
  return arr2;
6117
6373
  }
@@ -6380,7 +6636,7 @@
6380
6636
  state.hoverObj = topObject;
6381
6637
  }
6382
6638
  }
6383
- update(); // update camera animation tweens
6639
+ state.tweenGroup.update(); // update camera animation tweens
6384
6640
  }
6385
6641
  return this;
6386
6642
  },
@@ -6411,10 +6667,10 @@
6411
6667
  } else {
6412
6668
  var camPos = Object.assign({}, camera.position);
6413
6669
  var camLookAt = getLookAt();
6414
- new Tween(camPos).to(finalPos, transitionDuration).easing(Easing.Quadratic.Out).onUpdate(setCameraPos).start();
6670
+ state.tweenGroup.add(new Tween(camPos).to(finalPos, transitionDuration).easing(Easing.Quadratic.Out).onUpdate(setCameraPos).start());
6415
6671
 
6416
6672
  // Face direction in 1/3rd of time
6417
- new Tween(camLookAt).to(finalLookAt, transitionDuration / 3).easing(Easing.Quadratic.Out).onUpdate(setLookAt).start();
6673
+ state.tweenGroup.add(new Tween(camLookAt).to(finalLookAt, transitionDuration / 3).easing(Easing.Quadratic.Out).onUpdate(setLookAt).start());
6418
6674
  }
6419
6675
  return this;
6420
6676
  }
@@ -6545,7 +6801,8 @@
6545
6801
  return {
6546
6802
  scene: new three.Scene(),
6547
6803
  camera: new three.PerspectiveCamera(),
6548
- clock: new three.Clock()
6804
+ clock: new three.Clock(),
6805
+ tweenGroup: new Group()
6549
6806
  };
6550
6807
  },
6551
6808
  init: function init(domNode, state) {