Skip to content

Commit 25da165

Browse files
authored
DragControls: Fully migrate to pointer events. (#21958)
1 parent 1816194 commit 25da165

File tree

2 files changed

+95
-327
lines changed

2 files changed

+95
-327
lines changed

examples/js/controls/DragControls.js

Lines changed: 49 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
const _raycaster = new THREE.Raycaster();
66

7-
const _mouse = new THREE.Vector2();
7+
const _pointer = new THREE.Vector2();
88

99
const _offset = new THREE.Vector3();
1010

@@ -35,16 +35,6 @@
3535

3636
_domElement.addEventListener( 'pointerleave', onPointerCancel );
3737

38-
_domElement.addEventListener( 'touchmove', onTouchMove, {
39-
passive: false
40-
} );
41-
42-
_domElement.addEventListener( 'touchstart', onTouchStart, {
43-
passive: false
44-
} );
45-
46-
_domElement.addEventListener( 'touchend', onTouchEnd );
47-
4838
}
4939

5040
function deactivate() {
@@ -57,12 +47,6 @@
5747

5848
_domElement.removeEventListener( 'pointerleave', onPointerCancel );
5949

60-
_domElement.removeEventListener( 'touchmove', onTouchMove );
61-
62-
_domElement.removeEventListener( 'touchstart', onTouchStart );
63-
64-
_domElement.removeEventListener( 'touchend', onTouchEnd );
65-
6650
_domElement.style.cursor = '';
6751

6852
}
@@ -81,26 +65,9 @@
8165

8266
function onPointerMove( event ) {
8367

84-
switch ( event.pointerType ) {
85-
86-
case 'mouse':
87-
case 'pen':
88-
onMouseMove( event );
89-
break;
90-
// TODO touch
91-
92-
}
93-
94-
}
95-
96-
function onMouseMove( event ) {
97-
98-
const rect = _domElement.getBoundingClientRect();
99-
100-
_mouse.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
101-
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
68+
updatePointer( event );
10269

103-
_raycaster.setFromCamera( _mouse, _camera );
70+
_raycaster.setFromCamera( _pointer, _camera );
10471

10572
if ( _selected && scope.enabled ) {
10673

@@ -116,85 +83,80 @@
11683
} );
11784
return;
11885

119-
}
86+
} // hover support
12087

121-
_intersections.length = 0;
12288

123-
_raycaster.setFromCamera( _mouse, _camera );
89+
if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
12490

125-
_raycaster.intersectObjects( _objects, true, _intersections );
91+
_intersections.length = 0;
12692

127-
if ( _intersections.length > 0 ) {
93+
_raycaster.setFromCamera( _pointer, _camera );
12894

129-
const object = _intersections[ 0 ].object;
95+
_raycaster.intersectObjects( _objects, true, _intersections );
13096

131-
_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
97+
if ( _intersections.length > 0 ) {
13298

133-
if ( _hovered !== object && _hovered !== null ) {
99+
const object = _intersections[ 0 ].object;
134100

135-
scope.dispatchEvent( {
136-
type: 'hoveroff',
137-
object: _hovered
138-
} );
139-
_domElement.style.cursor = 'auto';
140-
_hovered = null;
101+
_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
141102

142-
}
103+
if ( _hovered !== object && _hovered !== null ) {
143104

144-
if ( _hovered !== object ) {
105+
scope.dispatchEvent( {
106+
type: 'hoveroff',
107+
object: _hovered
108+
} );
109+
_domElement.style.cursor = 'auto';
110+
_hovered = null;
145111

146-
scope.dispatchEvent( {
147-
type: 'hoveron',
148-
object: object
149-
} );
150-
_domElement.style.cursor = 'pointer';
151-
_hovered = object;
112+
}
152113

153-
}
154-
155-
} else {
156-
157-
if ( _hovered !== null ) {
114+
if ( _hovered !== object ) {
158115

159-
scope.dispatchEvent( {
160-
type: 'hoveroff',
161-
object: _hovered
162-
} );
163-
_domElement.style.cursor = 'auto';
164-
_hovered = null;
116+
scope.dispatchEvent( {
117+
type: 'hoveron',
118+
object: object
119+
} );
120+
_domElement.style.cursor = 'pointer';
121+
_hovered = object;
165122

166-
}
123+
}
167124

168-
}
125+
} else {
169126

170-
}
127+
if ( _hovered !== null ) {
171128

172-
function onPointerDown( event ) {
129+
scope.dispatchEvent( {
130+
type: 'hoveroff',
131+
object: _hovered
132+
} );
133+
_domElement.style.cursor = 'auto';
134+
_hovered = null;
173135

174-
switch ( event.pointerType ) {
136+
}
175137

176-
case 'mouse':
177-
case 'pen':
178-
onMouseDown();
179-
break;
180-
// TODO touch
138+
}
181139

182140
}
183141

