MapControls.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import { MOUSE, TOUCH, Plane, Raycaster, Vector2, Vector3 } from 'three';
  2. import { OrbitControls } from './OrbitControls.js';
  3. const _plane = new Plane();
  4. const _raycaster = new Raycaster();
  5. const _mouse = new Vector2();
  6. const _panCurrent = new Vector3();
  7. /**
  8. * This class is intended for transforming a camera over a map from bird's eye perspective.
  9. * The class shares its implementation with {@link OrbitControls} but uses a specific preset
  10. * for mouse/touch interaction and disables screen space panning by default.
  11. *
  12. * - Orbit: Right mouse, or left mouse + ctrl/meta/shiftKey / touch: two-finger rotate.
  13. * - Zoom: Middle mouse, or mousewheel / touch: two-finger spread or squish.
  14. * - Pan: Left mouse, or arrow keys / touch: one-finger move.
  15. *
  16. * @augments OrbitControls
  17. * @three_import import { MapControls } from 'three/addons/controls/MapControls.js';
  18. */
  19. class MapControls extends OrbitControls {
  20. constructor( object, domElement ) {
  21. super( object, domElement );
  22. /**
  23. * Overwritten and set to `false` to pan orthogonal to world-space direction `camera.up`.
  24. *
  25. * @type {boolean}
  26. * @default false
  27. */
  28. this.screenSpacePanning = false;
  29. /**
  30. * This object contains references to the mouse actions used by the controls.
  31. *
  32. * ```js
  33. * controls.mouseButtons = {
  34. * LEFT: THREE.MOUSE.PAN,
  35. * MIDDLE: THREE.MOUSE.DOLLY,
  36. * RIGHT: THREE.MOUSE.ROTATE
  37. * }
  38. * ```
  39. * @type {Object}
  40. */
  41. this.mouseButtons = { LEFT: MOUSE.PAN, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.ROTATE };
  42. /**
  43. * This object contains references to the touch actions used by the controls.
  44. *
  45. * ```js
  46. * controls.mouseButtons = {
  47. * ONE: THREE.TOUCH.PAN,
  48. * TWO: THREE.TOUCH.DOLLY_ROTATE
  49. * }
  50. * ```
  51. * @type {Object}
  52. */
  53. this.touches = { ONE: TOUCH.PAN, TWO: TOUCH.DOLLY_ROTATE };
  54. this._panWorldStart = new Vector3();
  55. }
  56. _handleMouseDownPan( event ) {
  57. super._handleMouseDownPan( event );
  58. this._panOffset.set( 0, 0, 0 );
  59. if ( this.screenSpacePanning === true ) return;
  60. _plane.setFromNormalAndCoplanarPoint( this.object.up, this.target );
  61. const element = this.domElement;
  62. const rect = element.getBoundingClientRect();
  63. _mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
  64. _mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
  65. _raycaster.setFromCamera( _mouse, this.object );
  66. _raycaster.ray.intersectPlane( _plane, this._panWorldStart );
  67. }
  68. _handleMouseMovePan( event ) {
  69. if ( this.screenSpacePanning === true ) {
  70. super._handleMouseMovePan( event );
  71. return;
  72. }
  73. const element = this.domElement;
  74. const rect = element.getBoundingClientRect();
  75. _mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
  76. _mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
  77. _raycaster.setFromCamera( _mouse, this.object );
  78. if ( _raycaster.ray.intersectPlane( _plane, _panCurrent ) ) {
  79. _panCurrent.sub( this._panWorldStart );
  80. this._panOffset.copy( _panCurrent ).negate();
  81. this.update();
  82. }
  83. }
  84. }
  85. export { MapControls };
粤ICP备19079148号