Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gamepad trigger-rumble and associated updates #34442

Merged
merged 8 commits into from
Jul 24, 2024
Merged
43 changes: 43 additions & 0 deletions files/en-us/web/api/gamepadhapticactuator/effects/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "GamepadHapticActuator: effects property"
short-title: effects
slug: Web/API/GamepadHapticActuator/effects
page-type: web-api-instance-property
browser-compat: api.GamepadHapticActuator.effects
---

{{APIRef("Gamepad API")}}

The **`effects`** read-only property of the {{domxref("GamepadHapticActuator")}} interface returns an array of enumerated values representing the different haptic effects that the actuator supports.

## Value

An array representing the supported haptic effects. Possible included values are:

- `"dual-rumble"`
- : A positional rumbling effect created by dual vibration motors in each handle of a controller, which can be vibrated independently.
- `"trigger-rumble"`
- : Localized rumbling effects on the surface of a controller's trigger buttons created by vibrational motors located in each button. These buttons most commonly take the form of spring-loaded triggers.

> **Note:** If an effect is not listed that is known to be supported by the hardware, it may be that the browser does not support playing effects of that type.

## Examples

```js
const gamepad = navigator.getGamepads()[0];

// Logs "dual-rumble" or "trigger-rumble"
console.log(gamepad.hapticActuators[0].effects[0]);
```

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- [Gamepad API](/en-US/docs/Web/API/Gamepad_API)
14 changes: 8 additions & 6 deletions files/en-us/web/api/gamepadhapticactuator/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@ This interface is accessible through the {{domxref("Gamepad.hapticActuators")}}

## Instance properties

- {{domxref("GamepadHapticActuator.type")}} {{ReadOnlyInline}}
- : Returns an enum representing the type of the haptic hardware.
- {{domxref("GamepadHapticActuator.effects")}} {{ReadOnlyInline}}
- : Returns an array of enumerated values representing the different haptic effects that the actuator supports.
- {{domxref("GamepadHapticActuator.type")}} {{deprecated_inline}} {{ReadOnlyInline}}
- : Returns an enumerated value representing the type of the haptic hardware. This property is deprecated: use `GamepadHapticActuator.effects` to detect effect support.

## Instance methods

- {{domxref("GamepadHapticActuator.playEffect()")}} {{ReadOnlyInline}}
- : Causes the hardware to play a specific vibration effect.
- {{domxref("GamepadHapticActuator.pulse()")}} {{ReadOnlyInline}}

- : Makes the hardware pulse at a certain intensity for a specified duration.

- {{domxref("GamepadHapticActuator.playEffect()")}} {{ReadOnlyInline}}
- : Makes the hardware play a specific vibration pattern.
- {{domxref("GamepadHapticActuator.reset()")}} {{ReadOnlyInline}}
- : Stops the hardware from playing an active vibration effect.

## Examples

Expand Down
28 changes: 16 additions & 12 deletions files/en-us/web/api/gamepadhapticactuator/playeffect/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ page-type: web-api-instance-method
browser-compat: api.GamepadHapticActuator.playEffect
---

{{APIRef("Gamepad")}}
{{APIRef("Gamepad API")}}

The **`playEffect()`** method of the {{domxref("GamepadHapticActuator")}} interface makes the hardware play a specific vibration pattern.
The **`playEffect()`** method of the {{domxref("GamepadHapticActuator")}} interface causes the hardware to play a specific vibration effect.

## Syntax

Expand All @@ -20,28 +20,32 @@ playEffect(type, params)

- `type`

- : A string representing the desired effect. This can vary depending on the hardware type. Possible values are "dual-rumble" or "vibration".
- : A string representing the desired effect. Possible values are `"dual-rumble"` and `"trigger-rumble"`, and their effects can vary depending on the hardware type. See {{domxref("GamepadHapticActuator.effects")}} for further details of the effect types.

- `params`

- : An object to describe a desired haptic effect.

Expected values are:

- `duration`
- : The duration of the effect in milliseconds.
- `startDelay`
- : The delay in milliseconds before the effect is started.
- `strongMagnitude`
- : Rumble intensity of the low-frequency (strong) rumble motors, normalized to the range between 0.0 and 1.0.
- `weakMagnitude`
- : Rumble intensity of the high-frequency (weak) rumble motors, normalized to the range between 0.0 and 1.0.
- `duration` {{optional_inline}}
- : The duration of the effect in milliseconds. If omitted, `duration` defaults to `0`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

highly subjective, but I think this is overly repetitive, and in this situation I just say:

Suggested change
- : The duration of the effect in milliseconds. If omitted, `duration` defaults to `0`.
- : The duration of the effect in milliseconds.
Defaults to `0`.

I wish we had a consistent way to write default values for optional items.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, mine is wordier, but it is also a bit more intuitive. Saying that, I don't think it really adds much, so I've updated it to your suggestion.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, mine is wordier, but it is also a bit more intuitive.

It is, and if this were the only place we document a default I would prefer it. But there are (obviously) thousands of places we document defaults, and if every one says "If omitted, thing defaults to value" then it is very repetitive: "if omitted" essentially repeats the definition of "default" every time. IMO MDN really misses a structured consistent way to represent "default", that's not just in prose at all.