184142
}
185143

186-
function onMouseDown() {
144+
function onPointerDown() {
187145

146+
_domElement.style.touchAction = 'none';
147+
updatePointer( event );
188148
_intersections.length = 0;
189149

190-
_raycaster.setFromCamera( _mouse, _camera );
150+
_raycaster.setFromCamera( _pointer, _camera );
191151

192152
_raycaster.intersectObjects( _objects, true, _intersections );
193153

194154
if ( _intersections.length > 0 ) {
195155

196156
_selected = scope.transformGroup === true ? _objects[ 0 ] : _intersections[ 0 ].object;
197157

158+
_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
159+
198160
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
199161

200162
_inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
@@ -213,21 +175,7 @@
213175

214176
}
215177

216-
function onPointerCancel( event ) {
217-
218-
switch ( event.pointerType ) {
219-
220-
case 'mouse':
221-
case 'pen':
222-
onMouseCancel();
223-
break;
224-
// TODO touch
225-
226-
}
227-
228-
}
229-
230-
function onMouseCancel() {
178+
function onPointerCancel() {
231179

232180
if ( _selected ) {
233181

@@ -240,93 +188,18 @@
240188
}
241189

242190
_domElement.style.cursor = _hovered ? 'pointer' : 'auto';
191+
_domElement.style.touchAction = '';
243192

244193
}
245194

246-
function onTouchMove( event ) {
195+
function updatePointer( event ) {
247196

248-
event.preventDefault();
249-
event = event.changedTouches[ 0 ];
197+
const e = event.changedTouches ? event.changedTouches[ 0 ] : event;
250198

251199
const rect = _domElement.getBoundingClientRect();
252200

253-
_mouse.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
254-
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
255-
256-
_raycaster.setFromCamera( _mouse, _camera );
257-
258-
if ( _selected && scope.enabled ) {
259-
260-
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
261-
262-
_selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
263-
264-
}
265-
266-
scope.dispatchEvent( {
267-
type: 'drag',
268-
object: _selected
269-
} );
270-
return;
271-
272-
}
273-
274-
}
275-
276-
function onTouchStart( event ) {
277-
278-
event.preventDefault();
279-
event = event.changedTouches[ 0 ];
280-
281-
const rect = _domElement.getBoundingClientRect();
282-
283-
_mouse.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
284-
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1;
285-
_intersections.length = 0;
286-
287-
_raycaster.setFromCamera( _mouse, _camera );
288-
289-
_raycaster.intersectObjects( _objects, true, _intersections );
290-
291-
if ( _intersections.length > 0 ) {
292-
293-
_selected = scope.transformGroup === true ? _objects[ 0 ] : _intersections[ 0 ].object;
294-
295-
_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
296-
297-
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) {
298-
299-
_inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
300-
301-
_offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
302-
303-
}
304-
305-
_domElement.style.cursor = 'move';
306-
scope.dispatchEvent( {
307-
type: 'dragstart',
308-
object: _selected
309-
} );
310-
311-
}
312-
313-
}
314-
315-
function onTouchEnd( event ) {
316-
317-
event.preventDefault();
318-
319-
if ( _selected ) {
320-
321-
scope.dispatchEvent( {
322-
type: 'dragend',
323-
object: _selected
324-
} );
325-
_selected = null;
326-
327-
}
328-
329-
_domElement.style.cursor = 'auto';
201+
_pointer.x = ( e.clientX - rect.left ) / rect.width * 2 - 1;
202+
_pointer.y = - ( e.clientY - rect.top ) / rect.height * 2 + 1;
330203

331204
}
332205

0 commit comments

Comments
 (0)