OrbitControls.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * @author qiao / https://github.com/qiao
  3. */
  4. THREE.OrbitControls = function( object, domElement ) {
  5. this.object = object;
  6. this.domElement = ( domElement !== undefined ? domElement : document );
  7. // API
  8. this.center = new THREE.Vector3( 0, 0, 0 );
  9. this.userZoom = true;
  10. this.userZoomSpeed = 1.0;
  11. this.userRotate = true;
  12. this.userRotateSpeed = 2.0;
  13. this.autoRotate = false;
  14. this.autoRotateSpeed = 3.0; // 20 seconds per round when fps is 60
  15. // internals
  16. var EPS = 0.000001;
  17. var PIXELS_PER_ROUND = 1800;
  18. var rotateStart = new THREE.Vector2();
  19. var rotateEnd = new THREE.Vector2();
  20. var rotateDelta = new THREE.Vector2();
  21. var rotating = false;
  22. var phiDelta = 0;
  23. var thetaDelta = 0;
  24. var scale = 1;
  25. this.update = function () {
  26. var position = this.object.position;
  27. // angle from z-axis around y-axis
  28. var theta = Math.atan2( position.x, position.z );
  29. // angle from y-axis
  30. var phi = Math.atan2(
  31. Math.sqrt( position.x * position.x + position.z * position.z ),
  32. position.y
  33. );
  34. if ( this.autoRotate ) {
  35. theta += 2 * Math.PI / 60 / 60 * this.autoRotateSpeed;
  36. }
  37. if ( this.userRotate ) {
  38. theta += thetaDelta;
  39. phi += phiDelta;
  40. // restrict phi to be betwee EPS and PI-EPS
  41. phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
  42. thetaDelta = 0;
  43. phiDelta = 0;
  44. }
  45. var radius = position.clone().subSelf( this.center ).length();
  46. var offset = new THREE.Vector3();
  47. offset.x = radius * Math.sin( phi ) * Math.sin( theta );
  48. offset.y = radius * Math.cos( phi );
  49. offset.z = radius * Math.sin( phi ) * Math.cos( theta );
  50. if ( this.userZoom ) {
  51. offset.multiplyScalar( scale );
  52. scale = 1;
  53. }
  54. position.copy( this.center ).addSelf( offset );
  55. this.object.lookAt( this.center );
  56. };
  57. var self = this;
  58. function onMouseMove( event ) {
  59. if ( !rotating ) return;
  60. rotateEnd.set( event.clientX, event.clientY );
  61. rotateDelta.sub( rotateEnd, rotateStart );
  62. thetaDelta = -2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * self.userRotateSpeed;
  63. phiDelta = -2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * self.userRotateSpeed;
  64. rotateStart.copy( rotateEnd );
  65. }
  66. function onMouseDown( event ) {
  67. if ( !self.userRotate ) return;
  68. rotateStart.set( event.clientX, event.clientY );
  69. rotating = true;
  70. }
  71. function onMouseUp( event ) {
  72. if ( !self.userRotate ) return;
  73. rotating = false;
  74. }
  75. function onMouseWheel( event ) {
  76. if ( !self.userZoom ) return;
  77. if ( event.wheelDelta > 0 ) {
  78. scale = Math.pow( 0.95, self.userZoomSpeed );
  79. } else {
  80. scale = 1.0 / Math.pow( 0.95, self.userZoomSpeed );
  81. }
  82. }
  83. function onKeyDown( event ) {
  84. }
  85. function onKeyUp( event ) {
  86. }
  87. this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
  88. this.domElement.addEventListener( 'mousemove', onMouseMove, false );
  89. this.domElement.addEventListener( 'mousedown', onMouseDown, false );
  90. this.domElement.addEventListener( 'mouseup', onMouseUp, false );
  91. this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
  92. this.domElement.addEventListener( 'keydown', onKeyDown, false );
  93. this.domElement.addEventListener( 'keyup', onKeyUp, false );
  94. };
粤ICP备19079148号