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