API reference

Every public class, method, and event in @codexo/exojs. Generated from source.

C

classInputSystem

@codexo/exojs / input / stable

Owns the unified input pipeline for an Application: keyboard events, pointer (mouse/touch/pen) events with multi-touch slot management, gamepad polling with mapping detection, mouse-wheel events, canvas-focus tracking, and high-level gesture recognition (pinch / rotate / long-press). All raw inputs are written into a shared `Float32Array` channel buffer. Bind input listeners via the onTrigger / onActive / onStart / onStop factory methods (or via Gamepad.onTrigger-style methods on individual pads), or subscribe to the signal-style notifications (`onKeyDown`, `onPointerDown`, `onGamepadConnected`, `onAnyGamepadButtonDown`, ...). Driven each frame by Application.update's internal prepare stage (first, ahead of interaction/audio/tweens/rendering); constructed automatically - you do not instantiate this class yourself.

9
props
11
methods
23
events
Import
import { InputSystem } from '@codexo/exojs'

Owns the unified input pipeline for an Application: keyboard events, pointer (mouse/touch/pen) events with multi-touch slot management, gamepad polling with mapping detection, mouse-wheel events, canvas-focus tracking, and high-level gesture recognition (pinch / rotate / long-press).

All raw inputs are written into a shared `Float32Array` channel buffer. Bind input listeners via the onTrigger / onActive / onStart / onStop factory methods (or via Gamepad.onTrigger-style methods on individual pads), or subscribe to the signal-style notifications (`onKeyDown`, `onPointerDown`, `onGamepadConnected`, `onAnyGamepadButtonDown`, ...).

Driven each frame by Application.update's internal prepare stage (first, ahead of interaction/audio/tweens/rendering); constructed automatically - you do not instantiate this class yourself.

Constructors1
Methods11
Start updating map every frame for the application's lifetime. Attaching a map that is already attached elsewhere moves it here. Call ActionMap.detach to stop, or use scene.inputs.attach for a map that should die with its scene. While attached, the keyboard controls the map's actions bind have their browser default suppressed, exactly as a direct on* binding does, and rebinding moves that suppression with them. Reading a key without binding it leaves its default alone.
destroy(): void
Direct accessor for a single gamepad slot. Equivalent to app.input.gamepads[slot] but reads more clearly at call sites.
Returns the canvas-relative position of the primary pointer (isPrimary = true), or the first non-cancelled pointer if no primary is found. Returns null when no active pointer is present. Used by debug layers to show cursor info.
lockPointer(): void
Ask the host to lock the pointer to the drawing surface, hiding the cursor and reporting motion as relative deltas. Best-effort and asynchronous. Hosts grant a lock only from a user gesture - call this from a press or key handler, not from a frame update - and may deny it outright; wait for InputSystem.onPointerLockChange rather than assuming the lock is in place when this returns.
Register a callback fired every frame while any of channels is active. The callback is optional: with none, this just creates a binding, which is the idiomatic way to poll an input per frame - read InputBinding.active / InputBinding.value in your own update() instead of tracking held-state in a callback.
SystemMethods.preFrame phase, registered on app.systems by the Application at SystemOrder.CoreInput - ahead of every other core system, so this frame's snapshot is current before anything simulates. Polls the gamepad API, drains queued keyboard/pointer/wheel deltas into the channel buffer, fires the corresponding Signals, then evaluates each registered binding. delta is also the clock a pending long-press matures on - see GestureRecognizer.update.
unlockPointer(): void
Release a lock this surface holds. No-op while it holds none.
Properties9
canvasFocused: boolean
Whether keyboard input is currently routed to this application. Keyboard and wheel events are gated on it. A focused text field keeps it true: its platform transport takes host focus away from the canvas element, but focus never leaves the application.
connectedGamepadCount: number
Number of slots currently occupied by a physical gamepad.
hasGamepad: boolean
true when at least one slot is occupied by a physical gamepad.
pointerLocked: boolean
Whether the host currently routes pointer input to the surface exclusively. While locked, pointers report no meaningful position: Pointer.position and Pointer.delta stand still and Pointer.movement carries the motion instead.
pointersInCanvas: boolean
Events23
Fires whenever the platform's single native contextmenu event fires - right-click, the keyboard context-menu key, Shift+F10, and (on most touch browsers) a long-press all funnel through that one event, so there is exactly one source to listen to here regardless of which of them the user used. Independent of whether the browser's own menu was suppressed - see InputApplicationOptions.allowNativeContextMenu. This is the engine-wide fallback: it fires unconditionally, with no regard for the scene graph, so it is the right place for an application-level menu that should appear no matter what - or nothing - was under the pointer. Fires even when the request has no pointer to attribute itself to (a keyboard-only session that has never moved a mouse) - see ContextMenuRequest's doc comment for why the request carries its own coordinates instead of forcing the contract onto a Pointer. A request over a specific interactive node additionally bubbles as a scene-graph contextmenu InteractionEvent (see InteractionSystem), which only fires when a node is actually hit and can be stopped with InteractionEvent.stopPropagation; use that one for a per-node menu instead. Do not confuse either with GestureRecognizer.onLongPress - a separate, purely informational touch/mouse-hold signal that never triggers this one on its own.
Fires once per physical key press with the key's channel. OS auto-repeat while a key is held does not fire again, so this matches the down transition an action's pressed reports rather than diverging from it. Read the channel buffer (or an action) to know a key is still held.
Fires when a pointer has been held without significant movement for ≥ 500 ms of ENGINE time - frame deltas summed across the frames this system actually ran, not wall-clock time. A hold therefore freezes while the active scene is paused and while the application is stopped, and resumes from where it left off; it never completes in the background.
Fires once per frame in which the wheel moved, with the accumulated offset for that frame. deltaY is the usual scroll axis; deltaX carries horizontal wheels and trackpad swipes. Both are normalized out of the event's deltaMode, so a line- or page-mode wheel arrives in the same units as a pixel-mode one. The values are plain numbers rather than a Vector on purpose: the offset is reset to zero right after dispatch, so a shared instance would be stale by the time a listener that kept it read it again.
Fires on every two-touch-pointer move where the distance between them changed. scale > 1 = spreading, < 1 = pinching; the center is the midpoint between the two pointers, in the same coordinate space as Pointer.position. The center arrives as two numbers rather than a Vector on purpose - a shared instance would be overwritten by the next gesture entry in the same frame.
Every pointer signal below carries the phase's own (x, y) explicitly, in design pixels, alongside the pointer - an immutable snapshot rather than a temporary rewind of Pointer.position. pointer.x/ pointer.y always read the pointer's live, current position instead (see Pointer.position's doc comment); use the x/y parameters for the position a specific phase actually happened at.
Fires whenever InputSystem.pointerLocked changes, including a lock the user ended themselves with Escape - which every host allows and no application can prevent, so this is the only reliable place to notice it.
Fires on every two-touch-pointer move where the angle between them changed. angleDelta is in radians; the center is the midpoint between the two pointers - see onPinch for why it is not a Vector.
Source