useGamepad
Provides reactive bindings for the Gamepad API.
Demo
Usage
Due to how the Gamepad API works, you must interact with the page using the gamepad before it will be detected.
<script setup>
import { useGamepad } from '@vueuse/core'
const { isSupported, gamepads } = useGamepad()
const gamepad = computed(() => gamepads.find(g => g.mapping === 'standard'))
</script>
<template>
<span>
{{ gamepad.id }}
<span>
</template>
<script setup>
import { useGamepad } from '@vueuse/core'
const { isSupported, gamepads } = useGamepad()
const gamepad = computed(() => gamepads.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
const { pause, resume, gamepads } = useGamepad()
pause()
// gamepads object will not update
resume()
// gamepads object will update on user input
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.
const { gamepads, onConnected, onDisconnected } = useGamepad()
onConnected((index) => {
console.log(`${gamepads.value[index].id} connected`)
})
onDisconnected((index) => {
console.log(`${index} disconnected`)
})
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.
const supportsVibration = computed(() => gamepad.hapticActuators.length > 0)
const vibrate = () => {
if (supportsVibration.value) {
const actuator = gamepad.hapticActuators[0]
actuator.playEffect('dual-rumble', {
startDelay: 0,
duration: 1000,
weakMagnitude: 1,
strongMagnitude: 1,
})
}
}
const supportsVibration = computed(() => gamepad.hapticActuators.length > 0)
const 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>
<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!
Type Declarations
Show 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: Ref<boolean>
onConnected: EventHookOn<number>
onDisconnected: EventHookOn<number>
gamepads: Ref<
{
readonly axes: readonly number[]
readonly buttons: readonly {
readonly pressed: boolean
readonly touched: boolean
readonly value: number
}[]
readonly connected: boolean
readonly hapticActuators: readonly {
readonly type: "vibration"
}[]
readonly id: string
readonly index: number
readonly mapping: GamepadMappingType
readonly timestamp: number
}[]
>
pause: Fn
resume: Fn
isActive: Readonly<Ref<boolean>>
}
export type UseGamepadReturn = ReturnType<typeof useGamepad>
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: Ref<boolean>
onConnected: EventHookOn<number>
onDisconnected: EventHookOn<number>
gamepads: Ref<
{
readonly axes: readonly number[]
readonly buttons: readonly {
readonly pressed: boolean
readonly touched: boolean
readonly value: number
}[]
readonly connected: boolean
readonly hapticActuators: readonly {
readonly type: "vibration"
}[]
readonly id: string
readonly index: number
readonly mapping: GamepadMappingType
readonly timestamp: number
}[]
>
pause: Fn
resume: Fn
isActive: Readonly<Ref<boolean>>
}
export type UseGamepadReturn = ReturnType<typeof useGamepad>