usePointer
Reactive pointer state tracking. Monitors pointerdown, pointermove, pointerup, and pointerleave events, exposing position, pressure, tilt, dimensions, twist, pointer type, and inside state as observables.
Move your pointer (mouse, pen, or touch) to track its state.
import { const usePointer: (options?: DeepMaybeObservable<UsePointerOptions>) => UsePointerReturn
usePointer } from "@usels/web";
function function PointerTracker(): JSX.Element
PointerTracker() { const { const x$: ReadonlyObservable<number>
X coordinate
x$, const y$: ReadonlyObservable<number>
Y coordinate
y$, const pressure$: ReadonlyObservable<number>
Pointer pressure (0-1)
pressure$, const pointerType$: ReadonlyObservable<UsePointerType | null>
Pointer device type
pointerType$, const isInside$: ReadonlyObservable<boolean>
Whether pointer is inside the target
isInside$ } = function usePointer(options?: DeepMaybeObservable<UsePointerOptions>): UsePointerReturn
Framework-agnostic reactive pointer tracker.
Listens to pointerdown / pointermove / pointerup / pointerleave
on a target (default: window resolved via resolveWindowSource) and
exposes position, pressure, tilt, dimensions, twist, pointer type, and
inside state as observables.
usePointer();
return ( <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Position: ({const x$: ReadonlyObservable<number>
X coordinate
x$.ImmutableObservableBase<number>.get(trackingType?: TrackingType | GetOptions): {}
get()}, {const y$: ReadonlyObservable<number>
Y coordinate
y$.ImmutableObservableBase<number>.get(trackingType?: TrackingType | GetOptions): {}
get()})</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Pressure: {const pressure$: ReadonlyObservable<number>
Pointer pressure (0-1)
pressure$.ImmutableObservableBase<number>.get(trackingType?: TrackingType | GetOptions): {}
get()}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Type: {const pointerType$: ReadonlyObservable<UsePointerType | null>
Pointer device type
pointerType$.ImmutableObservableBase<UsePointerType | null>.get(trackingType?: TrackingType | GetOptions): any
get()}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> <JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p>Inside: {const isInside$: ReadonlyObservable<boolean>
Whether pointer is inside the target
isInside$.ImmutableObservableBase<boolean>.get(trackingType?: TrackingType | GetOptions): {}
get() ? "Yes" : "No"}</JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p> </JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div> );}import { createPointer } from "@usels/web";
function PointerTracker() { "use scope" const { x$, y$, pressure$, pointerType$, isInside$ } = createPointer();
return ( <div> <p>Position: ({x$.get()}, {y$.get()})</p> <p>Pressure: {pressure$.get()}</p> <p>Type: {pointerType$.get()}</p> <p>Inside: {isInside$.get() ? "Yes" : "No"}</p> </div> );}Filter by pointer type
Section titled “Filter by pointer type”import { usePointer } from "@usels/web";
function PenOnly() { const { x$, y$, pressure$ } = usePointer({ pointerTypes: ["pen"] });
return ( <p> Pen at ({x$.get()}, {y$.get()}) pressure: {pressure$.get()} </p> );}import { createPointer } from "@usels/web";
function PenOnly() { "use scope" const { x$, y$, pressure$ } = createPointer({ pointerTypes: ["pen"] });
return ( <p> Pen at ({x$.get()}, {y$.get()}) pressure: {pressure$.get()} </p> );}Custom target
Section titled “Custom target”import { useRef$ } from "@usels/core";import { usePointer } from "@usels/web";
function AreaTracker() { const el$ = useRef$<HTMLDivElement>(); const { x$, y$, isInside$ } = usePointer({ target: el$ });
return ( <div ref={el$} style={{ width: 300, height: 300, background: "#eee" }}> {isInside$.get() ? `(${x$.get()}, ${y$.get()})` : "Move pointer here"} </div> );}import { createRef$ } from "@usels/core";import { createPointer } from "@usels/web";
function AreaTracker() { "use scope" const el$ = createRef$<HTMLDivElement>(); const { x$, y$, isInside$ } = createPointer({ target: el$ });
return ( <div ref={el$} style={{ width: 300, height: 300, background: "#eee" }}> {isInside$.get() ? `(${x$.get()}, ${y$.get()})` : "Move pointer here"} </div> );}Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
options | UsePointerOptions (optional) | - |
UsePointerOptions
Section titled “UsePointerOptions”Returns
Section titled “Returns”UsePointerReturn
| Name | Type | Description |
|---|---|---|
x$ | ReadonlyObservable<number> | X coordinate |
y$ | ReadonlyObservable<number> | Y coordinate |
pressure$ | ReadonlyObservable<number> | Pointer pressure (0-1) |
pointerId$ | ReadonlyObservable<number> | Unique pointer identifier |
tiltX$ | ReadonlyObservable<number> | Tilt angle on X axis (-90 to 90) |
tiltY$ | ReadonlyObservable<number> | Tilt angle on Y axis (-90 to 90) |
width$ | ReadonlyObservable<number> | Contact geometry width |
height$ | ReadonlyObservable<number> | Contact geometry height |
twist$ | ReadonlyObservable<number> | Clockwise rotation (0-359) |
pointerType$ | ReadonlyObservable<UsePointerType | null> | Pointer device type |
isInside$ | ReadonlyObservable<boolean> | Whether pointer is inside the target |