963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
6.0 KiB
category
| category |
|---|
| Browser |
useGamepad
Provides reactive bindings for the Gamepad API.
Usage
Due to how the Gamepad API works, you must interact with the page using the gamepad before it will be detected.
<script setup lang="ts">
import { useGamepad } from '@vueuse/core';
import { computed } from 'vue';
const { isSupported, gamepads } = useGamepad();
const gamepad = computed(() => gamepads.value.find((g) => g.mapping === 'standard'));
</script>
<template>
<span>
{{ gamepad.id }}
</span>
</template>
Gamepad Updates
Currently the Gamepad API does not have event support to update the state of the gamepad. To update the gamepad state, requestAnimationFrame is used to poll for gamepad changes. You can control this polling by using the pause and resume functions provided by useGamepad
import { useGamepad } from '@vueuse/core';
const { pause, resume, gamepads } = useGamepad();
pause();
// gamepads object will not update
resume();
// gamepads object will update on user input
Gamepad Connect & Disconnect Events
The onConnected and onDisconnected events will trigger when a gamepad is connected or disconnected.
import { useGamepad } from '@vueuse/core';
// ---cut---
const { gamepads, onConnected, onDisconnected } = useGamepad();
onConnected((index) => {
console.log(`${gamepads.value[index].id} connected`);
});
onDisconnected((index) => {
console.log(`${index} disconnected`);
});
Vibration
The Gamepad Haptics API is sparse, so check the compatibility table before using.
import { useGamepad } from '@vueuse/core';
const { gamepads, onConnected, onDisconnected } = useGamepad();
const gamepad = gamepads.value[0]!;
// ---cut---
import { computed } from 'vue';
const supportsVibration = computed(() => gamepad.hapticActuators.length > 0);
function vibrate() {
if (supportsVibration.value) {
const actuator = gamepad.hapticActuators[0];
actuator.playEffect('dual-rumble', {
startDelay: 0,
duration: 1000,
weakMagnitude: 1,
strongMagnitude: 1,
});
}
}
Mappings
To make the Gamepad API easier to use, we provide mappings to map a controller to a controllers button layout.
Xbox360 Controller
<script setup>
import { mapGamepadToXbox360Controller } from '@vueuse/core';
const controller = mapGamepadToXbox360Controller(gamepad);
</script>
<template>
<span>{{ controller.buttons.a.pressed }}</span>
<span>{{ controller.buttons.b.pressed }}</span>
<span>{{ controller.buttons.x.pressed }}</span>
<span>{{ controller.buttons.y.pressed }}</span>
</template>
Currently there are only mappings for the Xbox 360 controller. If you have controller you want to add mappings for, feel free to open a PR for more controller mappings!
SSR Compatibility
This component is designed to be used in the client side. In some cases, SSR might cause some hydration mismatches.
If you are using Nuxt, you can simply rename your component file with the .client.vue suffix (e.g., GamepadComponent.client.vue) which will automatically make it render only on the client side, avoiding hydration mismatches.
In other frameworks or plain Vue, you can wrap your usage component with a <ClientOnly> component to ensure it is only rendered on the client side.
Type Declarations
export interface UseGamepadOptions extends ConfigurableWindow, ConfigurableNavigator {}
/**
* Maps a standard standard gamepad to an Xbox 360 Controller.
*/
export declare function mapGamepadToXbox360Controller(
gamepad: Ref<Gamepad | undefined>,
): ComputedRef<{
buttons: {
a: GamepadButton;
b: GamepadButton;
x: GamepadButton;
y: GamepadButton;
};
bumper: {
left: GamepadButton;
right: GamepadButton;
};
triggers: {
left: GamepadButton;
right: GamepadButton;
};
stick: {
left: {
horizontal: number;
vertical: number;
button: GamepadButton;
};
right: {
horizontal: number;
vertical: number;
button: GamepadButton;
};
};
dpad: {
up: GamepadButton;
down: GamepadButton;
left: GamepadButton;
right: GamepadButton;
};
back: GamepadButton;
start: GamepadButton;
} | null>;
export declare function useGamepad(options?: UseGamepadOptions): {
isSupported: ComputedRef<boolean>;
onConnected: EventHookOn<number>;
onDisconnected: EventHookOn<number>;
gamepads: Ref<
{
readonly axes: ReadonlyArray<number>;
readonly buttons: readonly {
readonly pressed: boolean;
readonly touched: boolean;
readonly value: number;
}[];
readonly connected: boolean;
readonly id: string;
readonly index: number;
readonly mapping: GamepadMappingType;
readonly timestamp: DOMHighResTimeStamp;
readonly vibrationActuator: {
playEffect: (
type: GamepadHapticEffectType,
params?: GamepadEffectParameters,
) => Promise<GamepadHapticsResult>;
reset: () => Promise<GamepadHapticsResult>;
};
}[],
| Gamepad[]
| {
readonly axes: ReadonlyArray<number>;
readonly buttons: readonly {
readonly pressed: boolean;
readonly touched: boolean;
readonly value: number;
}[];
readonly connected: boolean;
readonly id: string;
readonly index: number;
readonly mapping: GamepadMappingType;
readonly timestamp: DOMHighResTimeStamp;
readonly vibrationActuator: {
playEffect: (
type: GamepadHapticEffectType,
params?: GamepadEffectParameters,
) => Promise<GamepadHapticsResult>;
reset: () => Promise<GamepadHapticsResult>;
};
}[]
>;
pause: Fn;
resume: Fn;
isActive: Readonly<ShallowRef<boolean>>;
};
export type UseGamepadReturn = ReturnType<typeof useGamepad>;