cursor-style-manager-wle
Version:
Shared cursor styles for Wonderland Engine
136 lines • 5.97 kB
JavaScript
import { Type } from '@wonderlandengine/api';
import { quat, vec3 } from 'gl-matrix';
import { CSMComponent } from './CSMComponent.js';
const Y_AXIS = new Float32Array([0, 1, 0]);
const Z_AXIS = new Float32Array([0, 0, 1]);
const TMP_VEC3 = new Float32Array(3);
const TEMP_ROT = new Float32Array(4);
const RAD_TO_DEG = 180 / Math.PI;
const ROT_MUL = RAD_TO_DEG / 100;
/**
* Similar to the official mouse-look component, but with cursor-style-manager
* support.
*/
class CSMMouseLookComponent extends CSMComponent {
init() {
super.init();
this.currentRotationY = 0;
this.currentRotationX = 0;
this.mouseDown = false;
this.lastCursorX = 0;
this.lastCursorY = 0;
this.lastPointerId = -1;
}
updateLastCursorPos(e) {
this.lastCursorX = e.screenX;
this.lastCursorY = e.screenY;
}
isActivePointer(e) {
return !this.requireMouseDown || !this.listenToPointerInsteadOfMouse || e.pointerId === this.lastPointerId;
}
start() {
document.addEventListener(this.listenToPointerInsteadOfMouse ? 'pointermove' : 'mousemove', (e) => {
if (!this.isActivePointer(e))
return;
if (this.active && (this.mouseDown || !this.requireMouseDown)) {
const deltaX = this.betterPointerMovement ? (e.screenX - this.lastCursorX) : e.movementX;
const deltaY = this.betterPointerMovement ? (e.screenY - this.lastCursorY) : e.movementY;
this.updateLastCursorPos(e);
if (this.statelessDrag) {
this.object.getRotationLocal(TEMP_ROT);
vec3.transformQuat(TMP_VEC3, Z_AXIS, TEMP_ROT);
this.currentRotationX = Math.asin(-vec3.dot(TMP_VEC3, Y_AXIS)) * RAD_TO_DEG;
this.currentRotationY = Math.atan2(TMP_VEC3[0], TMP_VEC3[2]) * RAD_TO_DEG;
}
this.currentRotationX += (-this.sensitivity * deltaY) * ROT_MUL;
this.currentRotationY += (-this.sensitivity * deltaX) * ROT_MUL;
// 89 deg instead of 90 so that there are no camera glitches
// when looking straight down/up
this.currentRotationX = Math.max(-89, Math.min(89, this.currentRotationX));
quat.fromEuler(TEMP_ROT, this.currentRotationX, this.currentRotationY, 0);
this.object.setRotationLocal(TEMP_ROT);
}
});
const canvas = this.engine.canvas;
if (this.pointerLockOnClick) {
canvas.addEventListener('mousedown', (e) => {
this.updateLastCursorPos(e);
canvas.requestPointerLock =
canvas.requestPointerLock ||
canvas.mozRequestPointerLock ||
canvas.webkitRequestPointerLock;
canvas.requestPointerLock();
});
}
if (this.requireMouseDown) {
if (this.mouseButtonIndex == 2) {
canvas.addEventListener('contextmenu', (e) => {
e.preventDefault();
}, false);
}
canvas.addEventListener(this.listenToPointerInsteadOfMouse ? 'pointerdown' : 'mousedown', (e) => {
if (this.listenToPointerInsteadOfMouse) {
this.lastPointerId = e.pointerId;
}
this.updateLastCursorPos(e);
if (e.button == this.mouseButtonIndex && this.active) {
this.mouseDown = true;
this.setCursorStyle('grabbing');
if (e.button == 1) {
e.preventDefault();
/* Prevent scrolling */
return false;
}
}
});
canvas.addEventListener(this.listenToPointerInsteadOfMouse ? 'pointerup' : 'mouseup', (e) => {
if (!this.isActivePointer(e))
return;
this.updateLastCursorPos(e);
if (e.button == this.mouseButtonIndex) {
this.mouseUp();
}
});
canvas.addEventListener(this.listenToPointerInsteadOfMouse ? 'pointerleave' : 'mouseleave', (e) => {
if (!this.isActivePointer(e))
return;
this.mouseUp();
});
}
}
onDeactivate() {
super.onDeactivate();
this.mouseUp();
}
mouseUp() {
this.lastPointerId = -1;
if (!this.mouseDown)
return;
this.mouseDown = false;
if (this.requireMouseDown)
this.setCursorStyle(null);
}
}
CSMMouseLookComponent.TypeName = 'csm-mouse-look';
CSMMouseLookComponent.Properties = Object.assign(Object.assign({}, CSMComponent.Properties), {
/** Mouse look sensitivity */
sensitivity: { type: Type.Float, default: 0.25 },
/** Require a mouse button to be pressed to control view.
* Otherwise view will allways follow mouse movement */
requireMouseDown: { type: Type.Bool, default: true },
/** If "moveOnClick" is enabled, mouse button which should
* be held down to control view */
mouseButtonIndex: { type: Type.Int },
/** Enables pointer lock on "mousedown" event on canvas */
pointerLockOnClick: { type: Type.Bool, default: false },
/** Should pointer events be listened to instead of mouse events? */
listenToPointerInsteadOfMouse: { type: Type.Bool, default: false },
/**
* Should an improved drag algorithm be used, which can be combined with
* other camera rotating methods?
*/
statelessDrag: { type: Type.Bool, default: false },
/** Should an improved method of getting mouse movement be used? */
betterPointerMovement: { type: Type.Bool, default: false } });
export { CSMMouseLookComponent };
//# sourceMappingURL=CSMMouseLook.js.map