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