three.js第一人称视角控制+全屏+鼠标锁定处理

three.js第一人称视角控制+全屏+鼠标锁定处理

视角控制改变

以下代码根据FirstPersonControls.js修改,附上源代码github地址:FirstPersonControls.js

//改变为根据鼠标移动的幅度移动视角
this.onMouseMove = function ( event ) {
		//新增,判断鼠标移动,初始化为false
		this.mouseMove = true;
		//新增,鼠标位置,初始化内容见下三行注释
		//this.rotateEnd = new THREE.Vector2();
		//this.rotateDelta = new THREE.Vector2();
		//this.rotateStart = new THREE.Vector2();
		this.rotateEnd.set( event.clientX, event.clientY );
		if(this.pointerLock===true){  
		/*
		 *添加pointerLock属性,处理当全屏并鼠标锁定的鼠标运动视角变化
		 *当鼠标锁定时,移动事件对象的位置相关属性中只有movementX和movementY属性会改变
		 */
			this.rotateDelta.set( event.movementX, event.movementY );
		}else{
			this.rotateDelta.subVectors( this.rotateEnd, this.rotateStart );
		}
		this.rotateStart.copy( this.rotateEnd );
};
//新增事件
this.onMouseOver = function( event ){
		//设置鼠标初始位置
		this.rotateStart.set( event.clientX, event.clientY );
}
//更改后的this.update方法
this.update = function ( delta ) {

		if ( this.enabled === false ) return;

		if ( this.heightSpeed ) {

			var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax );
			var heightDelta = y - this.heightMin;

			this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef );

		} else {

			this.autoSpeedFactor = 0.0;

		}

		var actualMoveSpeed = delta * this.movementSpeed;

		if ( this.moveForward || ( this.autoForward && ! this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
		if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed );

		if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed );
		if ( this.moveRight ) this.object.translateX( actualMoveSpeed );

		if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
		if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
		
		if(this.mouseMove === true){
			var actualLookSpeed = delta * this.lookSpeed*40;

			if ( ! this.activeLook ) {

				actualLookSpeed = 0;

			}

			var verticalLookRatio = 1;

			if ( this.constrainVertical ) {

				verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );

			}

			this.lon += this.rotateDelta.x * actualLookSpeed;
			if ( this.lookVertical ){
				this.lat -= this.rotateDelta.y * actualLookSpeed * verticalLookRatio;
			}
			this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
			
			this.phi = THREE.Math.degToRad( 90 - this.lat );
			this.theta = THREE.Math.degToRad( this.lon );

			if ( this.constrainVertical ) {

				this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax );

			}
		}
		var targetPosition = this.target,
			position = this.object.position;

		targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
		targetPosition.y = position.y + 100 * Math.cos( this.phi );
		targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
		
		this.object.lookAt( targetPosition );
		this.mouseMove = false;
}

全屏

使用fullscreen.js,github地址:fullscreen.js
全屏 MDN web docs: Element.requestFullscreen()

//全屏需要用户交互触发事件,示例使用点击按钮的方式
document.getElementById('button').addEventListener('click', () => {
    if (screenfull.enabled) {
        screenfull.request();
    } else {
        // Ignore or do something else
    }
});

监听全屏事件并锁定鼠标

鼠标锁定 MDN web docs: Pointer Lock API

document.addEventListener('fullscreenchange', fullscreenChange, false);
document.addEventListener('mozfullscreenchange', fullscreenChange, false);
document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
function fullscreenChange(elem) {
	if (document.webkitFullscreenElement === elem ||
		document.mozFullscreenElement === elem ||
		document.mozFullScreenElement === elem ) { 
			elem.requestPointerLock = elem.requestPointerLock    ||
								elem.mozRequestPointerLock ||
								elem.webkitRequestPointerLock;
		elem.requestPointerLock();
	}else{
		document.documentElement.requestPointerLock = document.documentElement.requestPointerLock    ||
                              document.documentElement.mozRequestPointerLock ||
                              document.documentElement.webkitRequestPointerLock;
		document.documentElement.requestPointerLock();			  
	}
	//改变FirstPersonControls的实例对象的鼠标锁定属性
	control.pointerLock = true;
}

版权声明:本文为dvb1188原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。