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