virtual-gamepad-lib
Version:
Emulate and display virtual and real gamepads on the web
134 lines (133 loc) • 9.59 kB
TypeScript
import { AxisChangeCallback, ButtonChangeCallback, GamepadApiWrapper, buttonChangeDetails } from './GamepadApiWrapper.js';
import { gamepadButtonType, gamepadDirection } from './enums.js';
export type GamepadDisplayButton = GamepadDisplayOnOffButton | GamepadDisplayVariableButton;
export type ButtonDisplayFunction = (buttonConfig: GamepadDisplayButton, value: number, touched: boolean, pressed: boolean, changes: buttonChangeDetails, btnIndex: number) => void;
export type JoystickDisplayFunction = (stickConfig: GamepadDisplayJoystick, xAxisValue: number, yAxisValue: number) => void;
export interface GamepadDisplayOnOffButton {
type: gamepadButtonType.onOff;
/** The element to add the touch and press classses, to represent touching or pressing on this button */
highlight: HTMLElement | SVGElement;
/** optional, for your own use */
extraData?: any;
}
export interface GamepadDisplayVariableButton {
type: gamepadButtonType.variable;
/** The element to add the touch and press classses to - to represent touching or pressing on this button,
* defaults to the same element as buttonElement */
highlight?: HTMLElement | SVGElement;
/** The element to move to represent pressing on this button */
buttonElement: HTMLElement | SVGElement;
/** How far the {@link GamepadDisplayVariableButton.buttonElement} should move to represent being pressed fully in HTML or SVG pixels */
movementRange: number;
/** Direction the {@link GamepadDisplayVariableButton.buttonElement} should move to represent being pressed */
direction: gamepadDirection;
/** Drag direction indicator / highlight element for this variable button */
directionHighlight?: HTMLElement | SVGElement;
/** optional, for your own use */
extraData?: any;
}
export interface GamepadDisplayJoystick {
joystickElement: HTMLElement | SVGElement;
movementRange: number;
/** Axis index (as returned by the browser gamepad api) to track for the horizontal movement of the display joystick
* see {@link standardGpadAxesMap} */
xAxisIndex?: number;
/** Axis index (as returned by the browser gamepad api) to track for the vertical movement of the display joystick
* see {@link standardGpadAxesMap} */
yAxisIndex?: number;
/** @deprecated
* use {@link GamepadDisplayJoystick.extraData} with a custom {@link DisplayGamepadConfig.joystickDisplayFunction} instead, see the custom gamepads example/demo */
highlights?: {
[gamepadDirection.up]?: HTMLElement | SVGElement | null;
[gamepadDirection.down]?: HTMLElement | SVGElement | null;
[gamepadDirection.left]?: HTMLElement | SVGElement | null;
[gamepadDirection.right]?: HTMLElement | SVGElement | null;
};
/** optional, for your own use */
extraData?: any;
}
export interface DisplayGamepadConfig {
/** The index of the gamepad this Gamepad Display should track as returned from `navigator.GetGamepads()` */
gamepadIndex: number;
/** Configuration for Buttons and Variable Pressure Buttons (eg: shoulder triggers) to represent in the gamepad display
* - The index of the button in the array corresponds to the index of the button as returned by the browser gamepad api.
* - Add null in the array for any button you don't want to track.
* - @see {@link GamepadDisplayButton} and {@link GamepadDisplayVariableButton} {@link standardGpadButtonMap} for more information */
buttons?: (GamepadDisplayButton | null | undefined)[];
/** Configuration for Joysticks to represent in the gamepad display (based on gamepad axes indecies as as returned by the browser gamepad api) */
sticks?: GamepadDisplayJoystick[];
/** The class to add to the corresponding highlight element when a gamepad button is touched (whether or not its pressed) */
touchedHighlightClass?: string;
/** The class to add to the corresponding highlight element when a gamepad button is pressed */
pressedHighlightClass?: string;
/** The class to add to the corresponding direction indicator element when a gamepad joystick is moved in a direction or a variable button is pressed */
moveDirectionHighlightClass?: string;
/** If provided, this function will be called for each button with a state change (pressed, touched, released, etc...)
* @see {@link GamepadDisplay.DefaultButtonDisplayFunction} for an example */
buttonDisplayFunction?: ButtonDisplayFunction;
/** If provided, this function will be called when the gamepad axies change for a joystick instead of the default display function.
* @see {@link GamepadDisplay.DefaultJoystickDisplayFunction} for an example */
joystickDisplayFunction?: JoystickDisplayFunction;
}
/**
* Class to handle displaying the state of a gamepad on the screen.
* This class will not draw anything to the screen. Instead it will update the classes / transforms of the elements
* you provide to represent the buttons and axes of the gamepad. See the examples for more information.
*/
export declare class GamepadDisplay {
protected config: DisplayGamepadConfig;
protected apiWrapper: GamepadApiWrapper;
/** Create a new GamepadDisplay instance
* @param config The config to use for the gamepad display
* @param apiWrapper (OPTIONAL) The gamepad api will use this GamepadApiWrapper instance to listen for gamepad events, otherwise it will create a new gamepad wrapper under the hood.
*/
constructor(config: DisplayGamepadConfig, apiWrapper?: GamepadApiWrapper);
/**
* Function called by default when the gamepad axies change for a joystick (as configured in this GamepadDisplay)
* If you specify your own {@link DisplayGamepadConfig.joystickDisplayFunction} in the config, this function won't get called.
* Instead, you can call this function with the same parameters as passed to the {@link DisplayGamepadConfig.joystickDisplayFunction}
* if you want to keep the default behaviour (and then you can add your own custom behaviour on top)
* @param stickConfig The config for the joystick that has changed (as configured in {@link DisplayGamepadConfig.sticks})
* @param xValue The new x axis value
* @param yValue The new y axis value
*/
readonly DefaultJoystickDisplayFunction: (stickConfig: GamepadDisplayJoystick, xValue: number, yValue: number) => void;
/**
* Function called by default when any gamepad buttons change (called separately for each button (as configured in this GamepadDisplay))
* If you specify your own {@link DisplayGamepadConfig.buttonDisplayFunction} in the config, this function won't get called.
* Instead, you can call this function with the same parameters as passed to the {@link DisplayGamepadConfig.buttonDisplayFunction}
* if you want to keep the default behaviour (and then you can add your own custom behaviour on top)
* @param buttonConfig The config for the button that has changed as configured in {@link DisplayGamepadConfig.buttons}
* @param value The new value of the button
* @param touched Whether the button is currently being touched (unused, but included for consistency with the {@link ButtonDisplayFunction} signature)
* @param pressed Whether the button is currently being pressed (unused, but included for consistency with the {@link ButtonDisplayFunction} signature)
* @param changes The changes that have occurred since the last update
* @param btnIndex The index of the button that has changed (unused, but included for consistency with the {@link ButtonDisplayFunction} signature)
*/
readonly DefaultButtonDisplayFunction: (buttonConfig: GamepadDisplayButton, value: number, touched: boolean, pressed: boolean, changes: buttonChangeDetails, btnIndex: number) => void;
/**
* This function is registered as the callback for {@link GamepadApiWrapper.onGamepadAxisChange()}
* it calls the {@link DisplayGamepadConfig.joystickDisplayFunction} (if specified) or the {@link GamepadDisplay.DefaultJoystickDisplayFunction} otherwise
* for each configured joystick with axies that have changed
* @param gpadIndex The index of the gamepad that has changed
* @param gpadState The new state of the gamepad as reported by the browser
* @param axisChangesMask An array of booleans, where each true indicates that the corresponding axis has changed since the last update
*/
protected displayJoystickChanges: AxisChangeCallback;
/**
* This function is registered as the callback for {@link GamepadApiWrapper.onGamepadButtonChange()}
* it calls the {@link DisplayGamepadConfig.buttonDisplayFunction} (if specified) or the {@link GamepadDisplay.DefaultButtonDisplayFunction} otherwise
* for every button that has changed since the last update
* @param gpadIndex The index of the gamepad that has changed
* @param gpadState The new state of the gamepad as reported by the browser / {@link GamepadApiWrapper.onGamepadButtonChange}
* @param buttonChangesMask An array of buttonChangeDetails or false, where each false in the array indicates that the corresponding button index has not changed since the last update.
* @returns
*/
protected displayButtonChanges: ButtonChangeCallback;
/**
* Cleanup function to remove all event listeners created by the {@link GamepadDisplay}
* Call this function before removing the gamepad display from the DOM or deleting
* the {@link GamepadDisplay} instance to prevent memory leaks
*/
Cleanup(): void;
}