@derschmale/tiny-input
v0.1.0
Published
A TypeScript library for poll-based input
Downloads
22
Readme
tiny-input
A lightweight polling input library made to reduce much of the boilerplate code needed when working with inputs in web-based interactive projects.
Example
My apologies for the lack of documentation, but this example of a simple orbit controller should be enough to get you started:
import {Action, Keyboard, Mouse, MouseTrigger, TinyInput} from "tiny-input";
import {mat4, vec3} from "gl-matrix";
import {Transform} from "../math/Transform"; // imagine your own Transform class here
import {SphericalCoord} from "../math/SphericalCoord"; // imagine your own SphericalCoord class here
const UP = vec3.fromValues(0, 0, 1);
const X_AXIS = vec3.create();
const Y_AXIS = vec3.create();
const Z_AXIS = vec3.create();
export class OrbitController {
target: Transform;
pivot: vec3 = vec3.fromValues(0, 0, 0);
position: SphericalCoord = new SphericalCoord();
rotateSpeed: number = 0.01;
zoomSpeed: number = 30;
minRadius: number = 1;
maxRadius: number = 100;
smoothing: number = 0.9;
private _smoothedPosition: SphericalCoord = new SphericalCoord();
private _input: TinyInput;
private _mouse: Mouse;
private _keyboard: Keyboard;
private _rotateAzimuth: Action;
private _rotateElevation: Action;
private _zoom: Action;
private _enabled: boolean = false;
constructor(input: TinyInput, target: Transform) {
const offset = vec3.sub(vec3.create(), target.position, this.pivot);
SphericalCoord.fromVec3(this.position, offset);
this._smoothedPosition.copyFrom(this.position);
this.target = target;
this._input = input;
this._rotateAzimuth = input.createAction();
this._rotateElevation = input.createAction();
this._zoom = input.createAction();
this._mouse = new Mouse()
.setSensitivity(100)
.setTrigger(MouseTrigger.DragX, this._rotateAzimuth)
.setTrigger(MouseTrigger.DragY, this._rotateElevation)
.setTrigger(MouseTrigger.WheelY, this._zoom);
this._keyboard = new Keyboard()
.setAxis("a", "d", this._rotateAzimuth)
.setAxis("s", "w", this._rotateElevation)
.setAxis("A", "D", this._rotateAzimuth, 4)
.setAxis("S", "W", this._rotateElevation, 2);
}
update()
{
if (!this._enabled) return;
this.position.azimuth += this._rotateAzimuth.value * this.rotateSpeed;
this.position.elevation -= this._rotateElevation.value * this.rotateSpeed;
this.position.elevation = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, this.position.elevation));
this.position.radius *= 1 - this._zoom.value * this.zoomSpeed;
this.position.radius = Math.max(this.minRadius, Math.min(this.maxRadius, this.position.radius));
SphericalCoord.lerp(this._smoothedPosition, this.position, this._smoothedPosition, this.smoothing);
const pos = this.target.position;
this._smoothedPosition.toVec3(Y_AXIS);
vec3.negate(Y_AXIS, Y_AXIS);
vec3.normalize(Y_AXIS, Y_AXIS);
vec3.cross(X_AXIS, Y_AXIS, UP);
vec3.normalize(X_AXIS, X_AXIS);
vec3.cross(Z_AXIS, X_AXIS, Y_AXIS);
vec3.add(pos, pos, this.pivot);
mat4.set(
this.target.matrix,
X_AXIS[0], X_AXIS[1], X_AXIS[2], 0,
Y_AXIS[0], Y_AXIS[1], Y_AXIS[2], 0,
Z_AXIS[0], Z_AXIS[1], Z_AXIS[2], 0,
pos[0], pos[1], pos[2],1
);
// mat4.targetTo(this.target.matrix, this.target.position, this.pivot, UP);
this.target.updateTRS();
}
enable()
{
if (this._enabled) return;
this._input.enable(this._mouse);
this._input.enable(this._keyboard);
this._enabled = true;
}
disable()
{
if (!this._enabled) return;
this._input.disable(this._mouse);
this._input.disable(this._keyboard);
this._enabled = false;
}
get enabled(): boolean
{
return this._enabled;
}
}
