Files
SpotMicroESP32-Leika/app/src/lib/stores/gamepad.ts
T
Rune Harlyk 91a7b170fe 🎨 format
2025-10-11 10:42:32 +02:00

48 lines
1.4 KiB
TypeScript

import { readable, derived } from 'svelte/store'
export type GamepadState = {
available: boolean
gamepads: Gamepad[]
}
export const gamepads = readable<GamepadState>({ available: false, gamepads: [] }, set => {
const update = () => {
const hasGamepadAPI = 'getGamepads' in navigator
if (!hasGamepadAPI) {
set({ available: false, gamepads: [] })
return
}
const gps = navigator.getGamepads?.() ?? []
const validGamepads = gps.filter(Boolean) as Gamepad[]
set({
available: true,
gamepads: validGamepads
})
raf = requestAnimationFrame(update)
}
window.addEventListener('gamepadconnected', update)
window.addEventListener('gamepaddisconnected', update)
let raf = requestAnimationFrame(update)
return () => {
cancelAnimationFrame(raf)
window.removeEventListener('gamepadconnected', update)
window.removeEventListener('gamepaddisconnected', update)
}
})
export const gamepad = derived(gamepads, $gamepads =>
$gamepads.available && $gamepads.gamepads.length > 0 ? $gamepads.gamepads[0] : null
)
export const gamepadAxes = derived(gamepad, $gamepad => $gamepad?.axes ?? [0, 0, 0, 0])
export const gamepadButtons = derived(gamepad, $gamepad => $gamepad?.buttons ?? [])
export const hasGamepad = derived(
gamepads,
$gamepads => $gamepads.available && $gamepads.gamepads.length > 0
)