singlePointer
Unified pointer stream that normalizes mouse, touch, and pen inputs into a single interface. Tracks only the primary pointer, ignoring secondary touch points.
npm install --save cerebBasic Usage
import { singlePointer } from "cereb";
singlePointer(element).on((signal) => { const { phase, cursor, pointerType } = signal.value; const [x, y] = cursor;
if (phase === "start") { console.log(`${pointerType} started at (${x}, ${y})`); }});Signature
function singlePointer(target: EventTarget, options?: SinglePointerOptions): Stream<SinglePointerSignal>Signal Value
The signal.value contains:
| Property | Type | Description |
|---|---|---|
phase | "start" | "move" | "end" | "cancel" | Current pointer phase |
cursor | [number, number] | Current position [x, y] (client) |
pageCursor | [number, number] | Current position [pageX, pageY] (page) |
pointerType | "mouse" | "touch" | "pen" | "unknown" | Input device type |
button | "none" | "primary" | "secondary" | ... | Mouse button pressed |
pressure | number | Pressure value (0.0-1.0, default 0.5) |
id | string | Unique pointer identifier |
Phase Lifecycle
pointer down → "start" → "move"* → "end" or "cancel"- start: Pointer pressed/touched
- move: Pointer moving while pressed
- end: Pointer released normally
- cancel: Pointer interrupted (e.g., system event)
Primary Pointer Only
singlePointer tracks only the primary pointer. When multiple fingers touch the screen, secondary touch points are ignored:
// Even with multiple fingers, only the first touch is trackedsinglePointer(canvas).on((signal) => { // signal.value contains only primary pointer data const [x, y] = signal.value.cursor; drawAt(x, y);});This makes it ideal for drawing apps, drag interactions, and single-point gestures.
With Operators
Combine with operators for gesture recognition:
import { singlePointer } from "cereb";import { session, offset } from "cereb/operators";
singlePointer(element) .pipe( session(), // Group start → end as one session offset({ target }) // Add element-relative coordinates ) .on((signal) => { const [offsetX, offsetY] = signal.value.offset; element.style.left = `${offsetX}px`; element.style.top = `${offsetY}px`; });Multi-pointer Handling
For tracking multiple touch points simultaneously, use multiPointers instead:
import { multiPointers } from "cereb";
multiPointers(element).on((signal) => { // Tracks all active pointers const pointers = signal.value.pointers; console.log(`${pointers.length} active touch points`);});See the multiPointers documentation for details.