pinch

Pinch gesture recognition for two-finger zoom interactions. Tracks distance, ratio, velocity, and center point between two pointers.

Basic Usage

import { pinch } from "cereb";
pinch(element).on((signal) => {
const { phase, ratio, center } = signal.value;
const [cx, cy] = center;
if (phase === "change") {
element.style.transform = `scale(${ratio})`;
}
});

Signature

function pinch(target: EventTarget, options?: PinchOptions): Stream<PinchSignal>

Options

OptionTypeDefaultDescription
thresholdnumber0Minimum distance change (px) before gesture starts

Signal Value

The signal.value contains:

PropertyTypeDescription
phase"start" | "change" | "end" | "cancel"Current gesture phase
initialDistancenumberDistance between pointers at start (px)
distancenumberCurrent distance between pointers (px)
rationumberCurrent distance / initial distance
deltaDistancenumberDistance change since last event (px)
velocitynumberDistance change velocity (px/ms)
center[number, number]Center between pointers [x, y] (client)
pageCenter[number, number]Center between pointers [pageX, pageY] (page)

Phase Lifecycle

two pointers down → (threshold met) → "start" → "change"* → "end" or "cancel"
  • start: Emitted once when threshold is met
  • change: Emitted repeatedly during pinch
  • end: One pointer released normally
  • cancel: Gesture interrupted (e.g., system event)

With Zoom Operator

Combine with the zoom operator for bounded scale calculations:

import { pinch } from "cereb";
import { zoom } from "cereb/operators";
pinch(element)
.pipe(zoom({ minScale: 0.5, maxScale: 3.0 }))
.on((signal) => {
const { scale, center } = signal.value;
const [cx, cy] = center;
element.style.transform = `scale(${scale})`;
});