From 25da1655019e85e178198736b24aae629e2b3d9b Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Mon, 7 Jun 2021 11:13:50 +0200 Subject: [PATCH] DragControls: Fully migrate to pointer events. (#21958) --- examples/js/controls/DragControls.js | 225 ++++++-------------------- examples/jsm/controls/DragControls.js | 197 ++++++---------------- 2 files changed, 95 insertions(+), 327 deletions(-) diff --git a/examples/js/controls/DragControls.js b/examples/js/controls/DragControls.js index 219180fab1..1dca969ff6 100644 --- a/examples/js/controls/DragControls.js +++ b/examples/js/controls/DragControls.js @@ -4,7 +4,7 @@ const _raycaster = new THREE.Raycaster(); - const _mouse = new THREE.Vector2(); + const _pointer = new THREE.Vector2(); const _offset = new THREE.Vector3(); @@ -35,16 +35,6 @@ _domElement.addEventListener( 'pointerleave', onPointerCancel ); - _domElement.addEventListener( 'touchmove', onTouchMove, { - passive: false - } ); - - _domElement.addEventListener( 'touchstart', onTouchStart, { - passive: false - } ); - - _domElement.addEventListener( 'touchend', onTouchEnd ); - } function deactivate() { @@ -57,12 +47,6 @@ _domElement.removeEventListener( 'pointerleave', onPointerCancel ); - _domElement.removeEventListener( 'touchmove', onTouchMove ); - - _domElement.removeEventListener( 'touchstart', onTouchStart ); - - _domElement.removeEventListener( 'touchend', onTouchEnd ); - _domElement.style.cursor = ''; } @@ -81,26 +65,9 @@ function onPointerMove( event ) { - switch ( event.pointerType ) { - - case 'mouse': - case 'pen': - onMouseMove( event ); - break; - // TODO touch - - } - - } - - function onMouseMove( event ) { - - const rect = _domElement.getBoundingClientRect(); - - _mouse.x = ( event.clientX - rect.left ) / rect.width * 2 - 1; - _mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; + updatePointer( event ); - _raycaster.setFromCamera( _mouse, _camera ); + _raycaster.setFromCamera( _pointer, _camera ); if ( _selected && scope.enabled ) { @@ -116,78 +83,71 @@ } ); return; - } + } // hover support - _intersections.length = 0; - _raycaster.setFromCamera( _mouse, _camera ); + if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) { - _raycaster.intersectObjects( _objects, true, _intersections ); + _intersections.length = 0; - if ( _intersections.length > 0 ) { + _raycaster.setFromCamera( _pointer, _camera ); - const object = _intersections[ 0 ].object; + _raycaster.intersectObjects( _objects, true, _intersections ); - _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) ); + if ( _intersections.length > 0 ) { - if ( _hovered !== object && _hovered !== null ) { + const object = _intersections[ 0 ].object; - scope.dispatchEvent( { - type: 'hoveroff', - object: _hovered - } ); - _domElement.style.cursor = 'auto'; - _hovered = null; + _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) ); - } + if ( _hovered !== object && _hovered !== null ) { - if ( _hovered !== object ) { + scope.dispatchEvent( { + type: 'hoveroff', + object: _hovered + } ); + _domElement.style.cursor = 'auto'; + _hovered = null; - scope.dispatchEvent( { - type: 'hoveron', - object: object - } ); - _domElement.style.cursor = 'pointer'; - _hovered = object; + } - } - - } else { - - if ( _hovered !== null ) { + if ( _hovered !== object ) { - scope.dispatchEvent( { - type: 'hoveroff', - object: _hovered - } ); - _domElement.style.cursor = 'auto'; - _hovered = null; + scope.dispatchEvent( { + type: 'hoveron', + object: object + } ); + _domElement.style.cursor = 'pointer'; + _hovered = object; - } + } - } + } else { - } + if ( _hovered !== null ) { - function onPointerDown( event ) { + scope.dispatchEvent( { + type: 'hoveroff', + object: _hovered + } ); + _domElement.style.cursor = 'auto'; + _hovered = null; - switch ( event.pointerType ) { + } - case 'mouse': - case 'pen': - onMouseDown(); - break; - // TODO touch + } } } - function onMouseDown() { + function onPointerDown() { + _domElement.style.touchAction = 'none'; + updatePointer( event ); _intersections.length = 0; - _raycaster.setFromCamera( _mouse, _camera ); + _raycaster.setFromCamera( _pointer, _camera ); _raycaster.intersectObjects( _objects, true, _intersections ); @@ -195,6 +155,8 @@ _selected = scope.transformGroup === true ? _objects[ 0 ] : _intersections[ 0 ].object; + _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); + if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { _inverseMatrix.copy( _selected.parent.matrixWorld ).invert(); @@ -213,21 +175,7 @@ } - function onPointerCancel( event ) { - - switch ( event.pointerType ) { - - case 'mouse': - case 'pen': - onMouseCancel(); - break; - // TODO touch - - } - - } - - function onMouseCancel() { + function onPointerCancel() { if ( _selected ) { @@ -240,93 +188,18 @@ } _domElement.style.cursor = _hovered ? 'pointer' : 'auto'; + _domElement.style.touchAction = ''; } - function onTouchMove( event ) { + function updatePointer( event ) { - event.preventDefault(); - event = event.changedTouches[ 0 ]; + const e = event.changedTouches ? event.changedTouches[ 0 ] : event; const rect = _domElement.getBoundingClientRect(); - _mouse.x = ( event.clientX - rect.left ) / rect.width * 2 - 1; - _mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; - - _raycaster.setFromCamera( _mouse, _camera ); - - if ( _selected && scope.enabled ) { - - if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { - - _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) ); - - } - - scope.dispatchEvent( { - type: 'drag', - object: _selected - } ); - return; - - } - - } - - function onTouchStart( event ) { - - event.preventDefault(); - event = event.changedTouches[ 0 ]; - - const rect = _domElement.getBoundingClientRect(); - - _mouse.x = ( event.clientX - rect.left ) / rect.width * 2 - 1; - _mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; - _intersections.length = 0; - - _raycaster.setFromCamera( _mouse, _camera ); - - _raycaster.intersectObjects( _objects, true, _intersections ); - - if ( _intersections.length > 0 ) { - - _selected = scope.transformGroup === true ? _objects[ 0 ] : _intersections[ 0 ].object; - - _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); - - if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { - - _inverseMatrix.copy( _selected.parent.matrixWorld ).invert(); - - _offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); - - } - - _domElement.style.cursor = 'move'; - scope.dispatchEvent( { - type: 'dragstart', - object: _selected - } ); - - } - - } - - function onTouchEnd( event ) { - - event.preventDefault(); - - if ( _selected ) { - - scope.dispatchEvent( { - type: 'dragend', - object: _selected - } ); - _selected = null; - - } - - _domElement.style.cursor = 'auto'; + _pointer.x = ( e.clientX - rect.left ) / rect.width * 2 - 1; + _pointer.y = - ( e.clientY - rect.top ) / rect.height * 2 + 1; } diff --git a/examples/jsm/controls/DragControls.js b/examples/jsm/controls/DragControls.js index bab258202e..5a54b6d325 100644 --- a/examples/jsm/controls/DragControls.js +++ b/examples/jsm/controls/DragControls.js @@ -10,7 +10,7 @@ import { const _plane = new Plane(); const _raycaster = new Raycaster(); -const _mouse = new Vector2(); +const _pointer = new Vector2(); const _offset = new Vector3(); const _intersection = new Vector3(); const _worldPosition = new Vector3(); @@ -36,9 +36,6 @@ class DragControls extends EventDispatcher { _domElement.addEventListener( 'pointerdown', onPointerDown ); _domElement.addEventListener( 'pointerup', onPointerCancel ); _domElement.addEventListener( 'pointerleave', onPointerCancel ); - _domElement.addEventListener( 'touchmove', onTouchMove, { passive: false } ); - _domElement.addEventListener( 'touchstart', onTouchStart, { passive: false } ); - _domElement.addEventListener( 'touchend', onTouchEnd ); } @@ -48,9 +45,6 @@ class DragControls extends EventDispatcher { _domElement.removeEventListener( 'pointerdown', onPointerDown ); _domElement.removeEventListener( 'pointerup', onPointerCancel ); _domElement.removeEventListener( 'pointerleave', onPointerCancel ); - _domElement.removeEventListener( 'touchmove', onTouchMove ); - _domElement.removeEventListener( 'touchstart', onTouchStart ); - _domElement.removeEventListener( 'touchend', onTouchEnd ); _domElement.style.cursor = ''; @@ -70,29 +64,13 @@ class DragControls extends EventDispatcher { function onPointerMove( event ) { - switch ( event.pointerType ) { + if ( scope.enabled === false ) return; - case 'mouse': - case 'pen': - onMouseMove( event ); - break; + updatePointer( event ); - // TODO touch + _raycaster.setFromCamera( _pointer, _camera ); - } - - } - - function onMouseMove( event ) { - - const rect = _domElement.getBoundingClientRect(); - - _mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1; - _mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; - - _raycaster.setFromCamera( _mouse, _camera ); - - if ( _selected && scope.enabled ) { + if ( _selected ) { if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { @@ -106,76 +84,75 @@ class DragControls extends EventDispatcher { } - _intersections.length = 0; + // hover support - _raycaster.setFromCamera( _mouse, _camera ); - _raycaster.intersectObjects( _objects, true, _intersections ); + if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) { - if ( _intersections.length > 0 ) { + _intersections.length = 0; - const object = _intersections[ 0 ].object; + _raycaster.setFromCamera( _pointer, _camera ); + _raycaster.intersectObjects( _objects, true, _intersections ); - _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) ); + if ( _intersections.length > 0 ) { - if ( _hovered !== object && _hovered !== null ) { + const object = _intersections[ 0 ].object; - scope.dispatchEvent( { type: 'hoveroff', object: _hovered } ); + _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) ); - _domElement.style.cursor = 'auto'; - _hovered = null; + if ( _hovered !== object && _hovered !== null ) { - } + scope.dispatchEvent( { type: 'hoveroff', object: _hovered } ); - if ( _hovered !== object ) { + _domElement.style.cursor = 'auto'; + _hovered = null; - scope.dispatchEvent( { type: 'hoveron', object: object } ); + } - _domElement.style.cursor = 'pointer'; - _hovered = object; + if ( _hovered !== object ) { - } + scope.dispatchEvent( { type: 'hoveron', object: object } ); - } else { + _domElement.style.cursor = 'pointer'; + _hovered = object; - if ( _hovered !== null ) { + } - scope.dispatchEvent( { type: 'hoveroff', object: _hovered } ); + } else { - _domElement.style.cursor = 'auto'; - _hovered = null; + if ( _hovered !== null ) { - } + scope.dispatchEvent( { type: 'hoveroff', object: _hovered } ); - } + _domElement.style.cursor = 'auto'; + _hovered = null; - } + } - function onPointerDown( event ) { + } - switch ( event.pointerType ) { + } - case 'mouse': - case 'pen': - onMouseDown(); - break; + } - // TODO touch + function onPointerDown() { - } + if ( scope.enabled === false ) return; - } + _domElement.style.touchAction = 'none'; - function onMouseDown() { + updatePointer( event ); _intersections.length = 0; - _raycaster.setFromCamera( _mouse, _camera ); + _raycaster.setFromCamera( _pointer, _camera ); _raycaster.intersectObjects( _objects, true, _intersections ); if ( _intersections.length > 0 ) { _selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object; + _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); + if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { _inverseMatrix.copy( _selected.parent.matrixWorld ).invert(); @@ -192,22 +169,9 @@ class DragControls extends EventDispatcher { } - function onPointerCancel( event ) { - - switch ( event.pointerType ) { + function onPointerCancel() { - case 'mouse': - case 'pen': - onMouseCancel(); - break; - - // TODO touch - - } - - } - - function onMouseCancel() { + if ( scope.enabled === false ) return; if ( _selected ) { @@ -218,87 +182,18 @@ class DragControls extends EventDispatcher { } _domElement.style.cursor = _hovered ? 'pointer' : 'auto'; + _domElement.style.touchAction = ''; } - function onTouchMove( event ) { + function updatePointer( event ) { - event.preventDefault(); - event = event.changedTouches[ 0 ]; + const e = event.changedTouches ? event.changedTouches[ 0 ] : event; const rect = _domElement.getBoundingClientRect(); - _mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1; - _mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; - - _raycaster.setFromCamera( _mouse, _camera ); - - if ( _selected && scope.enabled ) { - - if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { - - _selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) ); - - } - - scope.dispatchEvent( { type: 'drag', object: _selected } ); - - return; - - } - - } - - function onTouchStart( event ) { - - event.preventDefault(); - event = event.changedTouches[ 0 ]; - - const rect = _domElement.getBoundingClientRect(); - - _mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1; - _mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; - - _intersections.length = 0; - - _raycaster.setFromCamera( _mouse, _camera ); - _raycaster.intersectObjects( _objects, true, _intersections ); - - if ( _intersections.length > 0 ) { - - _selected = ( scope.transformGroup === true ) ? _objects[ 0 ] : _intersections[ 0 ].object; - - _plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); - - if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { - - _inverseMatrix.copy( _selected.parent.matrixWorld ).invert(); - _offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) ); - - } - - _domElement.style.cursor = 'move'; - - scope.dispatchEvent( { type: 'dragstart', object: _selected } ); - - } - - - } - - function onTouchEnd( event ) { - - event.preventDefault(); - - if ( _selected ) { - - scope.dispatchEvent( { type: 'dragend', object: _selected } ); - - _selected = null; - - } - - _domElement.style.cursor = 'auto'; + _pointer.x = ( e.clientX - rect.left ) / rect.width * 2 - 1; + _pointer.y = - ( e.clientY - rect.top ) / rect.height * 2 + 1; } -- GitLab