diff --git a/extensions.html b/extensions.html index a4448e1..af31e63 100644 --- a/extensions.html +++ b/extensions.html @@ -1,442 +1,442 @@ - - -
-[gamepad]
. See
- Bugzilla for this specification's open bugs.
- - The Gamepad API provides a tightly scoped interface to gamepad devices - and is focused on the most common elements of those devices, namely - axis and button inputs. It specifically excludes support for more - complex devices (e.g., those that do motion tracking or haptic - feedback). -
-- However, some uses of gamepads (e.g., those paired with Virtual Reality - headsets) rely heavily on those more advanced features. This - supplemetary spec describes extensions to the base API to accommodate - those use cases. If they prove to be broadly useful, the hope is that - they will be eventually merged into the main spec. -
-- This enum defines the set of possible hands a gamepad may be held by. -
-- enum GamepadHand { - "", /* unknown, both hands, or not applicable */ - "left", - "right" - }; --
- This interface defines the gamepad's position, orientation, velocity, - and acceleration. -
-- [Exposed=Window] - interface GamepadPose { - readonly attribute boolean hasOrientation; - readonly attribute boolean hasPosition; - - readonly attribute Float32Array? position; - readonly attribute Float32Array? linearVelocity; - readonly attribute Float32Array? linearAcceleration; - readonly attribute Float32Array? orientation; - readonly attribute Float32Array? angularVelocity; - readonly attribute Float32Array? angularAcceleration; - }; --
hasOrientation
attribute MUST return whether the
- gamepad is capable of tracking its orientation.
- hasPosition
attribute MUST return whether the
- gamepad is capable of tracking its position.
- - Position of the gamepad as a 3D vector, given in meters from an - origin point, which is determined by the gamepad hardware and MAY - be the position of the gamepad when first polled if no other - reference point is available. The coordinate system uses these axis - definitions, assuming the user is holding the gamepad in the - forward orientation: -
-
- MUST be null
if the gamepad is incapable of providing
- positional data. When not null
, MUST be a
- three-element array.
-
null
if the sensor is incapable of providing linear
- velocity. When not null
, MUST be a three-element array.
- null
if the sensor is incapable of providing linear
- acceleration. When not null
, MUST be a three-element
- array.
- [0, 0, 0, 1]
is considered to be forward
.
- The forward direction MUST be determined by the gamepad hardware. The
- forward direction MAY be the orientation of the hardware when it was
- first polled if no other reference orientation is available. If the
- sensor is incapable of providing orientation data, the orientation
- MUST be null
. When not null
, the
- orientation
MUST be a four-element array.
- null
if the sensor is incapable of providing angular
- velocity. When not null
, the
- angularVelocity
MUST be a three-element array.
- null
if the sensor is incapable of providing angular
- acceleration. When not null
,
- angularAcceleration
MUST be a three-element array.
- - This partial interface supplements the Gamepad interface described in - the main Gamepad spec. -
-- partial interface Gamepad { - readonly attribute GamepadHand hand; - readonly attribute FrozenArray<GamepadHapticActuator> hapticActuators; - readonly attribute GamepadPose? pose; - }; --
- Instances of {{Gamepad}} are created with the internal slots described - in the following table: -
-- Internal slot - | -- Initial value - | -- Description (non-normative) - | -
---|---|---|
- [[\hand]] - | -- `undefined` - | -- Indicates the hand the controller is held in. - | -
- [[\hapticActuators]] - | -- `undefined` - | -- List of all the haptic actuators in the gamepad. - | -
- [[\pose]] - | -- `null` - | -- The current pose of the gamepad. - | -
- This section supplements the Receiving - inputs section of the main Gamepad specification. -
-- This section supplements the Constructing - a `Gamepad` section of the main Gamepad specification. -
-- This partial interface supplements the {{GamepadHapticActuator}} - interface described in the main Gamepad spec. -
-- [Exposed=Window] - partial interface GamepadHapticActuator { - Promise<boolean> pulse(double value, double duration); - }; --
- {{GamepadHapticActuator/pulse()}} applies a |value:double| to the
- actuator for duration milliseconds. The value
- passed to pulse()
is clamped to limits defined by the
- actuator type. The returned Promise will resolve true
- once the pulse has completed.
-
- Repeated calls to pulse()
override the previous
- values.
-
[gamepad]
. See
+ Bugzilla for this specification's open bugs.
+ + The Gamepad API provides a tightly scoped interface to gamepad devices + and is focused on the most common elements of those devices, namely + axis and button inputs. It specifically excludes support for more + complex devices (e.g., those that do motion tracking or haptic + feedback). +
++ However, some uses of gamepads (e.g., those paired with Virtual Reality + headsets) rely heavily on those more advanced features. This + supplemetary spec describes extensions to the base API to accommodate + those use cases. If they prove to be broadly useful, the hope is that + they will be eventually merged into the main spec. +
++ This enum defines the set of possible hands a gamepad may be held by. +
++ enum GamepadHand { + "", /* unknown, both hands, or not applicable */ + "left", + "right" + }; ++
+ This interface defines the gamepad's position, orientation, velocity, + and acceleration. +
++ [Exposed=Window] + interface GamepadPose { + readonly attribute boolean hasOrientation; + readonly attribute boolean hasPosition; + + readonly attribute Float32Array? position; + readonly attribute Float32Array? linearVelocity; + readonly attribute Float32Array? linearAcceleration; + readonly attribute Float32Array? orientation; + readonly attribute Float32Array? angularVelocity; + readonly attribute Float32Array? angularAcceleration; + }; ++
hasOrientation
attribute MUST return whether the
+ gamepad is capable of tracking its orientation.
+ hasPosition
attribute MUST return whether the
+ gamepad is capable of tracking its position.
+ + Position of the gamepad as a 3D vector, given in meters from an + origin point, which is determined by the gamepad hardware and MAY + be the position of the gamepad when first polled if no other + reference point is available. The coordinate system uses these axis + definitions, assuming the user is holding the gamepad in the + forward orientation: +
+
+ MUST be null
if the gamepad is incapable of providing
+ positional data. When not null
, MUST be a
+ three-element array.
+
null
if the sensor is incapable of providing linear
+ velocity. When not null
, MUST be a three-element array.
+ null
if the sensor is incapable of providing linear
+ acceleration. When not null
, MUST be a three-element
+ array.
+ [0, 0, 0, 1]
is considered to be forward
.
+ The forward direction MUST be determined by the gamepad hardware. The
+ forward direction MAY be the orientation of the hardware when it was
+ first polled if no other reference orientation is available. If the
+ sensor is incapable of providing orientation data, the orientation
+ MUST be null
. When not null
, the
+ orientation
MUST be a four-element array.
+ null
if the sensor is incapable of providing angular
+ velocity. When not null
, the
+ angularVelocity
MUST be a three-element array.
+ null
if the sensor is incapable of providing angular
+ acceleration. When not null
,
+ angularAcceleration
MUST be a three-element array.
+ + This partial interface supplements the Gamepad interface described in + the main Gamepad spec. +
++ partial interface Gamepad { + readonly attribute GamepadHand hand; + readonly attribute FrozenArray<GamepadHapticActuator> hapticActuators; + readonly attribute GamepadPose? pose; + }; ++
+ Instances of {{Gamepad}} are created with the internal slots described + in the following table: +
++ Internal slot + | ++ Initial value + | ++ Description (non-normative) + | +
---|---|---|
+ [[\hand]] + | ++ `undefined` + | ++ Indicates the hand the controller is held in. + | +
+ [[\hapticActuators]] + | ++ `undefined` + | ++ List of all the haptic actuators in the gamepad. + | +
+ [[\pose]] + | ++ `null` + | ++ The current pose of the gamepad. + | +
+ This section supplements the Receiving + inputs section of the main Gamepad specification. +
++ This section supplements the Constructing + a `Gamepad` section of the main Gamepad specification. +
++ This partial interface supplements the {{GamepadHapticActuator}} + interface described in the main Gamepad spec. +
++ [Exposed=Window] + partial interface GamepadHapticActuator { + Promise<boolean> pulse(double value, double duration); + }; ++
+ {{GamepadHapticActuator/pulse()}} applies a |value:double| to the
+ actuator for duration milliseconds. The value
+ passed to pulse()
is clamped to limits defined by the
+ actuator type. The returned Promise will resolve true
+ once the pulse has completed.
+
+ Repeated calls to pulse()
override the previous
+ values.
+
- The Gamepad specification defines a low-level interface that represents - gamepad devices. -
-- This is a work in progress. -
-- Some [=user agent=]s have connected gamepad devices. 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 gamepad 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 Gamepad API provides a solution to this problem by specifying - interfaces that allow web applications to directly act on gamepad data. -
-- Interfacing with external devices designed to control games has the - potential to become large and intractable if approached in full - generality. In this specification we explicitly choose to narrow scope - to provide a useful subset of functionality that can be widely - implemented and broadly useful. -
-- Specifically, we choose to only support the functionality required to - support gamepads. Support for gamepads requires two input types: - buttons and axes. Both buttons and axes are reported as analog values, - buttons ranging from [0..1], and axes ranging from [-1..1]. -
-- While the primary goal is support for gamepad devices, supporting these - two types of analog inputs allows support for other similar devices - common to current gaming systems including joysticks, driving wheels, - pedals, and accelerometers. As such, the name "gamepad" is exemplary - rather than trying to be a generic name for the entire set of devices - addressed by this specification. -
-- We specifically exclude support for more complex devices that may also - be used in some gaming contexts, including those that that do motion - sensing, depth sensing, video analysis, gesture recognition, and so on. -
-- This interface defines an individual gamepad device. -
-- [Exposed=Window] - interface Gamepad { - readonly attribute DOMString id; - readonly attribute long index; - readonly attribute boolean connected; - readonly attribute DOMHighResTimeStamp timestamp; - readonly attribute GamepadMappingType mapping; - readonly attribute FrozenArray<double> axes; - readonly attribute FrozenArray<GamepadButton> buttons; - readonly attribute FrozenArray<GamepadTouch>? touchEvents; - [SameObject] readonly attribute GamepadHapticActuator vibrationActuator; - }; --
- The algorithms used to communicate with the system typically complete - asynchronously, queuing work on the gamepad task source. -
-- Instances of {{Gamepad}} are created with the internal slots described - in the following table: -
-- Internal slot - | -- Initial value - | -- Description (non-normative) - | -
---|---|---|
- [[\connected]] - | -- `false` - | -- A flag indicating that the device is connected to the system - | -
- [[\timestamp]] - | -- undefined - | -- The last time data for this {{Gamepad}} was updated - | -
- [[\axes]] - | -- An empty [=sequence=] - | -- A [=sequence=] of {{double}} values representing the current state - of axes exposed by this device - | -
- [[\buttons]] - | -- An empty [=sequence=] - | -- A [=sequence=] of {{GamepadButton}} objects representing the - current state of buttons exposed by this device - | -
- [[\exposed]] - | -- `false` - | -- A flag indicating that the {{Gamepad}} object has been exposed to - script - | -
- [[\axisMapping]] - | -- An empty [=ordered map=] - | -- Mapping from unmapped axis index to an index in the - {{Gamepad/axes}} array - | -
- [[\axisMinimums]] - | -- An empty [=list=] - | -- A [=list=] containing the minimum logical value for each axis - | -
- [[\axisMaximums]] - | -- An empty [=list=] - | -- A [=list=] containing the maximum logical value for each axis - | -
- [[\buttonMapping]] - | -- An empty [=ordered map=] - | -- Mapping from unmapped button index to an index in the - {{Gamepad/buttons}} array - | -
- [[\buttonMinimums]] - | -- An empty [=list=] - | -- A [=list=] containing the minimum logical value for each button. - | -
- [[\buttonMaximums]] - | -- An empty [=list=] - | -- A [=list=] containing the maximum logical value for each button - | -
- [[\touchEvents]] - | -- `null` - | -- List of generated touch events. - | -
- [[\vibrationActuator]] - | -- undefined - | -- A {{GamepadHapticActuator}} object capable of generating a haptic - effect that vibrates the entire gamepad - | -
- An identification string for the gamepad. This string identifies - the brand or style of connected gamepad device. -
-- The exact format of the {{Gamepad/id}} string is left unspecified. - It is RECOMMENDED that the [=user agent=] select a string that - identifies the product without uniquely identifying the device. For - example, a USB gamepad may be identified by its `idVendor` and - `idProduct` values. Unique identifiers like serial numbers or - Bluetooth device addresses MUST NOT be included in the - {{Gamepad/id}} string. -
-- Indicates whether the physical device represented by this object is - still connected to the system. When a gamepad becomes unavailable, - whether by being physically disconnected, powered off or otherwise - unusable, the {{Gamepad/connected}} attribute MUST be set to - `false`. -
-- The {{Gamepad/connected}} getter steps are: -
-- The {{Gamepad/timestamp}} allows the author to determine the last - time the {{Gamepad/axes}} or {{Gamepad/buttons}} attribute for this - gamepad was updated. The value MUST be set to the [=current high - resolution time=] each time the system [=receives new button or - axis input values=] from the device. If no data has been received - from the hardware, {{Gamepad/timestamp}} MUST be the [=current high - resolution time=] at the time when the {{Gamepad}} was first made - available to script. -
-- [=User agent=]s SHOULD set a minimum resolution of |gamepad|'s - {{Gamepad/timestamp}} attribute to 5 microseconds, following - [[HR-TIME]]'s clock resolution recommendation. -
-- The {{Gamepad/timestamp}} getter steps are: -
-- The mapping in use for this device. If the user agent has knowledge - of the layout of the device, then it SHOULD indicate that a mapping - is in use by setting {{Gamepad/mapping}} to the corresponding - {{GamepadMappingType}} value. -
-- To select a mapping for a - gamepad device, run the following steps: -
-- Array of values for all axes of the gamepad. All axis values MUST - be linearly normalized to the range [-1.0 .. 1.0]. If the - controller is perpendicular to the ground with the directional - stick pointing up, -1.0 SHOULD correspond to "forward" or "left", - and 1.0 SHOULD correspond to "backward" 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. The same object - MUST be returned until the [=user agent=] needs to return different - values (or values in a different order). -
-- The {{Gamepad/axes}} getter steps are: -
-- Array of button states for all buttons of the gamepad. 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. The same - object MUST be returned until the [=user agent=] needs to return - different values (or values in a different order). -
-- The {{Gamepad/buttons}} getter steps are: -
-- A list of {{GamepadTouch}} events generated from all touch - surfaces. If the device does not support touch events, MUST be set - to `null`. -
-- The {{Gamepad/touchEvents}} getter steps are: -
-- A {{GamepadHapticActuator}} object that represents the device's - primary vibration actuator. -
-- The {{Gamepad/vibrationActuator}} getter steps are: -
-- When the system receives new button or axis input values, - run the following steps: -
-- To update gamepad state for |gamepad:Gamepad|, run the - following steps: -
-- To map and normalize axes for |gamepad:Gamepad|, run the - following steps: -
-- To map and normalize buttons for |gamepad:Gamepad|, run - the following steps: -
-- If the button has a digital switch to indicate a pure pressed - or released state, set |button|.{{GamepadButton/[[pressed]]}} - to `true` if the button is pressed or `false` if it is not - pressed. -
-- Otherwise, set |button|.{{GamepadButton/[[pressed]]}} to - `true` if the value is above the [=button press threshold=] - or `false` if it is not above the threshold. -
-- If the button is capable of detecting touch, set - |button|.{{GamepadButton/[[touched]]}} to `true` if the - button is currently being touched. -
-- Otherwise, set |button|.{{GamepadButton/[[touched]]}} to - |button|.{{GamepadButton/[[pressed]]}}. -
-- When the user agent modifies the list of |active touch points| for a - touch surface by adding touch points, removing touch points, or - updating the values of existing touch points, update - touchEvents by running the following steps: -
-- If the Gamepad has multiple touch surfaces the touch - id will be unique across surfaces. -
-- |position|[0] should be set to the device X coordinate - relative to the device [=touch surface=] and normalized - to [-1.0,1.0] where -1.0 is the leftmost coordinate and - 1.0 is the rightmost coordinate. -
-- `position[0] = (2.0 * touchData.x / surfaceDimensions[0]) - - 1` -
-- |position|[1] should be set to the device Y coordinate - relative to the device [=touch surface=] and normalized - to [-1.0,1.0] where -1.0 is the topmost coordinate and - 1.0 is the bottommost coordinate. -
-- `position[1] = (2.0 * touchData.y / surfaceDimensions[1]) - - 1` -
-- A new `Gamepad` representing a connected gamepad device is - constructed by performing the following steps: -
-- To select an unused - gamepad index for |gamepad:Gamepad|, run the following steps: -
-- To initialize axes for - |gamepad:Gamepad|, run the following steps: -
-- Otherwise: -
-- Otherwise, [=list/append=] |rawInputIndex| to - |unmappedInputList|. -
-- To initialize buttons for a - gamepad, run the following steps: -
-- Otherwise: -
-- Otherwise, [=list/append=] |rawInputIndex| to - |unmappedInputList|. -
-- To initialize - touchEvents for a gamepad, run the following steps: -
-
- null
.
- - This interface defines the state of an individual button on a gamepad - device. -
-- [Exposed=Window] - interface GamepadButton { - readonly attribute boolean pressed; - readonly attribute boolean touched; - readonly attribute double value; - }; --
- Instances of {{GamepadButton}} are created with the internal slots - described in the following table: -
-- Internal slot - | -- Initial value - | -- Description (non-normative) - | -
---|---|---|
- [[\pressed]] - | -- `false` - | -- A flag indicating that the button is pressed - | -
- [[\touched]] - | -- `false` - | -- A flag indicating that the button is touched - | -
- [[\value]] - | -- 0.0 - | -- A {{double}} representing the button value scaled to the range [0.0 - .. 1.0] - | -
- The pressed state of the button. This property MUST be `true` if - the button is currently pressed, and `false` if it is not pressed. - For buttons which do not have a digital switch to indicate a pure - pressed or released state, the [=user agent=] MUST choose a - button press threshold to indicate the button as pressed - when its value is above a certain amount. If the platform API gives - a recommended value, the user agent SHOULD use that. In other - cases, the user agent SHOULD choose some other reasonable value. -
-- The {{GamepadButton/pressed}} getter steps are: -
-- The touched state of the button. If the button is capable of - detecting touch, this property MUST be `true` if the button is - currently being touched, and `false` otherwise. If the button is - not capable of detecting touch and is capable of reporting an - analog value, this property MUST be `true` if the value property is - greater than 0, and `false` if the value is 0. If the button is not - capable of detecting touch and can only report a digital value, - this property MUST mirror the {{GamepadButton/pressed}} attribute. -
-- The {{GamepadButton/touched}} getter steps are: -
-- For buttons that have an analog sensor, this property MUST - represent the amount which the button has been pressed. 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. For - buttons without an analog sensor, only the values 0.0 and 1.0 for - fully unpressed and fully pressed respectively, MUST be provided. -
-- The {{GamepadButton/value}} getter steps are: -
-- This interface defines a single touch event on a gamepad device that - supports input. The event consists of a touch id that uniquely - identifies the touch point from the time the input medium (e.g. finger, - stylus, etc) makes contact with the touch device, up to the time the - input medium is no longer making contact with the touch device. -
-- [Exposed=Window, SecureContext] - interface GamepadTouch { - readonly attribute unsigned long touchId; - readonly attribute octet surfaceId; - readonly attribute Float32Array position; - readonly attribute Uint32Array? surfaceDimensions; - }; --
- The user agent is responsible for: -
-null
, MUST be a two-element array.
- - This enum defines the set of known mappings for a Gamepad. -
-- enum GamepadMappingType { - "", - "standard", - "xr-standard", - }; --
- A {{GamepadHapticActuator}} corresponds to a configuration of motors or - other actuators that can apply a force for the purposes of haptic - feedback. -
-- [Exposed=Window] - interface GamepadHapticActuator { - [SameObject] readonly attribute FrozenArray<GamepadHapticEffectType> effects; - Promise<GamepadHapticsResult> playEffect( - GamepadHapticEffectType type, - optional GamepadEffectParameters params = {} - ); - Promise<GamepadHapticsResult> reset(); - }; --
- Instances of {{GamepadHapticActuator}} are created with the internal - slots described in the following table: -
-- Internal slot - | -- Initial value - | -- Description - | -
---|---|---|
- [[\effects]] - | -- An empty [=list=] of {{Gamepad/GamepadHapticEffectType}}. - | -- Represents the effects supported by the actuator. - | -
- [[\playingEffectPromise]] - | -- `null` - | -- The {{Promise}} to play some effect, or `null` if no effect is - playing. - | -
- Array of {{Gamepad/GamepadHapticEffectType}} values representing - all the types of haptic effects that the actuator supports. This - property lists the {{Gamepad/GamepadHapticEffectType}} values that - the actuator supports, unless the [=user agent=] does not support - playing effects of that type. -
-- The {{GamepadHapticActuator/effects}} getter steps are: -
-- The {{GamepadHapticActuator/playEffect()}} method steps, called - with {{GamepadHapticEffectType}} |type:GamepadHapticEffectType| and - {{GamepadEffectParameters}} |params:GamepadEffectParameters |, are: -
-- The {{GamepadHapticActuator/reset()}} method steps are: -
-- A {{GamepadHapticActuator}} can play effects with type - |type:GamepadHapticEffectType| if |type:GamepadHapticEffectType| can be - found in the {{GamepadHapticActuator/[[effects]]}} [=list=]. -
-- To check if an effect with {{GamepadHapticEffectType}} - |type:GamepadHapticEffectType| and {{GamepadEffectParameters}} - |params:GamepadEffectParameters| describes a valid effect, - run the following steps: -
-- To issue a haptic effect on an actuator, the [=user agent=] - MUST send a command to the device to render an effect of - |type:GamepadHapticEffectType| and try to make it use the provided - |params:GamepadEffectParameters|. The [=user agent=] SHOULD use the - provided |playEffectTimestamp:DOMHighResTimestamp| for more precise - playback timing when |params|.{{GamepadEffectParameters/startDelay}} is - not `0.0`. The [=user agent=] MAY modify the effect to increase - compatibility. For example, an effect intended for a rumble motor may - be transformed into a waveform-based effect for a device that supports - waveform haptics but lacks rumble motors. -
-- To stop haptic effects on an actuator, the [=user agent=] - MUST send a command to the device to abort any effects currently being - played. If a haptic effect was interrupted, the actuator SHOULD return - to a motionless state as quickly as possible. -
-- When the |document|'s [=Document/visibility state=] becomes - `"hidden"`, run these steps for each {{GamepadHapticActuator}} - |actuator:GamepadHapticActuator|: -
-- A new - |gamepadHapticActuator:GamepadHapticActuator| representing a - {{Gamepad}}'s primary vibration actuator is constructed by performing - the following steps: -
-- enum GamepadHapticsResult { - "complete", - "preempted" - }; --
- The haptic effected completed playing. -
-- The current effect was stopped or replaced (i.e., "preempted") by - another effect. -
-- The effect type defines how the effect parameters are interpreted by - the actuator. -
-- enum GamepadHapticEffectType { - "dual-rumble", - "trigger-rumble" - }; --
- {{GamepadHapticEffectType/"dual-rumble"}} describes a haptic - configuration with an eccentric rotating mass (ERM) vibration motor - in each handle of a standard gamepad. In this configuration, either - motor is capable of vibrating the whole gamepad. The vibration - effects created by each motor are unequal so that the effects of - each can be combined to create more complex haptic effects. -
-- A {{GamepadHapticEffectType/"dual-rumble"}} effect is a - fixed-duration, constant-intensity vibration effect intended for an - actuator of this type. {{GamepadHapticEffectType/"dual-rumble"}} - effects are defined by {{GamepadEffectParameters/startDelay}}, - {{GamepadEffectParameters/duration}}, - {{GamepadEffectParameters/strongMagnitude}}, and - {{GamepadEffectParameters/weakMagnitude}}, none of which are - required because they default to 0. -
-- {{GamepadEffectParameters/strongMagnitude}} and - {{GamepadEffectParameters/weakMagnitude}} set the intensity levels - for the low-frequency and high-frequency vibrations, normalized to - the range `[0,1]`, defaulting to 0. -
-- Given {{GamepadEffectParameters}} |params:GamepadEffectParameters|, - a valid dual-rumble effect must have a [=valid - effect|valid=] {{GamepadEffectParameters/duration}}, a [=valid - effect|valid=] {{GamepadEffectParameters/startDelay}}, and both the - {{GamepadEffectParameters/strongMagnitude}} and the - {{GamepadEffectParameters/weakMagnitude}} must be in the range - `[0,1]`. -
-- {{GamepadHapticEffectType/"trigger-rumble"}} describes a haptics - configuration with a vibration motor in each of the bottom front - buttons of a [=Standard Gamepad=] (buttons with [=canonical - indices=] 6 and 7) in addition to the two handle motors used for - {{GamepadHapticEffectType/"dual-rumble"}}. These buttons most - commonly take the form of spring-loaded triggers. In this - configuration, either motor is capable of providing localized - haptic feedback on the button's surface. -
-- A {{GamepadHapticEffectType/"trigger-rumble"}} effect is a - fixed-duration, constant-intensity vibration effect intended for an - actuator of this type. {{GamepadHapticEffectType/"trigger-rumble"}} - effects are defined by {{GamepadEffectParameters/startDelay}}, - {{GamepadEffectParameters/duration}}, - {{GamepadEffectParameters/strongMagnitude}}, - {{GamepadEffectParameters/weakMagnitude}}, - {{GamepadEffectParameters/leftTrigger}}, and - {{GamepadEffectParameters/rightTrigger}}, none of which are - required because they default to 0. -
-- {{GamepadEffectParameters/startDelay}}, - {{GamepadEffectParameters/duration}}, - {{GamepadEffectParameters/strongMagnitude}}, - {{GamepadEffectParameters/weakMagnitude}} share the same definition - with {{GamepadHapticEffectType/"dual-rumble"}}. - {{GamepadEffectParameters/leftTrigger}} and - {{GamepadEffectParameters/rightTrigger}}, respectively, set the - intensity levels for the left and right bottom front buttons - vibrations, normalized to the range `[0,1]`, defaulting to 0. -
-- Given {{GamepadEffectParameters}} |params:GamepadEffectParameters|, - a valid trigger-rumble effect must have a [=valid - effect|valid=] {{GamepadEffectParameters/duration}}, a [=valid - effect|valid=] {{GamepadEffectParameters/startDelay}}, and the - {{GamepadEffectParameters/strongMagnitude}}, - {{GamepadEffectParameters/weakMagnitude}}, - {{GamepadEffectParameters/leftTrigger}}, and - {{GamepadEffectParameters/rightTrigger}} must be in the range - `[0,1]`. -
-
- A GamepadEffectParameters
dictionary contains keys for
- parameters used by haptic effects. The meaning of each key is defined
- by the haptic effect, and some keys may be unused.
-
- To mitigate unwanted long-running effects, the [=user agent=] MAY limit - the total effect duration for a [=valid effect=] to some maximum - duration. It is RECOMMENDED that the [=user agent=] use a maximum of 5 - seconds. -
-- dictionary GamepadEffectParameters { - unsigned long long duration = 0; - unsigned long long startDelay = 0; - double strongMagnitude = 0.0; - double weakMagnitude = 0.0; - double leftTrigger = 0.0; - double rightTrigger = 0.0; - }; --
- [Exposed=Window] - partial interface Navigator { - sequence<Gamepad?> getGamepads(); - }; --
- Instances of {{Navigator}} are created with the internal slots - described in the following table: -
-- Internal slot - | -- Initial value - | -- Description (non-normative) - | -
---|---|---|
- [[\hasGamepadGesture]] - | -- `false` - | -- A flag indicating that a [=gamepad user gesture=] has been observed - | -
- [[\gamepads]] - | -- A empty [=sequence=] of {{Gamepad?}} objects - | -- Each {{Gamepad}} present at the index specified by its - {{Gamepad/index}} attribute, or `null` for unassigned indices. - | -
- The gamepad state returned from {{Navigator/getGamepads()}} does not - reflect disconnection or connection until after the - {{gamepaddisconnected}} or {{gamepadconnected}} events have fired. -
-- To mitigate fingerprinting, {{Navigator/getGamepads()}} returns an - empty [=list=] before a [=gamepad user gesture=] has been seen. - [[FINGERPRINTING-GUIDANCE]] -
- -- The {{Navigator/getGamepads()}} method steps are: -
-- A |gamepad:Gamepad| contains a - gamepad user gesture if the current input state indicates that - the user is currently interacting with the gamepad. The [=user - agent=] MUST provide an algorithm to check if the input state - contains a gamepad user gesture. For buttons that support a neutral - default value and have reported a {{GamepadButton/pressed}} value of - `false` at least once, a {{GamepadButton/pressed}} value of `true` - SHOULD be considered interaction. If a button does not support a - neutral default value (for example, a toggle switch), then a - {{GamepadButton/pressed}} value of `true` SHOULD NOT be considered - interaction. If a button has never reported a - {{GamepadButton/pressed}} value of `false` then it SHOULD NOT be - considered interaction. Axis movements SHOULD be considered - interaction if the axis supports a neutral default value, the current - displacement from neutral is greater than a threshold chosen by the - [=user agent=], and the axis has reported a value below the threshold - at least once. If an axis does not support a neutral default value - (for example, an axis for a joystick that does not self-center), or - an axis has never reported a value below the axis gesture threshold, - then the axis SHOULD NOT be considered when checking for interaction. - The axis gesture threshold SHOULD be large enough that random jitter - is not considered interaction. -
-- [Exposed=Window] - - interface GamepadEvent: Event { - constructor(DOMString type, GamepadEventInit eventInitDict); - [SameObject] readonly attribute Gamepad gamepad; - }; --
- dictionary GamepadEventInit : EventInit { - required Gamepad gamepad; - }; --
- Each device manufacturer creates many different products and each has - unique styles and layouts of buttons and axes. It is intended that the - [=user agent=] support as many of these as possible. -
-- Additionally there are de facto standard layouts that have - been made popular by game consoles. When the [=user agent=] recognizes - the attached device, it is RECOMMENDED that it be remapped to a - canonical ordering when possible. Devices that are not recognized - should still be exposed in their raw form. -
-- There is currently one canonical layout, the Standard - Gamepad. When remapping, the indices in {{Gamepad/axes}} and - {{Gamepad/buttons}} should correspond as closely as possible to the - physical locations in the diagram below. Additionally, - {{Gamepad/mapping}} SHOULD be set to {{GamepadMappingType/"standard"}}. -
-- The [=Standard Gamepad=] buttons are laid out in a left cluster of four - buttons, a right cluster of four buttons, a center cluster of three - buttons, and a pair of front facing buttons on the left and right side - of the gamepad. The four axes of the "Standard Gamepad" are associated - with a pair of analog sticks, one on the left and one on the right. The - following table describes the buttons/axes and their physical - locations. -
-- An axis input represents a Standard Gamepad axis if it - reports the input value for a thumbstick axis, the thumbstick is - located in approximately the same location as the corresponding - [=Standard Gamepad=] thumbstick, and the orientation of the axis - (up-down or left-right) matches the orientation of the [=Standard - Gamepad=] axis. If there are multiple axes that represent the same - [=Standard Gamepad=] axis, then the [=user agent=] SHOULD select one to - be the [=Standard Gamepad=] axis and assign a different index to the - other axis. -
-- A button input represents a Standard Gamepad button if it - reports the input value for a button or trigger, and the button or - trigger is located in approximately the same location as the - corresponding [=Standard Gamepad=] button. -
-- If an axis or button input represents a [=Standard Gamepad=] axis or - button, then its canonical index - is the index of the corresponding [=Standard Gamepad=] axis or button. -
-- Type - | -- Index - | -- Location - | -
---|---|---|
- Button - | -- 0 - | -- Bottom button in right cluster - | -
- 1 - | -- Right button in right cluster - | -|
- 2 - | -- Left button in right cluster - | -|
- 3 - | -- Top button in right cluster - | -|
- 4 - | -- Top left front button - | -|
- 5 - | -- Top right front button - | -|
- 6 - | -- Bottom left front button - | -|
- 7 - | -- Bottom right front button - | -|
- 8 - | -- Left button in center cluster - | -|
- 9 - | -- Right button in center cluster - | -|
- 10 - | -- Left stick pressed button - | -|
- 11 - | -- Right stick pressed button - | -|
- 12 - | -- Top button in left cluster - | -|
- 13 - | -- Bottom button in left cluster - | -|
- 14 - | -- Left button in left cluster - | -|
- 15 - | -- Right button in left cluster - | -|
- 16 - | -- Center button in center cluster - | -|
- axes - | -- 0 - | -- Horizontal axis for left stick (negative left/positive right) - | -
- 1 - | -- Vertical axis for left stick (negative up/positive down) - | -|
- 2 - | -- Horizontal axis for right stick (negative left/positive right) - | -|
- 3 - | -- Vertical axis for right stick (negative up/positive down) - | -
- Inspecting the capabilities of {{Gamepad}} objects can be used as a - means of active fingerprinting. The [=user agent=] MAY alter the - device information exposed through the API to reduce the - fingerprinting surface. As an example, an implementation can require - that a {{Gamepad}} object have exactly the number of buttons and axes - defined in the [=Standard Gamepad=] layout even if more or fewer - inputs are present on the connected device. - [[FINGERPRINTING-GUIDANCE]] -
-- The example below demonstrates typical access to gamepads. Note the - relationship with the - {{AnimationFrameProvider/requestAnimationFrame()}} method. -
-- function runAnimation() { - window.requestAnimationFrame(runAnimation); - for (const pad of navigator.getGamepads()) { - // todo; simple demo of displaying pad.axes and pad.buttons - console.log(pad); - } - } - - window.requestAnimationFrame(runAnimation); --
requestAnimationFrame()
- - Interactive applications will typically be using the - {{AnimationFrameProvider/requestAnimationFrame()}} method to drive - animation, and will want coordinate animation with user gamepad - input. As such, the gamepad 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 gamepad inputs should - also be sampled at that rate. -
-- When a gamepad becomes available on the system, run the following - steps: -
-- User agents implementing this specification must provide a new DOM - event, named {{gamepadconnected}}. The corresponding event MUST be of - type {{GamepadEvent}} and MUST fire on the {{Window}} object. -
-- A [=user agent=] MUST dispatch this event type to indicate the user has - connected a gamepad. If a gamepad was already connected when the page - was loaded, the {{gamepadconnected}} event SHOULD be dispatched when - the user presses a button or moves an axis. -
-- When a gamepad becomes unavailable on the system, run the following - steps: -
-- User agents implementing this specification must provide a new DOM - event, named {{gamepaddisconnected}}. The corresponding event MUST be - of type {{GamepadEvent}} and MUST fire on the {{Window}} object. -
-- When a gamepad is disconnected from the [=user agent=], if the [=user - agent=] has previously dispatched a {{gamepadconnected}} event for that - gamepad to a {{Window}}, a {{gamepaddisconnected}} event MUST be - dispatched to that same {{Window}}. -
-- More discussion needed, on whether to include or exclude axis and - button changed events, and whether to roll them more together - (`"gamepadchanged"`?), separate somewhat (`"gamepadaxischanged"`?), or - separate by individual axis and button. -
-- This specification extends the {{WindowEventHandlers}} interface mixin - from HTML to add [=event handler IDL attributes=] to facilitate the - event handler registration. -
-- partial interface mixin WindowEventHandlers { - attribute EventHandler ongamepadconnected; - attribute EventHandler ongamepaddisconnected; - }; --
- This specification defines a policy-controlled feature identified by - the string "gamepad". Its - [=policy-controlled feature/default allowlist=] is [=default - allowlist/*=]. -
-- A [=document=]’s [=Document/permissions policy=] determines whether - any content in that document is allowed to access - {{Navigator/getGamepads()}}. If disabled in any document, no content - in the document will be [=allowed to use=] - {{Navigator/getGamepads()}}, nor will the {{gamepadconnected}} and - {{gamepaddisconnected}} events fire. -
-- touch surface is a surface that can detect contact from a - users fingers and report where on the surface the contact is made. -
-- touch surface enumeration order is an ordered listing of all - the surfaces in a |gamepad|. -
-- active touch point is defined in the Touch - Events - Level 2 specification. -
-- The following people contributed to the development of this document. -
-+ The Gamepad specification defines a low-level interface that represents + gamepad devices. +
++ This is a work in progress. +
++ Some [=user agent=]s have connected gamepad devices. 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 gamepad 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 Gamepad API provides a solution to this problem by specifying + interfaces that allow web applications to directly act on gamepad data. +
++ Interfacing with external devices designed to control games has the + potential to become large and intractable if approached in full + generality. In this specification we explicitly choose to narrow scope + to provide a useful subset of functionality that can be widely + implemented and broadly useful. +
++ Specifically, we choose to only support the functionality required to + support gamepads. Support for gamepads requires two input types: + buttons and axes. Both buttons and axes are reported as analog values, + buttons ranging from [0..1], and axes ranging from [-1..1]. +
++ While the primary goal is support for gamepad devices, supporting these + two types of analog inputs allows support for other similar devices + common to current gaming systems including joysticks, driving wheels, + pedals, and accelerometers. As such, the name "gamepad" is exemplary + rather than trying to be a generic name for the entire set of devices + addressed by this specification. +
++ We specifically exclude support for more complex devices that may also + be used in some gaming contexts, including those that that do motion + sensing, depth sensing, video analysis, gesture recognition, and so on. +
++ This interface defines an individual gamepad device. +
++ [Exposed=Window] + interface Gamepad { + readonly attribute DOMString id; + readonly attribute long index; + readonly attribute boolean connected; + readonly attribute DOMHighResTimeStamp timestamp; + readonly attribute GamepadMappingType mapping; + readonly attribute FrozenArray<double> axes; + readonly attribute FrozenArray<GamepadButton> buttons; + readonly attribute FrozenArray<GamepadTouch>? touchEvents; + [SameObject] readonly attribute GamepadHapticActuator vibrationActuator; + }; ++
+ The algorithms used to communicate with the system typically complete + asynchronously, queuing work on the gamepad task source. +
++ Instances of {{Gamepad}} are created with the internal slots described + in the following table: +
++ Internal slot + | ++ Initial value + | ++ Description (non-normative) + | +
---|---|---|
+ [[\connected]] + | ++ `false` + | ++ A flag indicating that the device is connected to the system + | +
+ [[\timestamp]] + | ++ undefined + | ++ The last time data for this {{Gamepad}} was updated + | +
+ [[\axes]] + | ++ An empty [=sequence=] + | ++ A [=sequence=] of {{double}} values representing the current state + of axes exposed by this device + | +
+ [[\buttons]] + | ++ An empty [=sequence=] + | ++ A [=sequence=] of {{GamepadButton}} objects representing the + current state of buttons exposed by this device + | +
+ [[\exposed]] + | ++ `false` + | ++ A flag indicating that the {{Gamepad}} object has been exposed to + script + | +
+ [[\axisMapping]] + | ++ An empty [=ordered map=] + | ++ Mapping from unmapped axis index to an index in the + {{Gamepad/axes}} array + | +
+ [[\axisMinimums]] + | ++ An empty [=list=] + | ++ A [=list=] containing the minimum logical value for each axis + | +
+ [[\axisMaximums]] + | ++ An empty [=list=] + | ++ A [=list=] containing the maximum logical value for each axis + | +
+ [[\buttonMapping]] + | ++ An empty [=ordered map=] + | ++ Mapping from unmapped button index to an index in the + {{Gamepad/buttons}} array + | +
+ [[\buttonMinimums]] + | ++ An empty [=list=] + | ++ A [=list=] containing the minimum logical value for each button. + | +
+ [[\buttonMaximums]] + | ++ An empty [=list=] + | ++ A [=list=] containing the maximum logical value for each button + | +
+ [[\touchEvents]] + | ++ `null` + | ++ List of generated touch events. + | +
+ [[\vibrationActuator]] + | ++ undefined + | ++ A {{GamepadHapticActuator}} object capable of generating a haptic + effect that vibrates the entire gamepad + | +
+ An identification string for the gamepad. This string identifies + the brand or style of connected gamepad device. +
++ The exact format of the {{Gamepad/id}} string is left unspecified. + It is RECOMMENDED that the [=user agent=] select a string that + identifies the product without uniquely identifying the device. For + example, a USB gamepad may be identified by its `idVendor` and + `idProduct` values. Unique identifiers like serial numbers or + Bluetooth device addresses MUST NOT be included in the + {{Gamepad/id}} string. +
++ Indicates whether the physical device represented by this object is + still connected to the system. When a gamepad becomes unavailable, + whether by being physically disconnected, powered off or otherwise + unusable, the {{Gamepad/connected}} attribute MUST be set to + `false`. +
++ The {{Gamepad/connected}} getter steps are: +
++ The {{Gamepad/timestamp}} allows the author to determine the last + time the {{Gamepad/axes}} or {{Gamepad/buttons}} attribute for this + gamepad was updated. The value MUST be set to the [=current high + resolution time=] each time the system [=receives new button or + axis input values=] from the device. If no data has been received + from the hardware, {{Gamepad/timestamp}} MUST be the [=current high + resolution time=] at the time when the {{Gamepad}} was first made + available to script. +
++ [=User agent=]s SHOULD set a minimum resolution of |gamepad|'s + {{Gamepad/timestamp}} attribute to 5 microseconds, following + [[HR-TIME]]'s clock resolution recommendation. +
++ The {{Gamepad/timestamp}} getter steps are: +
++ The mapping in use for this device. If the user agent has knowledge + of the layout of the device, then it SHOULD indicate that a mapping + is in use by setting {{Gamepad/mapping}} to the corresponding + {{GamepadMappingType}} value. +
++ To select a mapping for a + gamepad device, run the following steps: +
++ Array of values for all axes of the gamepad. All axis values MUST + be linearly normalized to the range [-1.0 .. 1.0]. If the + controller is perpendicular to the ground with the directional + stick pointing up, -1.0 SHOULD correspond to "forward" or "left", + and 1.0 SHOULD correspond to "backward" 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. The same object + MUST be returned until the [=user agent=] needs to return different + values (or values in a different order). +
++ The {{Gamepad/axes}} getter steps are: +
++ Array of button states for all buttons of the gamepad. 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. The same + object MUST be returned until the [=user agent=] needs to return + different values (or values in a different order). +
++ The {{Gamepad/buttons}} getter steps are: +
++ A list of {{GamepadTouch}} events generated from all touch + surfaces. If the device does not support touch events, MUST be set + to `null`. +
++ The {{Gamepad/touchEvents}} getter steps are: +
++ A {{GamepadHapticActuator}} object that represents the device's + primary vibration actuator. +
++ The {{Gamepad/vibrationActuator}} getter steps are: +
++ When the system receives new button or axis input values, + run the following steps: +
++ To update gamepad state for |gamepad:Gamepad|, run the + following steps: +
++ To map and normalize axes for |gamepad:Gamepad|, run the + following steps: +
++ To map and normalize buttons for |gamepad:Gamepad|, run + the following steps: +
++ If the button has a digital switch to indicate a pure pressed + or released state, set |button|.{{GamepadButton/[[pressed]]}} + to `true` if the button is pressed or `false` if it is not + pressed. +
++ Otherwise, set |button|.{{GamepadButton/[[pressed]]}} to + `true` if the value is above the [=button press threshold=] + or `false` if it is not above the threshold. +
++ If the button is capable of detecting touch, set + |button|.{{GamepadButton/[[touched]]}} to `true` if the + button is currently being touched. +
++ Otherwise, set |button|.{{GamepadButton/[[touched]]}} to + |button|.{{GamepadButton/[[pressed]]}}. +
++ When the user agent modifies the list of |active touch points| for a + touch surface by adding touch points, removing touch points, or + updating the values of existing touch points, update + touchEvents by running the following steps: +
++ If the Gamepad has multiple touch surfaces the touch + id will be unique across surfaces. +
++ |position|[0] should be set to the device X coordinate + relative to the device [=touch surface=] and normalized + to [-1.0,1.0] where -1.0 is the leftmost coordinate and + 1.0 is the rightmost coordinate. +
++ `position[0] = (2.0 * touchData.x / surfaceDimensions[0]) + - 1` +
++ |position|[1] should be set to the device Y coordinate + relative to the device [=touch surface=] and normalized + to [-1.0,1.0] where -1.0 is the topmost coordinate and + 1.0 is the bottommost coordinate. +
++ `position[1] = (2.0 * touchData.y / surfaceDimensions[1]) + - 1` +
++ A new `Gamepad` representing a connected gamepad device is + constructed by performing the following steps: +
++ To select an unused + gamepad index for |gamepad:Gamepad|, run the following steps: +
++ To initialize axes for + |gamepad:Gamepad|, run the following steps: +
++ Otherwise: +
++ Otherwise, [=list/append=] |rawInputIndex| to + |unmappedInputList|. +
++ To initialize buttons for a + gamepad, run the following steps: +
++ Otherwise: +
++ Otherwise, [=list/append=] |rawInputIndex| to + |unmappedInputList|. +
++ To initialize + touchEvents for a gamepad, run the following steps: +
+
+ null
.
+ + This interface defines the state of an individual button on a gamepad + device. +
++ [Exposed=Window] + interface GamepadButton { + readonly attribute boolean pressed; + readonly attribute boolean touched; + readonly attribute double value; + }; ++
+ Instances of {{GamepadButton}} are created with the internal slots + described in the following table: +
++ Internal slot + | ++ Initial value + | ++ Description (non-normative) + | +
---|---|---|
+ [[\pressed]] + | ++ `false` + | ++ A flag indicating that the button is pressed + | +
+ [[\touched]] + | ++ `false` + | ++ A flag indicating that the button is touched + | +
+ [[\value]] + | ++ 0.0 + | ++ A {{double}} representing the button value scaled to the range [0.0 + .. 1.0] + | +
+ The pressed state of the button. This property MUST be `true` if + the button is currently pressed, and `false` if it is not pressed. + For buttons which do not have a digital switch to indicate a pure + pressed or released state, the [=user agent=] MUST choose a + button press threshold to indicate the button as pressed + when its value is above a certain amount. If the platform API gives + a recommended value, the user agent SHOULD use that. In other + cases, the user agent SHOULD choose some other reasonable value. +
++ The {{GamepadButton/pressed}} getter steps are: +
++ The touched state of the button. If the button is capable of + detecting touch, this property MUST be `true` if the button is + currently being touched, and `false` otherwise. If the button is + not capable of detecting touch and is capable of reporting an + analog value, this property MUST be `true` if the value property is + greater than 0, and `false` if the value is 0. If the button is not + capable of detecting touch and can only report a digital value, + this property MUST mirror the {{GamepadButton/pressed}} attribute. +
++ The {{GamepadButton/touched}} getter steps are: +
++ For buttons that have an analog sensor, this property MUST + represent the amount which the button has been pressed. 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. For + buttons without an analog sensor, only the values 0.0 and 1.0 for + fully unpressed and fully pressed respectively, MUST be provided. +
++ The {{GamepadButton/value}} getter steps are: +
++ This interface defines a single touch event on a gamepad device that + supports input. The event consists of a touch id that uniquely + identifies the touch point from the time the input medium (e.g. finger, + stylus, etc) makes contact with the touch device, up to the time the + input medium is no longer making contact with the touch device. +
++ [Exposed=Window, SecureContext] + interface GamepadTouch { + readonly attribute unsigned long touchId; + readonly attribute octet surfaceId; + readonly attribute Float32Array position; + readonly attribute Uint32Array? surfaceDimensions; + }; ++
+ The user agent is responsible for: +
+null
, MUST be a two-element array.
+ + This enum defines the set of known mappings for a Gamepad. +
++ enum GamepadMappingType { + "", + "standard", + "xr-standard", + }; ++
+ A {{GamepadHapticActuator}} corresponds to a configuration of motors or + other actuators that can apply a force for the purposes of haptic + feedback. +
++ [Exposed=Window] + interface GamepadHapticActuator { + [SameObject] readonly attribute FrozenArray<GamepadHapticEffectType> effects; + Promise<GamepadHapticsResult> playEffect( + GamepadHapticEffectType type, + optional GamepadEffectParameters params = {} + ); + Promise<GamepadHapticsResult> reset(); + }; ++
+ Instances of {{GamepadHapticActuator}} are created with the internal + slots described in the following table: +
++ Internal slot + | ++ Initial value + | ++ Description + | +
---|---|---|
+ [[\effects]] + | ++ An empty [=list=] of {{Gamepad/GamepadHapticEffectType}}. + | ++ Represents the effects supported by the actuator. + | +
+ [[\playingEffectPromise]] + | ++ `null` + | ++ The {{Promise}} to play some effect, or `null` if no effect is + playing. + | +
+ Array of {{Gamepad/GamepadHapticEffectType}} values representing + all the types of haptic effects that the actuator supports. This + property lists the {{Gamepad/GamepadHapticEffectType}} values that + the actuator supports, unless the [=user agent=] does not support + playing effects of that type. +
++ The {{GamepadHapticActuator/effects}} getter steps are: +
++ The {{GamepadHapticActuator/playEffect()}} method steps, called + with {{GamepadHapticEffectType}} |type:GamepadHapticEffectType| and + {{GamepadEffectParameters}} |params:GamepadEffectParameters |, are: +
++ The {{GamepadHapticActuator/reset()}} method steps are: +
++ A {{GamepadHapticActuator}} can play effects with type + |type:GamepadHapticEffectType| if |type:GamepadHapticEffectType| can be + found in the {{GamepadHapticActuator/[[effects]]}} [=list=]. +
++ To check if an effect with {{GamepadHapticEffectType}} + |type:GamepadHapticEffectType| and {{GamepadEffectParameters}} + |params:GamepadEffectParameters| describes a valid effect, + run the following steps: +
++ To issue a haptic effect on an actuator, the [=user agent=] + MUST send a command to the device to render an effect of + |type:GamepadHapticEffectType| and try to make it use the provided + |params:GamepadEffectParameters|. The [=user agent=] SHOULD use the + provided |playEffectTimestamp:DOMHighResTimestamp| for more precise + playback timing when |params|.{{GamepadEffectParameters/startDelay}} is + not `0.0`. The [=user agent=] MAY modify the effect to increase + compatibility. For example, an effect intended for a rumble motor may + be transformed into a waveform-based effect for a device that supports + waveform haptics but lacks rumble motors. +
++ To stop haptic effects on an actuator, the [=user agent=] + MUST send a command to the device to abort any effects currently being + played. If a haptic effect was interrupted, the actuator SHOULD return + to a motionless state as quickly as possible. +
++ When the |document|'s [=Document/visibility state=] becomes + `"hidden"`, run these steps for each {{GamepadHapticActuator}} + |actuator:GamepadHapticActuator|: +
++ A new + |gamepadHapticActuator:GamepadHapticActuator| representing a + {{Gamepad}}'s primary vibration actuator is constructed by performing + the following steps: +
++ enum GamepadHapticsResult { + "complete", + "preempted" + }; ++
+ The haptic effected completed playing. +
++ The current effect was stopped or replaced (i.e., "preempted") by + another effect. +
++ The effect type defines how the effect parameters are interpreted by + the actuator. +
++ enum GamepadHapticEffectType { + "dual-rumble", + "trigger-rumble" + }; ++
+ {{GamepadHapticEffectType/"dual-rumble"}} describes a haptic + configuration with an eccentric rotating mass (ERM) vibration motor + in each handle of a standard gamepad. In this configuration, either + motor is capable of vibrating the whole gamepad. The vibration + effects created by each motor are unequal so that the effects of + each can be combined to create more complex haptic effects. +
++ A {{GamepadHapticEffectType/"dual-rumble"}} effect is a + fixed-duration, constant-intensity vibration effect intended for an + actuator of this type. {{GamepadHapticEffectType/"dual-rumble"}} + effects are defined by {{GamepadEffectParameters/startDelay}}, + {{GamepadEffectParameters/duration}}, + {{GamepadEffectParameters/strongMagnitude}}, and + {{GamepadEffectParameters/weakMagnitude}}, none of which are + required because they default to 0. +
++ {{GamepadEffectParameters/strongMagnitude}} and + {{GamepadEffectParameters/weakMagnitude}} set the intensity levels + for the low-frequency and high-frequency vibrations, normalized to + the range `[0,1]`, defaulting to 0. +
++ Given {{GamepadEffectParameters}} |params:GamepadEffectParameters|, + a valid dual-rumble effect must have a [=valid + effect|valid=] {{GamepadEffectParameters/duration}}, a [=valid + effect|valid=] {{GamepadEffectParameters/startDelay}}, and both the + {{GamepadEffectParameters/strongMagnitude}} and the + {{GamepadEffectParameters/weakMagnitude}} must be in the range + `[0,1]`. +
++ {{GamepadHapticEffectType/"trigger-rumble"}} describes a haptics + configuration with a vibration motor in each of the bottom front + buttons of a [=Standard Gamepad=] (buttons with [=canonical + indices=] 6 and 7) in addition to the two handle motors used for + {{GamepadHapticEffectType/"dual-rumble"}}. These buttons most + commonly take the form of spring-loaded triggers. In this + configuration, either motor is capable of providing localized + haptic feedback on the button's surface. +
++ A {{GamepadHapticEffectType/"trigger-rumble"}} effect is a + fixed-duration, constant-intensity vibration effect intended for an + actuator of this type. {{GamepadHapticEffectType/"trigger-rumble"}} + effects are defined by {{GamepadEffectParameters/startDelay}}, + {{GamepadEffectParameters/duration}}, + {{GamepadEffectParameters/strongMagnitude}}, + {{GamepadEffectParameters/weakMagnitude}}, + {{GamepadEffectParameters/leftTrigger}}, and + {{GamepadEffectParameters/rightTrigger}}, none of which are + required because they default to 0. +
++ {{GamepadEffectParameters/startDelay}}, + {{GamepadEffectParameters/duration}}, + {{GamepadEffectParameters/strongMagnitude}}, + {{GamepadEffectParameters/weakMagnitude}} share the same definition + with {{GamepadHapticEffectType/"dual-rumble"}}. + {{GamepadEffectParameters/leftTrigger}} and + {{GamepadEffectParameters/rightTrigger}}, respectively, set the + intensity levels for the left and right bottom front buttons + vibrations, normalized to the range `[0,1]`, defaulting to 0. +
++ Given {{GamepadEffectParameters}} |params:GamepadEffectParameters|, + a valid trigger-rumble effect must have a [=valid + effect|valid=] {{GamepadEffectParameters/duration}}, a [=valid + effect|valid=] {{GamepadEffectParameters/startDelay}}, and the + {{GamepadEffectParameters/strongMagnitude}}, + {{GamepadEffectParameters/weakMagnitude}}, + {{GamepadEffectParameters/leftTrigger}}, and + {{GamepadEffectParameters/rightTrigger}} must be in the range + `[0,1]`. +
+
+ A GamepadEffectParameters
dictionary contains keys for
+ parameters used by haptic effects. The meaning of each key is defined
+ by the haptic effect, and some keys may be unused.
+
+ To mitigate unwanted long-running effects, the [=user agent=] MAY limit + the total effect duration for a [=valid effect=] to some maximum + duration. It is RECOMMENDED that the [=user agent=] use a maximum of 5 + seconds. +
++ dictionary GamepadEffectParameters { + unsigned long long duration = 0; + unsigned long long startDelay = 0; + double strongMagnitude = 0.0; + double weakMagnitude = 0.0; + double leftTrigger = 0.0; + double rightTrigger = 0.0; + }; ++
+ [Exposed=Window] + partial interface Navigator { + sequence<Gamepad?> getGamepads(); + }; ++
+ Instances of {{Navigator}} are created with the internal slots + described in the following table: +
++ Internal slot + | ++ Initial value + | ++ Description (non-normative) + | +
---|---|---|
+ [[\hasGamepadGesture]] + | ++ `false` + | ++ A flag indicating that a [=gamepad user gesture=] has been observed + | +
+ [[\gamepads]] + | ++ A empty [=sequence=] of {{Gamepad?}} objects + | ++ Each {{Gamepad}} present at the index specified by its + {{Gamepad/index}} attribute, or `null` for unassigned indices. + | +
+ The gamepad state returned from {{Navigator/getGamepads()}} does not + reflect disconnection or connection until after the + {{gamepaddisconnected}} or {{gamepadconnected}} events have fired. +
++ To mitigate fingerprinting, {{Navigator/getGamepads()}} returns an + empty [=list=] before a [=gamepad user gesture=] has been seen. + [[FINGERPRINTING-GUIDANCE]] +
+ ++ The {{Navigator/getGamepads()}} method steps are: +
++ A |gamepad:Gamepad| contains a + gamepad user gesture if the current input state indicates that + the user is currently interacting with the gamepad. The [=user + agent=] MUST provide an algorithm to check if the input state + contains a gamepad user gesture. For buttons that support a neutral + default value and have reported a {{GamepadButton/pressed}} value of + `false` at least once, a {{GamepadButton/pressed}} value of `true` + SHOULD be considered interaction. If a button does not support a + neutral default value (for example, a toggle switch), then a + {{GamepadButton/pressed}} value of `true` SHOULD NOT be considered + interaction. If a button has never reported a + {{GamepadButton/pressed}} value of `false` then it SHOULD NOT be + considered interaction. Axis movements SHOULD be considered + interaction if the axis supports a neutral default value, the current + displacement from neutral is greater than a threshold chosen by the + [=user agent=], and the axis has reported a value below the threshold + at least once. If an axis does not support a neutral default value + (for example, an axis for a joystick that does not self-center), or + an axis has never reported a value below the axis gesture threshold, + then the axis SHOULD NOT be considered when checking for interaction. + The axis gesture threshold SHOULD be large enough that random jitter + is not considered interaction. +
++ [Exposed=Window] + + interface GamepadEvent: Event { + constructor(DOMString type, GamepadEventInit eventInitDict); + [SameObject] readonly attribute Gamepad gamepad; + }; ++
+ dictionary GamepadEventInit : EventInit { + required Gamepad gamepad; + }; ++
+ Each device manufacturer creates many different products and each has + unique styles and layouts of buttons and axes. It is intended that the + [=user agent=] support as many of these as possible. +
++ Additionally there are de facto standard layouts that have + been made popular by game consoles. When the [=user agent=] recognizes + the attached device, it is RECOMMENDED that it be remapped to a + canonical ordering when possible. Devices that are not recognized + should still be exposed in their raw form. +
++ There is currently one canonical layout, the Standard + Gamepad. When remapping, the indices in {{Gamepad/axes}} and + {{Gamepad/buttons}} should correspond as closely as possible to the + physical locations in the diagram below. Additionally, + {{Gamepad/mapping}} SHOULD be set to {{GamepadMappingType/"standard"}}. +
++ The [=Standard Gamepad=] buttons are laid out in a left cluster of four + buttons, a right cluster of four buttons, a center cluster of three + buttons, and a pair of front facing buttons on the left and right side + of the gamepad. The four axes of the "Standard Gamepad" are associated + with a pair of analog sticks, one on the left and one on the right. The + following table describes the buttons/axes and their physical + locations. +
++ An axis input represents a Standard Gamepad axis if it + reports the input value for a thumbstick axis, the thumbstick is + located in approximately the same location as the corresponding + [=Standard Gamepad=] thumbstick, and the orientation of the axis + (up-down or left-right) matches the orientation of the [=Standard + Gamepad=] axis. If there are multiple axes that represent the same + [=Standard Gamepad=] axis, then the [=user agent=] SHOULD select one to + be the [=Standard Gamepad=] axis and assign a different index to the + other axis. +
++ A button input represents a Standard Gamepad button if it + reports the input value for a button or trigger, and the button or + trigger is located in approximately the same location as the + corresponding [=Standard Gamepad=] button. +
++ If an axis or button input represents a [=Standard Gamepad=] axis or + button, then its canonical index + is the index of the corresponding [=Standard Gamepad=] axis or button. +
++ Type + | ++ Index + | ++ Location + | +
---|---|---|
+ Button + | ++ 0 + | ++ Bottom button in right cluster + | +
+ 1 + | ++ Right button in right cluster + | +|
+ 2 + | ++ Left button in right cluster + | +|
+ 3 + | ++ Top button in right cluster + | +|
+ 4 + | ++ Top left front button + | +|
+ 5 + | ++ Top right front button + | +|
+ 6 + | ++ Bottom left front button + | +|
+ 7 + | ++ Bottom right front button + | +|
+ 8 + | ++ Left button in center cluster + | +|
+ 9 + | ++ Right button in center cluster + | +|
+ 10 + | ++ Left stick pressed button + | +|
+ 11 + | ++ Right stick pressed button + | +|
+ 12 + | ++ Top button in left cluster + | +|
+ 13 + | ++ Bottom button in left cluster + | +|
+ 14 + | ++ Left button in left cluster + | +|
+ 15 + | ++ Right button in left cluster + | +|
+ 16 + | ++ Center button in center cluster + | +|
+ axes + | ++ 0 + | ++ Horizontal axis for left stick (negative left/positive right) + | +
+ 1 + | ++ Vertical axis for left stick (negative up/positive down) + | +|
+ 2 + | ++ Horizontal axis for right stick (negative left/positive right) + | +|
+ 3 + | ++ Vertical axis for right stick (negative up/positive down) + | +
+ Inspecting the capabilities of {{Gamepad}} objects can be used as a + means of active fingerprinting. The [=user agent=] MAY alter the + device information exposed through the API to reduce the + fingerprinting surface. As an example, an implementation can require + that a {{Gamepad}} object have exactly the number of buttons and axes + defined in the [=Standard Gamepad=] layout even if more or fewer + inputs are present on the connected device. + [[FINGERPRINTING-GUIDANCE]] +
++ The example below demonstrates typical access to gamepads. Note the + relationship with the + {{AnimationFrameProvider/requestAnimationFrame()}} method. +
++ function runAnimation() { + window.requestAnimationFrame(runAnimation); + for (const pad of navigator.getGamepads()) { + // todo; simple demo of displaying pad.axes and pad.buttons + console.log(pad); + } + } + + window.requestAnimationFrame(runAnimation); ++
requestAnimationFrame()
+ + Interactive applications will typically be using the + {{AnimationFrameProvider/requestAnimationFrame()}} method to drive + animation, and will want coordinate animation with user gamepad + input. As such, the gamepad 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 gamepad inputs should + also be sampled at that rate. +
++ When a gamepad becomes available on the system, run the following + steps: +
++ User agents implementing this specification must provide a new DOM + event, named {{gamepadconnected}}. The corresponding event MUST be of + type {{GamepadEvent}} and MUST fire on the {{Window}} object. +
++ A [=user agent=] MUST dispatch this event type to indicate the user has + connected a gamepad. If a gamepad was already connected when the page + was loaded, the {{gamepadconnected}} event SHOULD be dispatched when + the user presses a button or moves an axis. +
++ When a gamepad becomes unavailable on the system, run the following + steps: +
++ User agents implementing this specification must provide a new DOM + event, named {{gamepaddisconnected}}. The corresponding event MUST be + of type {{GamepadEvent}} and MUST fire on the {{Window}} object. +
++ When a gamepad is disconnected from the [=user agent=], if the [=user + agent=] has previously dispatched a {{gamepadconnected}} event for that + gamepad to a {{Window}}, a {{gamepaddisconnected}} event MUST be + dispatched to that same {{Window}}. +
++ More discussion needed, on whether to include or exclude axis and + button changed events, and whether to roll them more together + (`"gamepadchanged"`?), separate somewhat (`"gamepadaxischanged"`?), or + separate by individual axis and button. +
++ This specification extends the {{WindowEventHandlers}} interface mixin + from HTML to add [=event handler IDL attributes=] to facilitate the + event handler registration. +
++ partial interface mixin WindowEventHandlers { + attribute EventHandler ongamepadconnected; + attribute EventHandler ongamepaddisconnected; + }; ++
+ This specification defines a policy-controlled feature identified by + the string "gamepad". Its + [=policy-controlled feature/default allowlist=] is [=default + allowlist/*=]. +
++ A [=document=]’s [=Document/permissions policy=] determines whether + any content in that document is allowed to access + {{Navigator/getGamepads()}}. If disabled in any document, no content + in the document will be [=allowed to use=] + {{Navigator/getGamepads()}}, nor will the {{gamepadconnected}} and + {{gamepaddisconnected}} events fire. +
++ touch surface is a surface that can detect contact from a + users fingers and report where on the surface the contact is made. +
++ touch surface enumeration order is an ordered listing of all + the surfaces in a |gamepad|. +
++ active touch point is defined in the Touch + Events - Level 2 specification. +
++ The following people contributed to the development of this document. +
+