import * as THREE from 'three'; import { KeyBoard, MouseKey } from './KeyEnum'; import { Vector3 } from 'three'; import { Viewer } from './Viewer'; //相机控制状态 export enum CameraControlState { Null = 0, Pan = 1, Rotate = 2, Scale = 3 } export class CameraControls { m_TouthTypeList = [CameraControlState.Rotate, CameraControlState.Scale, CameraControlState.Pan]; m_domElement: HTMLElement;//HTMLDocument //起始点击 m_StartClickPoint: THREE.Vector3 = new THREE.Vector3(); m_EndClickPoint: THREE.Vector3 = new THREE.Vector3(); m_DollyStart: THREE.Vector2 = new THREE.Vector2(); m_DollyEnd: THREE.Vector2 = new THREE.Vector2(); m_KeyDown = new Map(); m_MouseDown = new Map(); //状态 m_State: CameraControlState = CameraControlState.Null; m_Viewer: Viewer; //左键使用旋转 m_LeftUseRotate: boolean = true; constructor(viewer: Viewer) { this.m_Viewer = viewer; this.m_domElement = viewer.m_Render.domElement.parentElement; this.RegisterEvent(); } RegisterEvent() { if (this.m_domElement) { this.m_domElement.addEventListener("mousedown", this.onMouseDown, false) this.m_domElement.addEventListener("mousemove", this.onMouseMove, false) this.m_domElement.addEventListener("mouseup", this.onMouseUp, false) window.addEventListener("keydown", this.onKeyDown, false); window.addEventListener("keyup", this.onKeyUp, false); this.m_domElement.addEventListener('wheel', this.onMouseWheel, false); this.m_domElement.addEventListener('touchstart', this.onTouchStart, false); this.m_domElement.addEventListener('touchend', this.onTouchEnd, false); this.m_domElement.addEventListener('touchmove', this.onTouchMove, false); window.addEventListener("blur", this.onBlur, false); } } /** * 窗体失去焦点时. * * @memberof CameraControls */ onBlur = () => { this.m_KeyDown.clear(); this.m_MouseDown.clear(); } //触屏开始事件 onTouchStart = (event: TouchEvent) => { this.m_Viewer.UpdateLockTarget(); this.m_StartClickPoint.set(event.touches[0].pageX, event.touches[0].pageY, 0); if (event.touches.length < 4) { if (event.touches.length == 2) { var dx = event.touches[0].pageX - event.touches[1].pageX; var dy = event.touches[0].pageY - event.touches[1].pageY; var distance = Math.sqrt(dx * dx + dy * dy); this.m_DollyStart.set(0, distance); } this.m_State = this.m_TouthTypeList[event.touches.length - 1]; } } onTouchEnd = (event: TouchEvent) => { this.m_State = CameraControlState.Null; } onTouchMove = (event: TouchEvent) => { event.preventDefault(); event.stopPropagation(); this.m_EndClickPoint.set(event.touches[0].pageX, event.touches[0].pageY, 0); let vec = this.m_EndClickPoint.clone().sub(this.m_StartClickPoint); switch (this.m_State) { case CameraControlState.Pan: { this.m_Viewer.Pan(vec); break; } case CameraControlState.Scale: { var dx = event.touches[0].pageX - event.touches[1].pageX; var dy = event.touches[0].pageY - event.touches[1].pageY; var distance = Math.sqrt(dx * dx + dy * dy); this.m_DollyEnd.set(0, distance); if (distance > this.m_DollyStart.y) { this.m_Viewer.Zoom(0.95); } else { this.m_Viewer.Zoom(1.05) } this.m_DollyStart.copy(this.m_DollyEnd); break; } case CameraControlState.Rotate: { this.m_Viewer.Rotate(vec.multiplyScalar(2)); break; } } this.m_StartClickPoint.copy(this.m_EndClickPoint); this.m_Viewer.m_bNeedUpdate = true; } beginRotate() { this.m_State = CameraControlState.Rotate; this.m_Viewer.UpdateLockTarget(); } //最后一次按中键的时间 lastMiddleClickTime = 0; //鼠标 onMouseDown = (event: MouseEvent) => { event.preventDefault(); let key: MouseKey = event.button; this.m_MouseDown.set(key, true); this.m_StartClickPoint.set(event.offsetX, event.offsetY, 0); switch (key) { case MouseKey.Left: { if (this.m_LeftUseRotate) { this.beginRotate(); } break; } case MouseKey.Middle: { let curTime = Date.now(); let t = curTime - this.lastMiddleClickTime; this.lastMiddleClickTime = curTime; if (t < 350) { this.m_Viewer.ZoomAll(); return; } if (this.m_KeyDown.get(KeyBoard.Control)) { this.beginRotate(); } else { this.m_State = CameraControlState.Pan; } break; } case MouseKey.Right: { break; } } } onMouseUp = (event: MouseEvent) => { event.preventDefault(); this.m_State = CameraControlState.Null; this.m_MouseDown.set(event.button, false); } onMouseMove = (event: MouseEvent) => { event.preventDefault(); this.m_EndClickPoint.set(event.offsetX, event.offsetY, 0); let changeVec = this.m_EndClickPoint.clone().sub(this.m_StartClickPoint); this.m_StartClickPoint.copy(this.m_EndClickPoint); if ( (this.m_LeftUseRotate || (this.m_KeyDown.get(KeyBoard.Control)) ) && this.m_State == CameraControlState.Rotate ) { this.m_Viewer.Rotate(changeVec); } switch (this.m_State) { case CameraControlState.Pan: { this.m_Viewer.Pan(changeVec); break; } case CameraControlState.Rotate: { break; } case CameraControlState.Scale: { break; } } } /** * 鼠标滚轮事件 * * @memberof CameraControls */ onMouseWheel = (event: WheelEvent) => { event.preventDefault(); event.stopPropagation(); let pt = new THREE.Vector3(event.offsetX, event.offsetY, 0); this.m_Viewer.ScreenToWorld(pt, new Vector3().setFromMatrixColumn(this.m_Viewer.m_Camera.Camera.matrixWorld, 2)); if (event.deltaY < 0) { this.m_Viewer.Zoom(0.6, pt); } else if (event.deltaY > 0) { this.m_Viewer.Zoom(1.4, pt); } } //按键 onKeyDown = (event: KeyboardEvent) => { this.m_KeyDown.set(event.keyCode, true); } onKeyUp = (event: KeyboardEvent) => { this.m_KeyDown.set(event.keyCode, false); } }