Skip to content

Commit aee0fd4

Browse files
authored
MapControls: Improve panning accuracy (#32324)
1 parent 56ad6e0 commit aee0fd4

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

examples/jsm/controls/MapControls.js

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
import { MOUSE, TOUCH } from 'three';
1+
import { MOUSE, TOUCH, Plane, Raycaster, Vector2, Vector3 } from 'three';
22

33
import { OrbitControls } from './OrbitControls.js';
44

5+
const _plane = new Plane();
6+
const _raycaster = new Raycaster();
7+
const _mouse = new Vector2();
8+
const _panCurrent = new Vector3();
9+
510
/**
611
* This class is intended for transforming a camera over a map from bird's eye perspective.
712
* The class shares its implementation with {@link OrbitControls} but uses a specific preset
@@ -55,6 +60,55 @@ class MapControls extends OrbitControls {
5560
*/
5661
this.touches = { ONE: TOUCH.PAN, TWO: TOUCH.DOLLY_ROTATE };
5762

63+
this._panWorldStart = new Vector3();
64+
65+
}
66+
67+
_handleMouseDownPan( event ) {
68+
69+
super._handleMouseDownPan( event );
70+
71+
this._panOffset.set( 0, 0, 0 );
72+
73+
if ( this.screenSpacePanning === true ) return;
74+
75+
_plane.setFromNormalAndCoplanarPoint( this.object.up, this.target );
76+
77+
const element = this.domElement;
78+
const rect = element.getBoundingClientRect();
79+
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
80+
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
81+
82+
_raycaster.setFromCamera( _mouse, this.object );
83+
_raycaster.ray.intersectPlane( _plane, this._panWorldStart );
84+
85+
}
86+
87+
_handleMouseMovePan( event ) {
88+
89+
if ( this.screenSpacePanning === true ) {
90+
91+
super._handleMouseMovePan( event );
92+
return;
93+
94+
}
95+
96+
const element = this.domElement;
97+
const rect = element.getBoundingClientRect();
98+
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1;
99+
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
100+
101+
_raycaster.setFromCamera( _mouse, this.object );
102+
103+
if ( _raycaster.ray.intersectPlane( _plane, _panCurrent ) ) {
104+
105+
_panCurrent.sub( this._panWorldStart );
106+
this._panOffset.copy( _panCurrent ).negate();
107+
108+
this.update();
109+
110+
}
111+
58112
}
59113

60114
}

0 commit comments

Comments
 (0)