-
Notifications
You must be signed in to change notification settings - Fork 786
Description
Support for element focus:
In interactive 3D applications, if a user holds down a key (e.g., the 'W' key to move forward) and then switches focus to another application (e.g., clicks on a different browser tab, a desktop application, or the operating system taskbar/dock), the browser dispatches a blur event to the application's window (or target DOM element), but it does not necessarily fire a corresponding keyup event for the key that was held down.
This results in the KeyboardControls store keeping the state for that key as true indefinitely. When the user refocuses the application, the useFrame loop still reads the key as being pressed, and the corresponding action (e.g., movement) continues without user input—a "sticky" or "stuck" control issue.
Suggested implementation:
Add a new useEffect block for resetting State on Blur
The added useEffect block specifically listens for the blur event on the target element (window by default, or a specified domElement).
When the blur event occurs (indicating the application has lost focus), the listener immediately resets the entire Zustand state for all controls back to their initial false state:
function onBlur() {
const initialState = map.reduce(
(prev, cur) => ({ ...prev, [cur.name]: false }),
{} satisfies KeyboardControlsState
)
set(initialState)
}
This ensures that even if a keyup event is missed, all control inputs are guaranteed to be in a released state when the application is not in focus, preventing the "sticky" behavior when focus is regained.