first commit
This commit is contained in:
410
web-app/node_modules/three/examples/jsm/controls/DragControls.js
generated
vendored
Normal file
410
web-app/node_modules/three/examples/jsm/controls/DragControls.js
generated
vendored
Normal file
@@ -0,0 +1,410 @@
|
||||
import {
|
||||
Controls,
|
||||
Matrix4,
|
||||
Plane,
|
||||
Raycaster,
|
||||
Vector2,
|
||||
Vector3,
|
||||
MOUSE,
|
||||
TOUCH
|
||||
} from 'three';
|
||||
|
||||
const _plane = new Plane();
|
||||
|
||||
const _pointer = new Vector2();
|
||||
const _offset = new Vector3();
|
||||
const _diff = new Vector2();
|
||||
const _previousPointer = new Vector2();
|
||||
const _intersection = new Vector3();
|
||||
const _worldPosition = new Vector3();
|
||||
const _inverseMatrix = new Matrix4();
|
||||
|
||||
const _up = new Vector3();
|
||||
const _right = new Vector3();
|
||||
|
||||
let _selected = null, _hovered = null;
|
||||
const _intersections = [];
|
||||
|
||||
const STATE = {
|
||||
NONE: - 1,
|
||||
PAN: 0,
|
||||
ROTATE: 1
|
||||
};
|
||||
|
||||
class DragControls extends Controls {
|
||||
|
||||
constructor( objects, camera, domElement = null ) {
|
||||
|
||||
super( camera, domElement );
|
||||
|
||||
this.objects = objects;
|
||||
|
||||
this.recursive = true;
|
||||
this.transformGroup = false;
|
||||
this.rotateSpeed = 1;
|
||||
|
||||
this.raycaster = new Raycaster();
|
||||
|
||||
// interaction
|
||||
|
||||
this.mouseButtons = { LEFT: MOUSE.PAN, MIDDLE: MOUSE.PAN, RIGHT: MOUSE.ROTATE };
|
||||
this.touches = { ONE: TOUCH.PAN };
|
||||
|
||||
// event listeners
|
||||
|
||||
this._onPointerMove = onPointerMove.bind( this );
|
||||
this._onPointerDown = onPointerDown.bind( this );
|
||||
this._onPointerCancel = onPointerCancel.bind( this );
|
||||
this._onContextMenu = onContextMenu.bind( this );
|
||||
|
||||
//
|
||||
|
||||
if ( domElement !== null ) {
|
||||
|
||||
this.connect();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
connect() {
|
||||
|
||||
this.domElement.addEventListener( 'pointermove', this._onPointerMove );
|
||||
this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
|
||||
this.domElement.addEventListener( 'pointerup', this._onPointerCancel );
|
||||
this.domElement.addEventListener( 'pointerleave', this._onPointerCancel );
|
||||
this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
|
||||
|
||||
this.domElement.style.touchAction = 'none'; // disable touch scroll
|
||||
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
|
||||
this.domElement.removeEventListener( 'pointermove', this._onPointerMove );
|
||||
this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
|
||||
this.domElement.removeEventListener( 'pointerup', this._onPointerCancel );
|
||||
this.domElement.removeEventListener( 'pointerleave', this._onPointerCancel );
|
||||
this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
|
||||
|
||||
this.domElement.style.touchAction = 'auto';
|
||||
this.domElement.style.cursor = '';
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.disconnect();
|
||||
|
||||
}
|
||||
|
||||
_updatePointer( event ) {
|
||||
|
||||
const rect = this.domElement.getBoundingClientRect();
|
||||
|
||||
_pointer.x = ( event.clientX - rect.left ) / rect.width * 2 - 1;
|
||||
_pointer.y = - ( event.clientY - rect.top ) / rect.height * 2 + 1;
|
||||
|
||||
}
|
||||
|
||||
_updateState( event ) {
|
||||
|
||||
// determine action
|
||||
|
||||
let action;
|
||||
|
||||
if ( event.pointerType === 'touch' ) {
|
||||
|
||||
action = this.touches.ONE;
|
||||
|
||||
} else {
|
||||
|
||||
switch ( event.button ) {
|
||||
|
||||
case 0:
|
||||
|
||||
action = this.mouseButtons.LEFT;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
action = this.mouseButtons.MIDDLE;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
action = this.mouseButtons.RIGHT;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
action = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// determine state
|
||||
|
||||
switch ( action ) {
|
||||
|
||||
case MOUSE.PAN:
|
||||
case TOUCH.PAN:
|
||||
|
||||
this.state = STATE.PAN;
|
||||
|
||||
break;
|
||||
|
||||
case MOUSE.ROTATE:
|
||||
case TOUCH.ROTATE:
|
||||
|
||||
this.state = STATE.ROTATE;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
this.state = STATE.NONE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getRaycaster() {
|
||||
|
||||
console.warn( 'THREE.DragControls: getRaycaster() has been deprecated. Use controls.raycaster instead.' ); // @deprecated r169
|
||||
|
||||
return this.raycaster;
|
||||
|
||||
}
|
||||
|
||||
setObjects( objects ) {
|
||||
|
||||
console.warn( 'THREE.DragControls: setObjects() has been deprecated. Use controls.objects instead.' ); // @deprecated r169
|
||||
|
||||
this.objects = objects;
|
||||
|
||||
}
|
||||
|
||||
getObjects() {
|
||||
|
||||
console.warn( 'THREE.DragControls: getObjects() has been deprecated. Use controls.objects instead.' ); // @deprecated r169
|
||||
|
||||
return this.objects;
|
||||
|
||||
}
|
||||
|
||||
activate() {
|
||||
|
||||
console.warn( 'THREE.DragControls: activate() has been renamed to connect().' ); // @deprecated r169
|
||||
this.connect();
|
||||
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
|
||||
console.warn( 'THREE.DragControls: deactivate() has been renamed to disconnect().' ); // @deprecated r169
|
||||
this.disconnect();
|
||||
|
||||
}
|
||||
|
||||
set mode( value ) {
|
||||
|
||||
console.warn( 'THREE.DragControls: The .mode property has been removed. Define the type of transformation via the .mouseButtons or .touches properties.' ); // @deprecated r169
|
||||
|
||||
}
|
||||
|
||||
get mode() {
|
||||
|
||||
console.warn( 'THREE.DragControls: The .mode property has been removed. Define the type of transformation via the .mouseButtons or .touches properties.' ); // @deprecated r169
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onPointerMove( event ) {
|
||||
|
||||
const camera = this.object;
|
||||
const domElement = this.domElement;
|
||||
const raycaster = this.raycaster;
|
||||
|
||||
if ( this.enabled === false ) return;
|
||||
|
||||
this._updatePointer( event );
|
||||
|
||||
raycaster.setFromCamera( _pointer, camera );
|
||||
|
||||
if ( _selected ) {
|
||||
|
||||
if ( this.state === STATE.PAN ) {
|
||||
|
||||
if ( raycaster.ray.intersectPlane( _plane, _intersection ) ) {
|
||||
|
||||
_selected.position.copy( _intersection.sub( _offset ).applyMatrix4( _inverseMatrix ) );
|
||||
|
||||
}
|
||||
|
||||
} else if ( this.state === STATE.ROTATE ) {
|
||||
|
||||
_diff.subVectors( _pointer, _previousPointer ).multiplyScalar( this.rotateSpeed );
|
||||
_selected.rotateOnWorldAxis( _up, _diff.x );
|
||||
_selected.rotateOnWorldAxis( _right.normalize(), - _diff.y );
|
||||
|
||||
}
|
||||
|
||||
this.dispatchEvent( { type: 'drag', object: _selected } );
|
||||
|
||||
_previousPointer.copy( _pointer );
|
||||
|
||||
} else {
|
||||
|
||||
// hover support
|
||||
|
||||
if ( event.pointerType === 'mouse' || event.pointerType === 'pen' ) {
|
||||
|
||||
_intersections.length = 0;
|
||||
|
||||
raycaster.setFromCamera( _pointer, camera );
|
||||
raycaster.intersectObjects( this.objects, this.recursive, _intersections );
|
||||
|
||||
if ( _intersections.length > 0 ) {
|
||||
|
||||
const object = _intersections[ 0 ].object;
|
||||
|
||||
_plane.setFromNormalAndCoplanarPoint( camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( object.matrixWorld ) );
|
||||
|
||||
if ( _hovered !== object && _hovered !== null ) {
|
||||
|
||||
this.dispatchEvent( { type: 'hoveroff', object: _hovered } );
|
||||
|
||||
domElement.style.cursor = 'auto';
|
||||
_hovered = null;
|
||||
|
||||
}
|
||||
|
||||
if ( _hovered !== object ) {
|
||||
|
||||
this.dispatchEvent( { type: 'hoveron', object: object } );
|
||||
|
||||
domElement.style.cursor = 'pointer';
|
||||
_hovered = object;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( _hovered !== null ) {
|
||||
|
||||
this.dispatchEvent( { type: 'hoveroff', object: _hovered } );
|
||||
|
||||
domElement.style.cursor = 'auto';
|
||||
_hovered = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_previousPointer.copy( _pointer );
|
||||
|
||||
}
|
||||
|
||||
function onPointerDown( event ) {
|
||||
|
||||
const camera = this.object;
|
||||
const domElement = this.domElement;
|
||||
const raycaster = this.raycaster;
|
||||
|
||||
if ( this.enabled === false ) return;
|
||||
|
||||
this._updatePointer( event );
|
||||
this._updateState( event );
|
||||
|
||||
_intersections.length = 0;
|
||||
|
||||
raycaster.setFromCamera( _pointer, camera );
|
||||
raycaster.intersectObjects( this.objects, this.recursive, _intersections );
|
||||
|
||||
if ( _intersections.length > 0 ) {
|
||||
|
||||
if ( this.transformGroup === true ) {
|
||||
|
||||
// look for the outermost group in the object's upper hierarchy
|
||||
|
||||
_selected = findGroup( _intersections[ 0 ].object );
|
||||
|
||||
} else {
|
||||
|
||||
_selected = _intersections[ 0 ].object;
|
||||
|
||||
}
|
||||
|
||||
_plane.setFromNormalAndCoplanarPoint( camera.getWorldDirection( _plane.normal ), _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
|
||||
|
||||
if ( raycaster.ray.intersectPlane( _plane, _intersection ) ) {
|
||||
|
||||
if ( this.state === STATE.PAN ) {
|
||||
|
||||
_inverseMatrix.copy( _selected.parent.matrixWorld ).invert();
|
||||
_offset.copy( _intersection ).sub( _worldPosition.setFromMatrixPosition( _selected.matrixWorld ) );
|
||||
|
||||
} else if ( this.state === STATE.ROTATE ) {
|
||||
|
||||
// the controls only support Y+ up
|
||||
_up.set( 0, 1, 0 ).applyQuaternion( camera.quaternion ).normalize();
|
||||
_right.set( 1, 0, 0 ).applyQuaternion( camera.quaternion ).normalize();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
domElement.style.cursor = 'move';
|
||||
|
||||
this.dispatchEvent( { type: 'dragstart', object: _selected } );
|
||||
|
||||
}
|
||||
|
||||
_previousPointer.copy( _pointer );
|
||||
|
||||
}
|
||||
|
||||
function onPointerCancel() {
|
||||
|
||||
if ( this.enabled === false ) return;
|
||||
|
||||
if ( _selected ) {
|
||||
|
||||
this.dispatchEvent( { type: 'dragend', object: _selected } );
|
||||
|
||||
_selected = null;
|
||||
|
||||
}
|
||||
|
||||
this.domElement.style.cursor = _hovered ? 'pointer' : 'auto';
|
||||
|
||||
this.state = STATE.NONE;
|
||||
|
||||
}
|
||||
|
||||
function onContextMenu( event ) {
|
||||
|
||||
if ( this.enabled === false ) return;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
}
|
||||
|
||||
function findGroup( obj, group = null ) {
|
||||
|
||||
if ( obj.isGroup ) group = obj;
|
||||
|
||||
if ( obj.parent === null ) return group;
|
||||
|
||||
return findGroup( obj.parent, group );
|
||||
|
||||
}
|
||||
|
||||
export { DragControls };
|
||||
Reference in New Issue
Block a user