Web Inspector: Add three.js in preparation for layer visualization.
[WebKit-https.git] / Source / WebInspectorUI / UserInterface / External / three.js / OrbitControls.js
1 /**
2  * @author qiao / https://github.com/qiao
3  * @author mrdoob / http://mrdoob.com
4  * @author alteredq / http://alteredqualia.com/
5  * @author WestLangley / http://github.com/WestLangley
6  * @author erich666 / http://erichaines.com
7  */
8
9 // This set of controls performs orbiting, dollying (zooming), and panning.
10 // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
11 //
12 //    Orbit - left mouse / touch: one finger move
13 //    Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
14 //    Pan - right mouse, or arrow keys / touch: three finger swipe
15
16 THREE.OrbitControls = function ( object, domElement ) {
17
18     this.object = object;
19
20     this.domElement = ( domElement !== undefined ) ? domElement : document;
21
22     // Set to false to disable this control
23     this.enabled = true;
24
25     // "target" sets the location of focus, where the object orbits around
26     this.target = new THREE.Vector3();
27
28     // How far you can dolly in and out ( PerspectiveCamera only )
29     this.minDistance = 0;
30     this.maxDistance = Infinity;
31
32     // How far you can zoom in and out ( OrthographicCamera only )
33     this.minZoom = 0;
34     this.maxZoom = Infinity;
35
36     // How far you can orbit vertically, upper and lower limits.
37     // Range is 0 to Math.PI radians.
38     this.minPolarAngle = 0; // radians
39     this.maxPolarAngle = Math.PI; // radians
40
41     // How far you can orbit horizontally, upper and lower limits.
42     // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
43     this.minAzimuthAngle = - Infinity; // radians
44     this.maxAzimuthAngle = Infinity; // radians
45
46     // Set to true to enable damping (inertia)
47     // If damping is enabled, you must call controls.update() in your animation loop
48     this.enableDamping = false;
49     this.dampingFactor = 0.25;
50
51     // This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
52     // Set to false to disable zooming
53     this.enableZoom = true;
54     this.zoomSpeed = 1.0;
55
56     // Set to false to disable rotating
57     this.enableRotate = true;
58     this.rotateSpeed = 1.0;
59
60     // Set to false to disable panning
61     this.enablePan = true;
62     this.keyPanSpeed = 7.0; // pixels moved per arrow key push
63
64     // Set to true to automatically rotate around the target
65     // If auto-rotate is enabled, you must call controls.update() in your animation loop
66     this.autoRotate = false;
67     this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
68
69     // Set to false to disable use of the keys
70     this.enableKeys = true;
71
72     // The four arrow keys
73     this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
74
75     // Mouse buttons
76     this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };
77
78     // for reset
79     this.target0 = this.target.clone();
80     this.position0 = this.object.position.clone();
81     this.zoom0 = this.object.zoom;
82
83     //
84     // public methods
85     //
86
87     this.getPolarAngle = function () {
88
89         return spherical.phi;
90
91     };
92
93     this.getAzimuthalAngle = function () {
94
95         return spherical.theta;
96
97     };
98
99     this.saveState = function () {
100
101         scope.target0.copy( scope.target );
102         scope.position0.copy( scope.object.position );
103         scope.zoom0 = scope.object.zoom;
104
105     };
106
107     this.reset = function () {
108
109         scope.target.copy( scope.target0 );
110         scope.object.position.copy( scope.position0 );
111         scope.object.zoom = scope.zoom0;
112
113         scope.object.updateProjectionMatrix();
114         scope.dispatchEvent( changeEvent );
115
116         scope.update();
117
118         state = STATE.NONE;
119
120     };
121
122     // this method is exposed, but perhaps it would be better if we can make it private...
123     this.update = function () {
124
125         var offset = new THREE.Vector3();
126
127         // so camera.up is the orbit axis
128         var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
129         var quatInverse = quat.clone().inverse();
130
131         var lastPosition = new THREE.Vector3();
132         var lastQuaternion = new THREE.Quaternion();
133
134         return function update() {
135
136             var position = scope.object.position;
137
138             offset.copy( position ).sub( scope.target );
139
140             // rotate offset to "y-axis-is-up" space
141             offset.applyQuaternion( quat );
142
143             // angle from z-axis around y-axis
144             spherical.setFromVector3( offset );
145
146             if ( scope.autoRotate && state === STATE.NONE ) {
147
148                 rotateLeft( getAutoRotationAngle() );
149
150             }
151
152             spherical.theta += sphericalDelta.theta;
153             spherical.phi += sphericalDelta.phi;
154
155             // restrict theta to be between desired limits
156             spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
157
158             // restrict phi to be between desired limits
159             spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
160
161             spherical.makeSafe();
162
163
164             spherical.radius *= scale;
165
166             // restrict radius to be between desired limits
167             spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
168
169             // move target to panned location
170             scope.target.add( panOffset );
171
172             offset.setFromSpherical( spherical );
173
174             // rotate offset back to "camera-up-vector-is-up" space
175             offset.applyQuaternion( quatInverse );
176
177             position.copy( scope.target ).add( offset );
178
179             scope.object.lookAt( scope.target );
180
181             if ( scope.enableDamping === true ) {
182
183                 sphericalDelta.theta *= ( 1 - scope.dampingFactor );
184                 sphericalDelta.phi *= ( 1 - scope.dampingFactor );
185
186             } else {
187
188                 sphericalDelta.set( 0, 0, 0 );
189
190             }
191
192             scale = 1;
193             panOffset.set( 0, 0, 0 );
194
195             // update condition is:
196             // min(camera displacement, camera rotation in radians)^2 > EPS
197             // using small-angle approximation cos(x/2) = 1 - x^2 / 8
198
199             if ( zoomChanged ||
200                 lastPosition.distanceToSquared( scope.object.position ) > EPS ||
201                 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
202
203                 scope.dispatchEvent( changeEvent );
204
205                 lastPosition.copy( scope.object.position );
206                 lastQuaternion.copy( scope.object.quaternion );
207                 zoomChanged = false;
208
209                 return true;
210
211             }
212
213             return false;
214
215         };
216
217     }();
218
219     this.dispose = function () {
220
221         scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );
222         scope.domElement.removeEventListener( 'mousedown', onMouseDown, false );
223         scope.domElement.removeEventListener( 'wheel', onMouseWheel, false );
224
225         scope.domElement.removeEventListener( 'touchstart', onTouchStart, false );
226         scope.domElement.removeEventListener( 'touchend', onTouchEnd, false );
227         scope.domElement.removeEventListener( 'touchmove', onTouchMove, false );
228
229         document.removeEventListener( 'mousemove', onMouseMove, false );
230         document.removeEventListener( 'mouseup', onMouseUp, false );
231
232         window.removeEventListener( 'keydown', onKeyDown, false );
233
234         //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
235
236     };
237
238     //
239     // internals
240     //
241
242     var scope = this;
243
244     var changeEvent = { type: 'change' };
245     var startEvent = { type: 'start' };
246     var endEvent = { type: 'end' };
247
248     var STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };
249
250     var state = STATE.NONE;
251
252     var EPS = 0.000001;
253
254     // current position in spherical coordinates
255     var spherical = new THREE.Spherical();
256     var sphericalDelta = new THREE.Spherical();
257
258     var scale = 1;
259     var panOffset = new THREE.Vector3();
260     var zoomChanged = false;
261
262     var rotateStart = new THREE.Vector2();
263     var rotateEnd = new THREE.Vector2();
264     var rotateDelta = new THREE.Vector2();
265
266     var panStart = new THREE.Vector2();
267     var panEnd = new THREE.Vector2();
268     var panDelta = new THREE.Vector2();
269
270     var dollyStart = new THREE.Vector2();
271     var dollyEnd = new THREE.Vector2();
272     var dollyDelta = new THREE.Vector2();
273
274     function getAutoRotationAngle() {
275
276         return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
277
278     }
279
280     function getZoomScale() {
281
282         return Math.pow( 0.95, scope.zoomSpeed );
283
284     }
285
286     function rotateLeft( angle ) {
287
288         sphericalDelta.theta -= angle;
289
290     }
291
292     function rotateUp( angle ) {
293
294         sphericalDelta.phi -= angle;
295
296     }
297
298     var panLeft = function () {
299
300         var v = new THREE.Vector3();
301
302         return function panLeft( distance, objectMatrix ) {
303
304             v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
305             v.multiplyScalar( - distance );
306
307             panOffset.add( v );
308
309         };
310
311     }();
312
313     var panUp = function () {
314
315         var v = new THREE.Vector3();
316
317         return function panUp( distance, objectMatrix ) {
318
319             v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix
320             v.multiplyScalar( distance );
321
322             panOffset.add( v );
323
324         };
325
326     }();
327
328     // deltaX and deltaY are in pixels; right and down are positive
329     var pan = function () {
330
331         var offset = new THREE.Vector3();
332
333         return function pan( deltaX, deltaY ) {
334
335             var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
336
337             if ( scope.object instanceof THREE.PerspectiveCamera ) {
338
339                 // perspective
340                 var position = scope.object.position;
341                 offset.copy( position ).sub( scope.target );
342                 var targetDistance = offset.length();
343
344                 // half of the fov is center to top of screen
345                 targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
346
347                 // we actually don't use screenWidth, since perspective camera is fixed to screen height
348                 panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
349                 panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
350
351             } else if ( scope.object instanceof THREE.OrthographicCamera ) {
352
353                 // orthographic
354                 panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
355                 panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
356
357             } else {
358
359                 // camera neither orthographic nor perspective
360                 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
361                 scope.enablePan = false;
362
363             }
364
365         };
366
367     }();
368
369     function dollyIn( dollyScale ) {
370
371         if ( scope.object instanceof THREE.PerspectiveCamera ) {
372
373             scale /= dollyScale;
374
375         } else if ( scope.object instanceof THREE.OrthographicCamera ) {
376
377             scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );
378             scope.object.updateProjectionMatrix();
379             zoomChanged = true;
380
381         } else {
382
383             console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
384             scope.enableZoom = false;
385
386         }
387
388     }
389
390     function dollyOut( dollyScale ) {
391
392         if ( scope.object instanceof THREE.PerspectiveCamera ) {
393
394             scale *= dollyScale;
395
396         } else if ( scope.object instanceof THREE.OrthographicCamera ) {
397
398             scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );
399             scope.object.updateProjectionMatrix();
400             zoomChanged = true;
401
402         } else {
403
404             console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
405             scope.enableZoom = false;
406
407         }
408
409     }
410
411     //
412     // event callbacks - update the object state
413     //
414
415     function handleMouseDownRotate( event ) {
416
417         //console.log( 'handleMouseDownRotate' );
418
419         rotateStart.set( event.clientX, event.clientY );
420
421     }
422
423     function handleMouseDownDolly( event ) {
424
425         //console.log( 'handleMouseDownDolly' );
426
427         dollyStart.set( event.clientX, event.clientY );
428
429     }
430
431     function handleMouseDownPan( event ) {
432
433         //console.log( 'handleMouseDownPan' );
434
435         panStart.set( event.clientX, event.clientY );
436
437     }
438
439     function handleMouseMoveRotate( event ) {
440
441         //console.log( 'handleMouseMoveRotate' );
442
443         rotateEnd.set( event.clientX, event.clientY );
444         rotateDelta.subVectors( rotateEnd, rotateStart );
445
446         var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
447
448         // rotating across whole screen goes 360 degrees around
449         rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
450
451         // rotating up and down along whole screen attempts to go 360, but limited to 180
452         rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
453
454         rotateStart.copy( rotateEnd );
455
456         scope.update();
457
458     }
459
460     function handleMouseMoveDolly( event ) {
461
462         //console.log( 'handleMouseMoveDolly' );
463
464         dollyEnd.set( event.clientX, event.clientY );
465
466         dollyDelta.subVectors( dollyEnd, dollyStart );
467
468         if ( dollyDelta.y > 0 ) {
469
470             dollyIn( getZoomScale() );
471
472         } else if ( dollyDelta.y < 0 ) {
473
474             dollyOut( getZoomScale() );
475
476         }
477
478         dollyStart.copy( dollyEnd );
479
480         scope.update();
481
482     }
483
484     function handleMouseMovePan( event ) {
485
486         //console.log( 'handleMouseMovePan' );
487
488         panEnd.set( event.clientX, event.clientY );
489
490         panDelta.subVectors( panEnd, panStart );
491
492         pan( panDelta.x, panDelta.y );
493
494         panStart.copy( panEnd );
495
496         scope.update();
497
498     }
499
500     function handleMouseUp( event ) {
501
502         // console.log( 'handleMouseUp' );
503
504     }
505
506     function handleMouseWheel( event ) {
507
508         // console.log( 'handleMouseWheel' );
509
510         if ( event.deltaY < 0 ) {
511
512             dollyOut( getZoomScale() );
513
514         } else if ( event.deltaY > 0 ) {
515
516             dollyIn( getZoomScale() );
517
518         }
519
520         scope.update();
521
522     }
523
524     function handleKeyDown( event ) {
525
526         //console.log( 'handleKeyDown' );
527
528         switch ( event.keyCode ) {
529
530             case scope.keys.UP:
531                 pan( 0, scope.keyPanSpeed );
532                 scope.update();
533                 break;
534
535             case scope.keys.BOTTOM:
536                 pan( 0, - scope.keyPanSpeed );
537                 scope.update();
538                 break;
539
540             case scope.keys.LEFT:
541                 pan( scope.keyPanSpeed, 0 );
542                 scope.update();
543                 break;
544
545             case scope.keys.RIGHT:
546                 pan( - scope.keyPanSpeed, 0 );
547                 scope.update();
548                 break;
549
550         }
551
552     }
553
554     function handleTouchStartRotate( event ) {
555
556         //console.log( 'handleTouchStartRotate' );
557
558         rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
559
560     }
561
562     function handleTouchStartDolly( event ) {
563
564         //console.log( 'handleTouchStartDolly' );
565
566         var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
567         var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
568
569         var distance = Math.sqrt( dx * dx + dy * dy );
570
571         dollyStart.set( 0, distance );
572
573     }
574
575     function handleTouchStartPan( event ) {
576
577         //console.log( 'handleTouchStartPan' );
578
579         panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
580
581     }
582
583     function handleTouchMoveRotate( event ) {
584
585         //console.log( 'handleTouchMoveRotate' );
586
587         rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
588         rotateDelta.subVectors( rotateEnd, rotateStart );
589
590         var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
591
592         // rotating across whole screen goes 360 degrees around
593         rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
594
595         // rotating up and down along whole screen attempts to go 360, but limited to 180
596         rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
597
598         rotateStart.copy( rotateEnd );
599
600         scope.update();
601
602     }
603
604     function handleTouchMoveDolly( event ) {
605
606         //console.log( 'handleTouchMoveDolly' );
607
608         var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
609         var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
610
611         var distance = Math.sqrt( dx * dx + dy * dy );
612
613         dollyEnd.set( 0, distance );
614
615         dollyDelta.subVectors( dollyEnd, dollyStart );
616
617         if ( dollyDelta.y > 0 ) {
618
619             dollyOut( getZoomScale() );
620
621         } else if ( dollyDelta.y < 0 ) {
622
623             dollyIn( getZoomScale() );
624
625         }
626
627         dollyStart.copy( dollyEnd );
628
629         scope.update();
630
631     }
632
633     function handleTouchMovePan( event ) {
634
635         //console.log( 'handleTouchMovePan' );
636
637         panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
638
639         panDelta.subVectors( panEnd, panStart );
640
641         pan( panDelta.x, panDelta.y );
642
643         panStart.copy( panEnd );
644
645         scope.update();
646
647     }
648
649     function handleTouchEnd( event ) {
650
651         //console.log( 'handleTouchEnd' );
652
653     }
654
655     //
656     // event handlers - FSM: listen for events and reset state
657     //
658
659     function onMouseDown( event ) {
660
661         if ( scope.enabled === false ) return;
662
663         event.preventDefault();
664
665         switch ( event.button ) {
666
667             case scope.mouseButtons.ORBIT:
668
669                 if ( scope.enableRotate === false ) return;
670
671                 handleMouseDownRotate( event );
672
673                 state = STATE.ROTATE;
674
675                 break;
676
677             case scope.mouseButtons.ZOOM:
678
679                 if ( scope.enableZoom === false ) return;
680
681                 handleMouseDownDolly( event );
682
683                 state = STATE.DOLLY;
684
685                 break;
686
687             case scope.mouseButtons.PAN:
688
689                 if ( scope.enablePan === false ) return;
690
691                 handleMouseDownPan( event );
692
693                 state = STATE.PAN;
694
695                 break;
696
697         }
698
699         if ( state !== STATE.NONE ) {
700
701             document.addEventListener( 'mousemove', onMouseMove, false );
702             document.addEventListener( 'mouseup', onMouseUp, false );
703
704             scope.dispatchEvent( startEvent );
705
706         }
707
708     }
709
710     function onMouseMove( event ) {
711
712         if ( scope.enabled === false ) return;
713
714         event.preventDefault();
715
716         switch ( state ) {
717
718             case STATE.ROTATE:
719
720                 if ( scope.enableRotate === false ) return;
721
722                 handleMouseMoveRotate( event );
723
724                 break;
725
726             case STATE.DOLLY:
727
728                 if ( scope.enableZoom === false ) return;
729
730                 handleMouseMoveDolly( event );
731
732                 break;
733
734             case STATE.PAN:
735
736                 if ( scope.enablePan === false ) return;
737
738                 handleMouseMovePan( event );
739
740                 break;
741
742         }
743
744     }
745
746     function onMouseUp( event ) {
747
748         if ( scope.enabled === false ) return;
749
750         handleMouseUp( event );
751
752         document.removeEventListener( 'mousemove', onMouseMove, false );
753         document.removeEventListener( 'mouseup', onMouseUp, false );
754
755         scope.dispatchEvent( endEvent );
756
757         state = STATE.NONE;
758
759     }
760
761     function onMouseWheel( event ) {
762
763         if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;
764
765         event.preventDefault();
766         event.stopPropagation();
767
768         handleMouseWheel( event );
769
770         scope.dispatchEvent( startEvent ); // not sure why these are here...
771         scope.dispatchEvent( endEvent );
772
773     }
774
775     function onKeyDown( event ) {
776
777         if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;
778
779         handleKeyDown( event );
780
781     }
782
783     function onTouchStart( event ) {
784
785         if ( scope.enabled === false ) return;
786
787         switch ( event.touches.length ) {
788
789             case 1: // one-fingered touch: rotate
790
791                 if ( scope.enableRotate === false ) return;
792
793                 handleTouchStartRotate( event );
794
795                 state = STATE.TOUCH_ROTATE;
796
797                 break;
798
799             case 2: // two-fingered touch: dolly
800
801                 if ( scope.enableZoom === false ) return;
802
803                 handleTouchStartDolly( event );
804
805                 state = STATE.TOUCH_DOLLY;
806
807                 break;
808
809             case 3: // three-fingered touch: pan
810
811                 if ( scope.enablePan === false ) return;
812
813                 handleTouchStartPan( event );
814
815                 state = STATE.TOUCH_PAN;
816
817                 break;
818
819             default:
820
821                 state = STATE.NONE;
822
823         }
824
825         if ( state !== STATE.NONE ) {
826
827             scope.dispatchEvent( startEvent );
828
829         }
830
831     }
832
833     function onTouchMove( event ) {
834
835         if ( scope.enabled === false ) return;
836
837         event.preventDefault();
838         event.stopPropagation();
839
840         switch ( event.touches.length ) {
841
842             case 1: // one-fingered touch: rotate
843
844                 if ( scope.enableRotate === false ) return;
845                 if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...
846
847                 handleTouchMoveRotate( event );
848
849                 break;
850
851             case 2: // two-fingered touch: dolly
852
853                 if ( scope.enableZoom === false ) return;
854                 if ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...
855
856                 handleTouchMoveDolly( event );
857
858                 break;
859
860             case 3: // three-fingered touch: pan
861
862                 if ( scope.enablePan === false ) return;
863                 if ( state !== STATE.TOUCH_PAN ) return; // is this needed?...
864
865                 handleTouchMovePan( event );
866
867                 break;
868
869             default:
870
871                 state = STATE.NONE;
872
873         }
874
875     }
876
877     function onTouchEnd( event ) {
878
879         if ( scope.enabled === false ) return;
880
881         handleTouchEnd( event );
882
883         scope.dispatchEvent( endEvent );
884
885         state = STATE.NONE;
886
887     }
888
889     function onContextMenu( event ) {
890
891         if ( scope.enabled === false ) return;
892
893         event.preventDefault();
894
895     }
896
897     //
898
899     scope.domElement.addEventListener( 'contextmenu', onContextMenu, false );
900
901     scope.domElement.addEventListener( 'mousedown', onMouseDown, false );
902     scope.domElement.addEventListener( 'wheel', onMouseWheel, false );
903
904     scope.domElement.addEventListener( 'touchstart', onTouchStart, false );
905     scope.domElement.addEventListener( 'touchend', onTouchEnd, false );
906     scope.domElement.addEventListener( 'touchmove', onTouchMove, false );
907
908     window.addEventListener( 'keydown', onKeyDown, false );
909
910     // force an update at start
911
912     this.update();
913
914 };
915
916 THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
917 THREE.OrbitControls.prototype.constructor = THREE.OrbitControls;
918
919 Object.defineProperties( THREE.OrbitControls.prototype, {
920
921     center: {
922
923         get: function () {
924
925             console.warn( 'THREE.OrbitControls: .center has been renamed to .target' );
926             return this.target;
927
928         }
929
930     },
931
932     // backward compatibility
933
934     noZoom: {
935
936         get: function () {
937
938             console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
939             return ! this.enableZoom;
940
941         },
942
943         set: function ( value ) {
944
945             console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
946             this.enableZoom = ! value;
947
948         }
949
950     },
951
952     noRotate: {
953
954         get: function () {
955
956             console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
957             return ! this.enableRotate;
958
959         },
960
961         set: function ( value ) {
962
963             console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
964             this.enableRotate = ! value;
965
966         }
967
968     },
969
970     noPan: {
971
972         get: function () {
973
974             console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
975             return ! this.enablePan;
976
977         },
978
979         set: function ( value ) {
980
981             console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
982             this.enablePan = ! value;
983
984         }
985
986     },
987
988     noKeys: {
989
990         get: function () {
991
992             console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
993             return ! this.enableKeys;
994
995         },
996
997         set: function ( value ) {
998
999             console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
1000             this.enableKeys = ! value;
1001
1002         }
1003
1004     },
1005
1006     staticMoving: {
1007
1008         get: function () {
1009
1010             console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
1011             return ! this.enableDamping;
1012
1013         },
1014
1015         set: function ( value ) {
1016
1017             console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
1018             this.enableDamping = ! value;
1019
1020         }
1021
1022     },
1023
1024     dynamicDampingFactor: {
1025
1026         get: function () {
1027
1028             console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
1029             return this.dampingFactor;
1030
1031         },
1032
1033         set: function ( value ) {
1034
1035             console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
1036             this.dampingFactor = value;
1037
1038         }
1039
1040     }
1041
1042 } );