Input
Unified input manager that aggregates mouse, keyboard, gamepad, and touchpad into a single high-level API. Handles device detection, preference switching, pointer locking, fullscreen, and provides per-frame state queries (is down, just pressed, just released).
import { Input } from "@jolly-pixel/engine";
const canvas = document.querySelector("canvas")!;
const input = new Input(canvas);
input.connect();
function gameLoop() {
input.update();
if (input.wasKeyJustPressed("Space")) {
console.log("Jump!");
}
if (input.isMouseButtonDown("left")) {
const delta = input.getMouseDelta(true);
console.log("Dragging", delta.x, delta.y);
}
requestAnimationFrame(gameLoop);
}
gameLoop();Device APIs
Each device is available as a property on the Input instance (input.mouse, input.keyboard, input.gamepad, input.touchpad, input.screen) and can also be used standalone.
Constructor
new Input(canvas, options?)
interface InputOptions {
// Emit an "exit" event on window.onbeforeunload
enableOnExit?: boolean;
// Custom window adapter (defaults to BrowserWindowAdapter)
windowAdapter?: WindowAdapter;
}
new Input(canvas: HTMLCanvasElement, options?: InputOptions);Lifecycle
connect()
Register all DOM event listeners for every device (mouse, keyboard, gamepad, touchpad, screen). Must be called before update().
disconnect()
Remove all DOM event listeners. Call when tearing down the game loop.
update()
Poll every device and flush per-frame state (just pressed / just released). Call once per frame before querying input state.
Events
Input extends EventEmitter and emits the following events:
type InputDevicePreference = "default" | "gamepad";
type InputEvents = {
// Fired on window.onbeforeunload (requires enableOnExit)
exit: [];
// Fired when active device switches between "default" (mouse + keyboard) and "gamepad"
devicePreferenceChange: [preference: InputDevicePreference];
};Decorator
Input.listen(type)
Method decorator that registers a behavior method as a listener for an input event. Used with reflect-metadata.
class PlayerBehavior {
@Input.listen("keyboard.down")
onKeyDown() {
// ...
}
}Available listener types:
mouse.downmouse.upmouse.movemouse.wheelmouse.lockStateChangekeyboard.downkeyboard.upkeyboard.presskeyboard.<KeyCode>gamepad.connectgamepad.disconnecttouchpad.starttouchpad.movetouchpad.endscreen.stateChangeinput.devicePreferenceChangeinput.exit
Screen
enterFullscreen()
Request fullscreen on the canvas element.
exitFullscreen()
Exit fullscreen mode.
getScreenSize(): Vector2
Returns canvas client dimensions as a THREE.Vector2.
getScreenBounds(): { left, right, top, bottom }
Returns screen bounds centered at origin (useful for orthographic cameras).
Mouse
getMousePosition(): Vector2
Returns mouse position normalized to [-1, 1] on both axes.
getMouseWorldPosition(): Vector2
Returns mouse position in world-space pixels, centered at origin.
getMouseDelta(normalizeWithSize?): Vector2
Returns mouse movement delta since last frame. When normalizeWithSize is true, the delta is divided by half the canvas dimensions.
isMouseMoving(): boolean
Returns true if the mouse moved during the current frame.
isMouseButtonDown(action): boolean
Returns true while the given button is held.
wasMouseButtonJustPressed(action): boolean
Returns true only on the frame the button was pressed.
wasMouseButtonJustReleased(action): boolean
Returns true only on the frame the button was released.
lockMouse() / unlockMouse()
Request or release pointer lock on the canvas.
getMouseVisible(): boolean / setMouseVisible(visible)
Get or set cursor visibility.
type InputMouseAction =
| "left" | "middle" | "right" | "back" | "forward"
| number
| "ANY" | "NONE";Keyboard
isKeyDown(key): boolean
Returns true while the key is held.
wasKeyJustPressed(key): boolean
Returns true only on the frame the key was pressed.
wasKeyJustReleased(key): boolean
Returns true only on the frame the key was released.
wasKeyJustAutoRepeated(key): boolean
Returns true on auto-repeat frames (held key).
getTextEntered(): string
Returns the character typed during the current frame (if any).
type InputKeyboardAction = KeyCode | "ANY" | "NONE";Touchpad
isTouchDown(index): boolean
Returns true while the touch point is active.
wasTouchStarted(index): boolean
Returns true on the frame the touch began.
wasTouchEnded(index): boolean
Returns true on the frame the touch ended.
getTouchPosition(index): Vector2
Returns touch position normalized to [-1, 1].
isTouchpadAvailable(): boolean
Returns true if the device supports touch events.
Gamepad
isGamepadButtonDown(gamepad, button): boolean
Returns true while the button is held.
wasGamepadButtonJustPressed(gamepad, button): boolean
Returns true only on the frame the button was pressed.
wasGamepadButtonJustReleased(gamepad, button): boolean
Returns true only on the frame the button was released.
getGamepadButtonValue(gamepad, button): number
Returns the analog value of a button (0 to 1).
getGamepadAxisValue(gamepad, axis): number
Returns the current axis value (-1 to 1).
wasGamepadAxisJustPressed(gamepad, axis, options?): boolean
Returns true when an axis crosses the dead zone threshold.
interface GamepadAxisPressOptions {
// Check positive direction instead of negative
positive?: boolean;
// Include auto-repeat frames
autoRepeat?: boolean;
}wasGamepadAxisJustReleased(gamepad, axis, options?): boolean
Returns true when an axis returns inside the dead zone.
setGamepadAxisDeadZone(deadZone) / getGamepadAxisDeadZone(): number
Set or get the dead zone threshold for all axes.
type GamepadIndex = 0 | 1 | 2 | 3;
type GamepadButton =
| "A" | "B" | "X" | "Y"
| "LeftBumper" | "RightBumper" | "LeftTrigger" | "RightTrigger"
| "Select" | "Start"
| "LeftStick" | "RightStick"
| "DPadUp" | "DPadDown" | "DPadLeft" | "DPadRight"
| "Home"
| number;
type GamepadAxis =
| "LeftStickX" | "LeftStickY"
| "RightStickX" | "RightStickY"
| number;Misc
vibrate(pattern)
Trigger device vibration via navigator.vibrate().
getDevicePreference(): InputDevicePreference
Returns "default" (mouse + keyboard) or "gamepad" based on which device was last active.