material-editor/src/common/MaterialMouseControl.ts

86 lines
2.4 KiB
TypeScript

import { Vector3 } from 'three';
import type { Viewer } from './Viewer';
/**
* 材质编辑器的场景鼠标控制.
*/
export class MaterialEditorCameraControl {
private Viewer: Viewer;
private _movement: Vector3 = new Vector3();
private _MouseIsDown: boolean = false;
private pointId: number;
private _target: Vector3 | null = null;
get Target() { return this._target; }
set Target(val: Vector3 | null) { this._target = val; }
constructor(view: Viewer, target: Vector3 | null = null) {
this.Viewer = view;
this.Target = target;
this.initMouseControl();
}
initMouseControl() {
let el = this.Viewer.Renderer.domElement;
el.addEventListener("pointerdown", (e) => { this.pointId = e.pointerId; }, false);
el.addEventListener("mousedown", this.onMouseDown, false);
el.addEventListener("mousemove", this.onMouseMove, false);
el.addEventListener("mouseup", this.onMouseUp, false);
el.addEventListener('wheel', this.onMouseWheel, false);
}
onMouseDown = (event: MouseEvent) => {
this.requestPointerLock();
this._MouseIsDown = true;
};
onMouseUp = (event: MouseEvent) => {
this._MouseIsDown = false;
this.exitPointerLock();
};
onMouseMove = (event: MouseEvent) => {
event.preventDefault();
if (this._MouseIsDown) {
this._movement.set(event.movementX, event.movementY, 0);
if (this.Target) {
this.Viewer.RotateAround(this._movement, this.Target);
}
else this.Viewer.Rotate(this._movement);
}
};
onMouseWheel = (event: WheelEvent) =>
{
if (event.deltaY < 0)
{
this.Viewer.Zoom(0.6);
}
else if (event.deltaY > 0)
{
this.Viewer.Zoom(1.4);
}
};
requestPointerLock() {
const dom = this.Viewer.Renderer.domElement;
if (dom.setPointerCapture)
dom.setPointerCapture(this.pointId);
if (dom.requestPointerLock)
dom.requestPointerLock();
}
exitPointerLock() {
const dom = this.Viewer.Renderer.domElement;
if (dom.releasePointerCapture && this.pointId !== undefined) {
try {
dom.releasePointerCapture(this.pointId);
}
catch (error) { }
}
if (document.exitPointerLock)
document.exitPointerLock();
}
}