Files
CADViewComponent/src/CameraControls.ts

237 lines
7.2 KiB
TypeScript
Raw Normal View History

import * as THREE from 'three';
import { Vector3 } from 'three';
import { equaln } from './GeUtils';
import { KeyBoard, MouseKey } from './KeyEnum';
import { Viewer } from './Viewer';
//相机控制状态
export enum CameraControlState
{
Null = 0, Pan = 1, Rotate = 2, Scale = 4
}
export class CameraControls
{
m_TouthTypeList = [CameraControlState.Rotate, CameraControlState.Scale | CameraControlState.Pan, CameraControlState.Pan];
m_domElement: HTMLElement;//HTMLDocument
//起始点击
m_StartClickPoint: THREE.Vector3 = new THREE.Vector3();
m_EndClickPoint: THREE.Vector3 = new THREE.Vector3();
m_DollyStart: number;
m_KeyDown = new Map<KeyBoard, boolean>();
m_MouseDown = new Map<MouseKey, boolean>();
//状态
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, { passive: false });
this.m_domElement.addEventListener('touchstart', this.onTouchStart, { passive: false });
this.m_domElement.addEventListener('touchend', this.onTouchEnd, false);
this.m_domElement.addEventListener('touchmove', this.onTouchMove, { passive: 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 = 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);
if (this.m_State & CameraControlState.Pan)
{
this.m_Viewer.Pan(vec);
}
if (this.m_State & 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);
if (!equaln(this.m_DollyStart / distance, 1, 0.05))//轻微防抖
{
if (distance > this.m_DollyStart)
{
this.m_Viewer.Zoom(0.95);
}
else
{
this.m_Viewer.Zoom(1.05);
}
this.m_DollyStart = distance;
}
}
if (this.m_State & CameraControlState.Rotate)
{
this.m_Viewer.Rotate(vec.multiplyScalar(2));
}
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;
2020-05-07 10:51:27 +08:00
//鼠标
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);
}
if (this.m_State & CameraControlState.Pan)
{
this.m_Viewer.Pan(changeVec);
}
};
/**
*
2020-05-07 10:51:27 +08:00
*
* @memberof CameraControls
*/
onMouseWheel = (event: WheelEvent) =>
{
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);
};
}