- `startDelay` {{optional_inline}}
- : The delay in milliseconds before the effect is started. If omitted, `startDelay` defaults to `0`.
- `strongMagnitude` {{optional_inline}}
- : The rumble intensity of the low-frequency (strong) rumble motors, normalized to the range between `0.0` and `1.0`. If omitted, `strongMagnitude` defaults to `0.0`.
- `weakMagnitude` {{optional_inline}}
- : The rumble intensity of the high-frequency (weak) rumble motors, normalized to the range between `0.0` and `1.0`. If omitted, `weakMagnitude` defaults to `0.0`.
- `leftTrigger` (relevant to `"trigger-rumble"` effects only) {{optional_inline}}
- : The rumble intensity of the bottom-left front trigger, normalized to the range between `0.0` and `1.0`. If omitted, `leftTrigger` defaults to `0.0`.
- `rightTrigger` (relevant to `"trigger-rumble"` effects only) {{optional_inline}}
- : The rumble intensity of the bottom-right front trigger, normalized to the range between `0.0` and `1.0`. If omitted, `rightTrigger` defaults to `0.0`.

> **Note:** A new call to `playEffect()` overrides a previous ongoing call.

### Return value

A promise that resolves with `true` when the playEffect successfully completes.
A promise that resolves with `"complete"` when the effect successfully completes, or `"preempted"` if the current effect is stopped or replaced by another effect.

## Examples

Expand Down
2 changes: 1 addition & 1 deletion files/en-us/web/api/gamepadhapticactuator/pulse/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ page-type: web-api-instance-method
browser-compat: api.GamepadHapticActuator.pulse
---

{{APIRef("Gamepad")}}
{{APIRef("Gamepad API")}}

The **`pulse()`** method of the {{domxref("GamepadHapticActuator")}} interface makes the hardware pulse at a certain intensity for a specified duration.

Expand Down
52 changes: 52 additions & 0 deletions files/en-us/web/api/gamepadhapticactuator/reset/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: "GamepadHapticActuator: reset() method"
short-title: reset()
slug: Web/API/GamepadHapticActuator/reset
page-type: web-api-instance-method
browser-compat: api.GamepadHapticActuator.reset
---

{{APIRef("Gamepad API")}}

The **`reset()`** method of the {{domxref("GamepadHapticActuator")}} interface stops the hardware from playing an active vibration effect.

## Syntax

```js-nolint
reset()
```

### Parameters

None.

### Return value

A promise that resolves with `"complete"` if the effect is successfully reset, or `"preempted"` if the effect was stopped or replaced by another effect.

## Examples

```js
const gamepad = navigator.getGamepads()[0];

gamepad.vibrationActuator.playEffect("dual-rumble", {
startDelay: 0,
duration: 200,
weakMagnitude: 1.0,
strongMagnitude: 1.0,
});

gamepad.vibrationActuator.reset();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you want to await this and show the returned value? Maybe to make it crystal-clear, you could wrap the call in a setTimeout() with a delay <200ms, so you can show the "preempted" return value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @tomayac! I wasn't 100% sure what you meant, but I've tried to update both pages as suggested. Let me know what you think!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the reset() example, you await playing the effect before scheduling the timeout, so it doesn't show the effect you mean to show as per the comment. You need to flip the order. I would probably rather work with then() in both cases, resetting and playing the effect. Awaiting something in a realtime game scenario feels like a weird pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've swapped the order as you suggested, and converted both examples to use then(). Thanks again.

```

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- [Gamepad API](/en-US/docs/Web/API/Gamepad_API)
22 changes: 17 additions & 5 deletions files/en-us/web/api/gamepadhapticactuator/type/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,34 @@ title: "GamepadHapticActuator: type property"
short-title: type
slug: Web/API/GamepadHapticActuator/type
page-type: web-api-instance-property
status:
- deprecated
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These days the source of truth for deprecated is BCD, which auto-fills this value and auto-adds macro calls. So unless the BCD for this property also marks it deprecated, this will get un-fixed again next time the script runs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good call. I've just done that.

browser-compat: api.GamepadHapticActuator.type
---

{{APIRef("Gamepad")}}
{{APIRef("Gamepad API")}}{{deprecated_header}}

The **`type`** read-only property of the {{domxref("GamepadHapticActuator")}} interface returns an enum representing the type of the haptic hardware.
The **`type`** read-only property of the {{domxref("GamepadHapticActuator")}} interface returns an enumerated value representing the type of the haptic hardware.

This property is deprecated: use {{domxref("GamepadHapticActuator.effects")}} to detect effect support.

## Value

An enum of type [`GamepadHapticActuatorType`](https://w3c.github.io/gamepad/extensions.html#gamepadhapticactuatortype-enum); currently available types are:
An enumerated value representing the haptic hardware type. Currently available types are:

- `vibration` — vibration hardware, which creates a rumbling effect.
- `"vibration"`
- : Simple vibration hardware, which creates a rumbling effect.
- `"dual-rumble"`
- : A controller with a vibration motor in each handle. Each motor can be vibrated independently to create positional rumbling effects.

## Examples

TBC
```js
const gamepad = navigator.getGamepads()[0];

// Logs "vibration" or "dual-rumble"
console.log(gamepad.hapticActuators[0].type);
```

## Specifications

Expand Down
7 changes: 6 additions & 1 deletion files/jsondata/GroupData.json
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,12 @@
"/docs/Web/API/Gamepad_API/Using_the_Gamepad_API",
"/docs/Games/Techniques/Controls_Gamepad_API"
],
"interfaces": ["Gamepad", "GamepadButton", "GamepadEvent"],
"interfaces": [
"Gamepad",
"GamepadButton",
"GamepadEvent",
"GamepadHapticActuator"
],
"methods": ["Navigator.getGamepads()"],
"properties": [],
"events": ["Window: gamepadconnected", "Window: gamepaddisconnected"]
Expand Down