Skip to content
Sensors

usePointerLock

Reactive wrapper around the Pointer Lock API. Captures the pointer so that mouse movement events are delivered regardless of cursor position, useful for games and 3D interactions.

Pointer Lock
Not Supported

Click the card to lock the pointer, then move your mouse to rotate it. Press Escape to release.

🖱️Click to drag
import {
const usePointerLock: () => UsePointerLockReturn
usePointerLock
} from "@usels/web";
function
function PointerLockDemo(): JSX.Element
PointerLockDemo
() {
const {
const isSupported$: ReadonlyObservable<boolean>
isSupported$
,
const element$: ReadonlyObservable<OpaqueObject<Element> | null>

Currently locked element

element$
,
const lock: (target: Element | Event) => void

Request pointer lock on a target element or event's currentTarget

lock
,
const unlock: () => void

Release pointer lock

unlock
} =
function usePointerLock(): UsePointerLockReturn

Framework-agnostic reactive pointer-lock controller.

Listens to pointerlockchange / pointerlockerror on document and exposes the currently locked element as an Observable. lock() / unlock() request and release the pointer lock via the Pointer Lock API.

usePointerLock
();
return (
<
JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
>
<
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>Supported: {
const isSupported$: ReadonlyObservable<boolean>
isSupported$
.
ImmutableObservableBase<boolean>.get(trackingType?: TrackingType | GetOptions): {}
get
() ? "Yes" : "No"}</
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>
<
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>Locked: {
const element$: ReadonlyObservable<OpaqueObject<Element> | null>

Currently locked element

element$
.
ImmutableObservableBase<OpaqueObject<Element> | null>.get(trackingType?: TrackingType | GetOptions): any
get
() ? "Yes" : "No"}</
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>
<
JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick
={(
e: MouseEvent<HTMLButtonElement, MouseEvent>
e
) =>
const lock: (target: Element | Event) => void

Request pointer lock on a target element or event's currentTarget

lock
(
e: MouseEvent<HTMLButtonElement, MouseEvent>
e
)}>Lock</
JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
>
<
JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
DOMAttributes<HTMLButtonElement>.onClick?: MouseEventHandler<HTMLButtonElement> | undefined
onClick
={() =>
const unlock: () => void

Release pointer lock

unlock
()}>Unlock</
JSX.IntrinsicElements.button: DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
>
</
JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
>
);
}
import { usePointerLock } from "@usels/web";
import { useRef$ } from "@usels/core";
function GameCanvas() {
const canvas$ = useRef$<HTMLCanvasElement>();
const { element$, lock, unlock } = usePointerLock();
const handleClick = () => {
const el = canvas$.current;
if (el) lock(el);
};
return <canvas ref={canvas$} onClick={handleClick} width={800} height={600} />;
}

UsePointerLockReturn

NameTypeDescription
element$ReadonlyObservable<OpaqueObject<Element> | null>Currently locked element
lock(target: Element | Event) => voidRequest pointer lock on a target element or event’s currentTarget
unlock() => voidRelease pointer lock
isSupported$ReadonlyObservable<boolean>-

View on GitHub