Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions types/webxr/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,28 @@ interface XRInputSource {

declare abstract class XRInputSource implements XRInputSource {}

/**
* This Gamepad API interface represents hardware in the controller designed to provide haptic feedback to the user (if available), most commonly vibration hardware.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadHapticActuator)
*/
interface GamepadHapticActuator {
/**
* The pulse() method of the GamepadHapticActuator interface makes the hardware pulse at a certain intensity for a specified duration.
* @remarks Repeated calls to pulse() override the previous calls if they are still ongoing.
* @param value A double representing the intensity of the pulse. This can vary depending on the hardware type, but generally takes a value between 0.0 (no intensity) and 1.0 (full intensity).
* @param duration A double representing the duration of the pulse, in milliseconds.
* @returns A promise that resolves with a value of true when the pulse has successfully completed.
*
* @remarks This feature should be documented in the Gamepad API, but it is not yet implemented in any browser thus missing there. However, it is commonly used in WebXR applications and causes issues for people if omitted.
*/
pulse(value: number, duration: number): Promise<boolean>;
}

interface Gamepad {
readonly hapticActuators: readonly GamepadHapticActuator[];
Copy link
Contributor

Choose a reason for hiding this comment

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

This should probably be optional? This is not supported by all implementations. And the initial value (per specs) is undefined

}

/**
* Represents a list of XRInputSources. It is used in favor of a frozen array type when the contents
* of the list are expected to change over time, such as with the XRSession inputSources attribute.
Expand Down
4 changes: 4 additions & 0 deletions types/webxr/webxr-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ function assertNever(value: never) {
throw new Error("Can't test instance of XRSession");
}

if (session.inputSources[0].gamepad?.hapticActuators) {
session.inputSources[0].gamepad.hapticActuators[0].pulse(0.5, 100);
}

const button = root?.querySelector("button");
button?.addEventListener("beforexrselect", (evt: XRSessionEvent) => {
console.assert(evt.session === session);
Expand Down