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 16THREE.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 phi; 90 91 }; 92 93 this.getAzimuthalAngle = function () { 94 95 return 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 () { 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( 'mousewheel', onMouseWheel, false ); 224 scope.domElement.removeEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox 225 226 scope.domElement.removeEventListener( 'touchstart', onTouchStart, false ); 227 scope.domElement.removeEventListener( 'touchend', onTouchEnd, false ); 228 scope.domElement.removeEventListener( 'touchmove', onTouchMove, false ); 229 230 document.removeEventListener( 'mousemove', onMouseMove, false ); 231 document.removeEventListener( 'mouseup', onMouseUp, false ); 232 document.removeEventListener( 'mouseout', onMouseUp, false ); 233 234 window.removeEventListener( 'keydown', onKeyDown, false ); 235 236 //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? 237 238 }; 239 240 // 241 // internals 242 // 243 244 var scope = this; 245 246 var changeEvent = { type: 'change' }; 247 var startEvent = { type: 'start' }; 248 var endEvent = { type: 'end' }; 249 250 var STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 }; 251 252 var state = STATE.NONE; 253 254 var EPS = 0.000001; 255 256 // current position in spherical coordinates 257 var spherical = new THREE.Spherical(); 258 var sphericalDelta = new THREE.Spherical(); 259 260 var scale = 1; 261 var panOffset = new THREE.Vector3(); 262 var zoomChanged = false; 263 264 var rotateStart = new THREE.Vector2(); 265 var rotateEnd = new THREE.Vector2(); 266 var rotateDelta = new THREE.Vector2(); 267 268 var panStart = new THREE.Vector2(); 269 var panEnd = new THREE.Vector2(); 270 var panDelta = new THREE.Vector2(); 271 272 var dollyStart = new THREE.Vector2(); 273 var dollyEnd = new THREE.Vector2(); 274 var dollyDelta = new THREE.Vector2(); 275 276 function getAutoRotationAngle() { 277 278 return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed; 279 280 } 281 282 function getZoomScale() { 283 284 return Math.pow( 0.95, scope.zoomSpeed ); 285 286 } 287 288 function rotateLeft( angle ) { 289 290 sphericalDelta.theta -= angle; 291 292 } 293 294 function rotateUp( angle ) { 295 296 sphericalDelta.phi -= angle; 297 298 } 299 300 var panLeft = function() { 301 302 var v = new THREE.Vector3(); 303 304 return function panLeft( distance, objectMatrix ) { 305 306 v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix 307 v.multiplyScalar( - distance ); 308 309 panOffset.add( v ); 310 311 }; 312 313 }(); 314 315 var panUp = function() { 316 317 var v = new THREE.Vector3(); 318 319 return function panUp( distance, objectMatrix ) { 320 321 v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix 322 v.multiplyScalar( distance ); 323 324 panOffset.add( v ); 325 326 }; 327 328 }(); 329 330 // deltaX and deltaY are in pixels; right and down are positive 331 var pan = function() { 332 333 var offset = new THREE.Vector3(); 334 335 return function( deltaX, deltaY ) { 336 337 var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 338 339 if ( scope.object instanceof THREE.PerspectiveCamera ) { 340 341 // perspective 342 var position = scope.object.position; 343 offset.copy( position ).sub( scope.target ); 344 var targetDistance = offset.length(); 345 346 // half of the fov is center to top of screen 347 targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); 348 349 // we actually don't use screenWidth, since perspective camera is fixed to screen height 350 panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix ); 351 panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix ); 352 353 }
353 else if ( scope.object instanceof THREE.OrthographicCamera ) { 354 355 // orthographic 356 panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); 357 panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); 358 359 } else { 360 361 // camera neither orthographic nor perspective 362 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); 363 scope.enablePan = false; 364 365 } 366 367 }; 368 369 }(); 370 371 function dollyIn( dollyScale ) { 372 373 if ( scope.object instanceof THREE.PerspectiveCamera ) { 374 375 scale /= dollyScale; 376 377 } else if ( scope.object instanceof THREE.OrthographicCamera ) { 378 379 scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); 380 scope.object.updateProjectionMatrix(); 381 zoomChanged = true; 382 383 } else { 384 385 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); 386 scope.enableZoom = false; 387 388 } 389 390 } 391 392 function dollyOut( dollyScale ) { 393 394 if ( scope.object instanceof THREE.PerspectiveCamera ) { 395 396 scale *= dollyScale; 397 398 } else if ( scope.object instanceof THREE.OrthographicCamera ) { 399 400 scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); 401 scope.object.updateProjectionMatrix(); 402 zoomChanged = true; 403 404 } else { 405 406 console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); 407 scope.enableZoom = false; 408 409 } 410 411 } 412 413 // 414 // event callbacks - update the object state 415 // 416 417 function handleMouseDownRotate( event ) { 418 419 //console.log( 'handleMouseDownRotate' ); 420 421 rotateStart.set( event.clientX, event.clientY ); 422 423 } 424 425 function handleMouseDownDolly( event ) { 426 427 //console.log( 'handleMouseDownDolly' ); 428 429 dollyStart.set( event.clientX, event.clientY ); 430 431 } 432 433 function handleMouseDownPan( event ) { 434 435 //console.log( 'handleMouseDownPan' ); 436 437 panStart.set( event.clientX, event.clientY ); 438 439 } 440 441 function handleMouseMoveRotate( event ) { 442 443 //console.log( 'handleMouseMoveRotate' ); 444 445 rotateEnd.set( event.clientX, event.clientY ); 446 rotateDelta.subVectors( rotateEnd, rotateStart ); 447 448 var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 449 450 // rotating across whole screen goes 360 degrees around 451 rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); 452 453 // rotating up and down along whole screen attempts to go 360, but limited to 180 454 rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); 455 456 rotateStart.copy( rotateEnd ); 457 458 scope.update(); 459 460 } 461 462 function handleMouseMoveDolly( event ) { 463 464 //console.log( 'handleMouseMoveDolly' ); 465 466 dollyEnd.set( event.clientX, event.clientY ); 467 468 dollyDelta.subVectors( dollyEnd, dollyStart ); 469 470 if ( dollyDelta.y > 0 ) { 471 472 dollyIn( getZoomScale() ); 473 474 } else if ( dollyDelta.y < 0 ) { 475 476 dollyOut( getZoomScale() ); 477 478 } 479 480 dollyStart.copy( dollyEnd ); 481 482 scope.update(); 483 484 } 485 486 function handleMouseMovePan( event ) { 487 488 //console.log( 'handleMouseMovePan' ); 489 490 panEnd.set( event.clientX, event.clientY ); 491 492 panDelta.subVectors( panEnd, panStart ); 493 494 pan( panDelta.x, panDelta.y ); 495 496 panStart.copy( panEnd ); 497 498 scope.update(); 499 500 } 501 502 function handleMouseUp( event ) { 503 504 //console.log( 'handleMouseUp' ); 505 506 } 507 508 function handleMouseWheel( event ) { 509 510 //console.log( 'handleMouseWheel' ); 511 512 var delta = 0; 513 514 if ( event.wheelDelta !== undefined ) { 515 516 // WebKit / Opera / Explorer 9 517 518 delta = event.wheelDelta; 519 520 } else if ( event.detail !== undefined ) { 521 522 // Firefox 523 524 delta = - event.detail; 525 526 } 527 528 if ( delta > 0 ) { 529 530 dollyOut( getZoomScale() ); 531 532 } else if ( delta < 0 ) { 533 534 dollyIn( getZoomScale() ); 535 536 } 537 538 scope.update(); 539 540 } 541 542 function handleKeyDown( event ) { 543 544 //console.log( 'handleKeyDown' ); 545 546 switch ( event.keyCode ) { 547 548 case scope.keys.UP: 549 pan( 0, scope.keyPanSpeed );
550 scope.update(); 551 break; 552 553 case scope.keys.BOTTOM: 554 pan( 0, - scope.keyPanSpeed ); 555 scope.update(); 556 break; 557 558 case scope.keys.LEFT: 559 pan( scope.keyPanSpeed, 0 ); 560 scope.update(); 561 break; 562 563 case scope.keys.RIGHT: 564 pan( - scope.keyPanSpeed, 0 ); 565 scope.update(); 566 break; 567 568 } 569 570 } 571 572 function handleTouchStartRotate( event ) { 573 574 //console.log( 'handleTouchStartRotate' ); 575 576 rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 577 578 } 579 580 function handleTouchStartDolly( event ) { 581 582 //console.log( 'handleTouchStartDolly' ); 583 584 var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 585 var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 586 587 var distance = Math.sqrt( dx * dx + dy * dy ); 588 589 dollyStart.set( 0, distance ); 590 591 } 592 593 function handleTouchStartPan( event ) { 594 595 //console.log( 'handleTouchStartPan' ); 596 597 panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 598 599 } 600 601 function handleTouchMoveRotate( event ) { 602 603 //console.log( 'handleTouchMoveRotate' ); 604 605 rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 606 rotateDelta.subVectors( rotateEnd, rotateStart ); 607 608 var element = scope.domElement === document ? scope.domElement.body : scope.domElement; 609 610 // rotating across whole screen goes 360 degrees around 611 rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); 612 613 // rotating up and down along whole screen attempts to go 360, but limited to 180 614 rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); 615 616 rotateStart.copy( rotateEnd ); 617 618 scope.update(); 619 620 } 621 622 function handleTouchMoveDolly( event ) { 623 624 //console.log( 'handleTouchMoveDolly' ); 625 626 var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; 627 var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; 628 629 var distance = Math.sqrt( dx * dx + dy * dy ); 630 631 dollyEnd.set( 0, distance ); 632 633 dollyDelta.subVectors( dollyEnd, dollyStart ); 634 635 if ( dollyDelta.y > 0 ) { 636 637 dollyOut( getZoomScale() ); 638 639 } else if ( dollyDelta.y < 0 ) { 640 641 dollyIn( getZoomScale() ); 642 643 } 644 645 dollyStart.copy( dollyEnd ); 646 647 scope.update(); 648 649 } 650 651 function handleTouchMovePan( event ) { 652 653 //console.log( 'handleTouchMovePan' ); 654 655 panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); 656 657 panDelta.subVectors( panEnd, panStart ); 658 659 pan( panDelta.x, panDelta.y ); 660 661 panStart.copy( panEnd ); 662 663 scope.update(); 664 665 } 666 667 function handleTouchEnd( event ) { 668 669 //console.log( 'handleTouchEnd' ); 670 671 } 672 673 // 674 // event handlers - FSM: listen for events and reset state 675 // 676 677 function onMouseDown( event ) { 678 679 if ( scope.enabled === false ) return; 680 681 event.preventDefault(); 682 683 if ( event.button === scope.mouseButtons.ORBIT ) { 684 685 if ( scope.enableRotate === false ) return; 686 687 handleMouseDownRotate( event ); 688 689 state = STATE.ROTATE; 690 691 } else if ( event.button === scope.mouseButtons.ZOOM ) { 692 693 if ( scope.enableZoom === false ) return; 694 695 handleMouseDownDolly( event ); 696 697 state = STATE.DOLLY; 698 699 } else if ( event.button === scope.mouseButtons.PAN ) { 700 701 if ( scope.enablePan === false ) return; 702 703 handleMouseDownPan( event ); 704 705 state = STATE.PAN; 706 707 } 708 709 if ( state !== STATE.NONE ) { 710 711 document.addEventListener( 'mousemove', onMouseMove, false ); 712 document.addEventListener( 'mouseup', onMouseUp, false ); 713 document.addEventListener( 'mouseout', onMouseUp, false ); 714 715 scope.dispatchEvent( startEvent ); 716 717 } 718 719 } 720 721 function onMouseMove( event ) { 722 723 if ( scope.enabled === false ) return; 724 725 event.preventDefault(); 726 727 if ( state === STATE.ROTATE ) { 728 729 if ( scope.enableRotate === false ) return; 730 731 handleMouseMoveRotate( event ); 732 733 } else if ( state === STATE.DOLLY ) { 734 735 if ( scope.enableZoom === false ) return; 736 737 handleMouseMoveDolly( event ); 738 739 } else if ( state === STATE.PAN ) { 740 741 if ( scope.enablePan === false ) return; 742 743 handleMouseMovePan( event ); 744 745 } 746 747 } 748 749 function onMouseUp( event ) { 750 751 if ( scope.enabled === false ) return; 752 753 handleMouseUp( event ); 754 755 document.removeEventListener( 'mousemove', onMouseMove, false ); 756 document.removeEventListener( 'mouseup', onMouseUp, false ); 757 document.removeEventListener( 'mouseout', onMouseUp, false ); 758 759 scope.dispatchEvent( endEvent ); 760 761 state = STATE.NONE; 762 763 } 764 765 function onMouseWheel( event ) { 766 767 if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return; 768 769 event.preventDefault(); 770 event.stopPropagation(); 771 772 handleMouseWheel( event ); 773 774 scope.dispatchEvent( startEvent ); // not sure why these are here... 775 scope.dispatchEvent( endEvent ); 776 777 } 778 779 function onKeyDown( event ) { 780 781 if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return; 782 783 handleKeyDown( event ); 784 785 } 786 787 function onTouchStart( event ) { 788 789 if ( scope.enabled === false ) return; 790 791 switch ( event.touches.length ) { 792 793 case 1: // one-fingered touch: rotate 794 795 if ( scope.enableRotate === false ) return; 796 797 handleTouchStartRotate( event ); 798 799 state = STATE.TOUCH_ROTATE;
vendor: 4,937 bytes, lines 800-1045
800 801 break; 802 803 case 2: // two-fingered touch: dolly 804 805 if ( scope.enableZoom === false ) return; 806 807 handleTouchStartDolly( event ); 808 809 state = STATE.TOUCH_DOLLY; 810 811 break; 812 813 case 3: // three-fingered touch: pan 814 815 if ( scope.enablePan === false ) return; 816 817 handleTouchStartPan( event ); 818 819 state = STATE.TOUCH_PAN; 820 821 break; 822 823 default: 824 825 state = STATE.NONE; 826 827 } 828 829 if ( state !== STATE.NONE ) { 830 831 scope.dispatchEvent( startEvent ); 832 833 } 834 835 } 836 837 function onTouchMove( event ) { 838 839 if ( scope.enabled === false ) return; 840 841 event.preventDefault(); 842 event.stopPropagation(); 843 844 switch ( event.touches.length ) { 845 846 case 1: // one-fingered touch: rotate 847 848 if ( scope.enableRotate === false ) return; 849 if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?... 850 851 handleTouchMoveRotate( event ); 852 853 break; 854 855 case 2: // two-fingered touch: dolly 856 857 if ( scope.enableZoom === false ) return; 858 if ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?... 859 860 handleTouchMoveDolly( event ); 861 862 break; 863 864 case 3: // three-fingered touch: pan 865 866 if ( scope.enablePan === false ) return; 867 if ( state !== STATE.TOUCH_PAN ) return; // is this needed?... 868 869 handleTouchMovePan( event ); 870 871 break; 872 873 default: 874 875 state = STATE.NONE; 876 877 } 878 879 } 880 881 function onTouchEnd( event ) { 882 883 if ( scope.enabled === false ) return; 884 885 handleTouchEnd( event ); 886 887 scope.dispatchEvent( endEvent ); 888 889 state = STATE.NONE; 890 891 } 892 893 function onContextMenu( event ) { 894 895 event.preventDefault(); 896 897 } 898 899 // 900 901 scope.domElement.addEventListener( 'contextmenu', onContextMenu, false ); 902 903 scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); 904 scope.domElement.addEventListener( 'mousewheel', onMouseWheel, false ); 905 scope.domElement.addEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox 906 907 scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); 908 scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); 909 scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); 910 911 window.addEventListener( 'keydown', onKeyDown, false ); 912 913 // force an update at start 914 915 this.update(); 916 917}; 918 919THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); 920THREE.OrbitControls.prototype.constructor = THREE.OrbitControls; 921 922Object.defineProperties( THREE.OrbitControls.prototype, { 923 924 center: { 925 926 get: function () { 927 928 console.warn( 'THREE.OrbitControls: .center has been renamed to .target' ); 929 return this.target; 930 931 } 932 933 }, 934 935 // backward compatibility 936 937 noZoom: { 938 939 get: function () { 940 941 console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); 942 return ! this.enableZoom; 943 944 }, 945 946 set: function ( value ) { 947 948 console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); 949 this.enableZoom = ! value; 950 951 } 952 953 }, 954 955 noRotate: { 956 957 get: function () { 958 959 console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); 960 return ! this.enableRotate; 961 962 }, 963 964 set: function ( value ) { 965 966 console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); 967 this.enableRotate = ! value; 968 969 } 970 971 }, 972 973 noPan: { 974 975 get: function () { 976 977 console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); 978 return ! this.enablePan; 979 980 }, 981 982 set: function ( value ) { 983 984 console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); 985 this.enablePan = ! value; 986 987 } 988 989 }, 990 991 noKeys: { 992 993 get: function () { 994 995 console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); 996 return ! this.enableKeys; 997 998 }, 999 1000 set: function ( value ) { 1001 1002 console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); 1003 this.enableKeys = ! value; 1004 1005 } 1006 1007 }, 1008 1009 staticMoving : { 1010 1011 get: function () { 1012 1013 console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); 1014 return ! this.constraint.enableDamping; 1015 1016 }, 1017 1018 set: function ( value ) { 1019 1020 console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); 1021 this.constraint.enableDamping = ! value; 1022 1023 } 1024 1025 }, 1026 1027 dynamicDampingFactor : { 1028 1029 get: function () { 1030 1031 console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); 1032 return this.constraint.dampingFactor; 1033 1034 }, 1035 1036 set: function ( value ) { 1037 1038 console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); 1039 this.constraint.dampingFactor = value; 1040 1041 } 1042 1043 } 1044 1045} );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.