The Joystick specification defines a low-level interface that represents joystick devices (also known as game pads).

Introduction

Some user agents have connected joystick devices (also known as gamepads). These devices are desirable and suited to input for gaming applications, and for "10 foot" user interfaces (presentations, media viewers).

Currently, the only way for a joystick to be used as input would be to emulate mouse or keyboard events, however this would lose information and require additional software outside of the user agent to accomplish emulation.

Meanwhile, native applications are capable of accessing these devices via system APIs.

The Joystick API provides a solution to this problem by specifying interfaces that allow web applications to directly act on joystick data.

This specification references interfaces from a number of other specifications:

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]] as this specification uses that specification and terminology.

A conforming implementation is required to implement all fields defined in this specification.

Joystick Interface

This interface defines an individual joystick device.

readonly attribute string id
An identification string for the joystick. This string identifies the brand or style of connected joystick device. Typically, this will include the USB vendor and a product ID.
readonly attribute long index
The index of the joystick in the DocumentJoysticks. When multiple joysticks are connected to a user agent, indices MUST be assigned on a first-come, first-serve basis, starting at zero. If a joystick is disconnected, previously assigned indices MUST NOT be reassigned to joysticks that continue to be connected. However, if a joystick is disconnected, and subsequently the same or a different joystick is then connected, index entries MUST be reused.
readonly attribute DOMTimeStamp timestamp
Last time the data for this joystick was updated. Timestamp is a monotonically increasing value that allows the author to determine if the axes and button data have been updated from the hardware, relative to a previously saved timestamp.
readonly attribute float[] axes
Array of values for all axes of the joystick. All axis values MUST be linearly normalized to the range [-1.0 .. 1.0]. As appropriate, -1.0 SHOULD correspond to "up" or "left", and 1.0 SHOULD correspond to "down" or "right". Axes that are drawn from a 2D input device SHOULD appear next to each other in the axes array, X then Y. It is RECOMMENDED that axes appear in decreasing order of importance, such that element 0 and 1 typically represent the X and Y axis of a directional stick.
readonly attribute float[] buttons
Array of values for all buttons of the joystick. All button values MUST be linearly normalized to the range [0.0 .. 1.0]. 0.0 MUST mean fully unpressed, and 1.0 MUST mean fully pressed. It is RECOMMENDED that buttons appear in decreasing importance such that the primary button, secondary button, tertiary button, and so on appear as elements 0, 1, 2, ... in the buttons array.
readonly attribute float[] suggestedAxesDeadZone
Array of values that represent suggested amount of input to ignore for corresponding values in the axes array. These values are hardware dependent and reflect tolerances for sampling (sometimes low-quality) analog inputs.
readonly attribute float[] suggestedButtonsDeadZone
Array of values that represent suggested amount of input to ignore for corresponding values in the buttons array. These values are hardware dependent and reflect tolerances for sampling (sometimes low-quality) analog inputs.

DocumentJoysticks Interface

This interface defines a collection of Joysticks. The DocumentJoysticks interface MUST be implemented on the Document object.

readonly attribute Joystick[] joysticks
The currently connected and interacted-with joysticks. Joysticks MUST only appear in the list if they are currently connected to the user agent, and have been interacted with by the user. Otherwise, they MUST not appear in the list to avoid a malicious page from fingerprinting the user based on connected devices.

JoystickEvent Interface

readonly attribute Joystick joystick
The single joystick attribute provides access to the associated joystick data for this event.

Usage Examples

The example below demonstrates typical access to joysticks. Note the relationship with the WindowAnimationTiming [[!ANIMATION-TIMING]] interface.


function runAnimation()
{
    window.requestAnimationFrame(runAnimation);

    for (var i = 0; i < document.joysticks.length; ++i)
    {
        var joy = document.joysticks[i];
        // todo; simple demo of displaying joy.axes and joy.buttons
    }
}

window.requestAnimationFrame(runAnimation);

              

Coordination with WindowAnimationTiming

Interactive applications will typically be using the WindowAnimationTiming interface to drive animation, and will want coordinate animation with user joystick input. As such, the joystick data should be polled as closely as possible to immediately before the animation callbacks are executed, and with frequency matching that of the animation. That is, if the animation callbacks are running at 60Hz, the joystick inputs should also be sampled at that rate.

The joystickconnected event

A user agent MUST dispatch this event type to indicate the user has connected a joystick. If a joystick was already connected when the page was loaded, the joystickconnected event will be dispatched when the user presses a button or moves an axis.

The joystickdisconnected event

When a joystick is disconnected from the user agent, if the user agent has previously dispatched a joystickconnected event, a joystickdisconnected event MUST be dispatched.

Other events

More discussion needed, on whether to include or exclude axis and button changed events, and whether to roll them more together (joystickchanged?), separate somewhat (joystickaxischanged?), or separate by individual axis and button.

Acknowledgements

Many have made contributions in code, comments, or documentation:

Please let me know if I have inadvertently omitted your name.