Skip to content

@map-gesture-controls/core API Reference ​

The map-agnostic gesture detection engine. All exports are also available from @map-gesture-controls/ol.


Classes ​

GestureController ​

Manages webcam capture and MediaPipe hand landmark detection. Produces a GestureFrame on every video frame.

ts
new GestureController(
  tuning: TuningConfig,
  onFrame: (frame: GestureFrame) => void
)
MethodReturnsDescription
init()Promise<HTMLVideoElement>Opens the webcam, initialises MediaPipe WASM, and returns the video element. Must be awaited before calling start().
start()voidBegins the per-frame detection loop. Call after init() resolves.
stop()voidStops the detection loop and pauses the video stream.
destroy()voidStops detection, closes the webcam stream, and releases all MediaPipe resources.

GestureStateMachine ​

Classifies raw GestureFrame data into stable gesture modes, applying dwell and grace-period timing.

ts
new GestureStateMachine(tuning: TuningConfig)
MethodReturnsDescription
update(frame: GestureFrame)StateMachineOutputProcess one frame and return the current state machine output including mode, deltas, and metadata.
getMode()GestureModeReturn the current active mode without processing a new frame.
reset()voidReset the state machine to idle, clearing all timers and buffered state.

WebcamOverlay ​

Renders the webcam video feed and hand skeleton landmarks on a canvas overlay positioned over the map container.

ts
new WebcamOverlay(config: WebcamConfig)
MethodReturnsDescription
mount(el: HTMLElement)voidInsert the overlay DOM into the given container element.
unmount()voidRemove the overlay DOM from the container.
attachVideo(videoEl: HTMLVideoElement)voidConnect a video element (from GestureController.init()) to the overlay for rendering.
render(frame: GestureFrame | null, mode: GestureMode)voidDraw one frame: video feed, hand skeleton, and colour-coded mode indicator. Pass null for frame to clear the canvas.

Functions ​

classifyGesture ​

ts
function classifyGesture(landmarks: HandLandmark[]): GestureType;

Stateless classification of a single hand from its 21 MediaPipe landmarks. Priority: 'fist' (3+ fingers curled) > 'pinch' (thumb and index tip within 25% of hand size) > 'openPalm' (all fingers extended and spread) > 'none'.

This function has no pinch hysteresis. For per-hand stateful classification that prevents pinch flickering, use createHandClassifier() instead.


createHandClassifier ​

ts
function createHandClassifier(): (landmarks: HandLandmark[]) => GestureType;

Returns a stateful classify function for a single hand. Pinch detection uses hysteresis: the hand enters 'pinch' when thumb and index tips are within 25% of hand size, and stays in 'pinch' until they separate beyond 35% of hand size. This prevents rapid toggling when fingers hover at the entry threshold during a held pinch.

Create one instance per hand (left and right) and reuse it across frames. GestureController does this internally; you only need this function when building a custom detection pipeline.

ts
import { createHandClassifier } from '@map-gesture-controls/core';

const classifyLeft = createHandClassifier();
const classifyRight = createHandClassifier();

// In your frame loop:
const leftGesture = classifyLeft(leftLandmarks);
const rightGesture = classifyRight(rightLandmarks);

getHandSize ​

ts
function getHandSize(landmarks: HandLandmark[]): number;

Returns the Euclidean distance between the wrist landmark and the middle-finger MCP (knuckle) landmark. Used as a normalisation factor to make gesture thresholds scale-invariant with distance from the camera.


getTwoHandDistance ​

ts
function getTwoHandDistance(
  landmarksA: HandLandmark[],
  landmarksB: HandLandmark[],
): number;

Returns the Euclidean distance between the index fingertips of two detected hands.


Constants ​

DEFAULT_WEBCAM_CONFIG ​

ts
const DEFAULT_WEBCAM_CONFIG: WebcamConfig;

Default values for all WebcamConfig keys. Merged with any user-provided partial config.

DEFAULT_TUNING_CONFIG ​

ts
const DEFAULT_TUNING_CONFIG: TuningConfig;

Default values for all TuningConfig keys. See Configuration for the full table.

LANDMARKS ​

ts
const LANDMARKS: {
  WRIST: number;
  THUMB_TIP: number;
  INDEX_TIP: number;
  INDEX_MCP: number;
  MIDDLE_TIP: number;
  MIDDLE_MCP: number;
  RING_TIP: number;
  RING_MCP: number;
  PINKY_TIP: number;
  PINKY_MCP: number;
};

Named indices into MediaPipe's 21-landmark hand array. Use these instead of magic numbers when working with landmarks directly.

COLORS ​

ts
const COLORS: {
  idle: string;
  panning: string;
  zooming: string;
  rotating: string;
  landmark: string;
  connection: string;
  fingertipGlow: string;
};

CSS colour strings used by WebcamOverlay to render the hand skeleton in each gesture mode.


Types ​

GestureMode ​

ts
type GestureMode = 'idle' | 'panning' | 'zooming' | 'rotating';

The active state of the gesture state machine.

GestureType ​

ts
type GestureType = 'fist' | 'pinch' | 'openPalm' | 'none';

The raw classification result for a single hand from classifyGesture() or createHandClassifier().

HandednessLabel ​

ts
type HandednessLabel = 'Left' | 'Right';

Which hand MediaPipe detected.

GestureFrame ​

ts
interface GestureFrame {
  hands: DetectedHand[];
  leftHand: DetectedHand | null;
  rightHand: DetectedHand | null;
  timestamp: number;
}

A single processed video frame. leftHand and rightHand are convenience references into hands for the respective handedness; either is null when that hand is not detected.

DetectedHand ​

ts
interface DetectedHand {
  landmarks: HandLandmark[];
  handedness: HandednessLabel;
  gesture: GestureType;
  score: number;
}

A single detected hand within a GestureFrame. gesture is the classified result for this hand, computed by GestureController using the stateful per-hand classifier.

WebcamConfig ​

Full type for webcam overlay configuration. See Configuration for field descriptions.

TuningConfig ​

Full type for gesture tuning configuration. See Configuration for field descriptions.

StateMachineOutput ​

ts
interface StateMachineOutput {
  mode: GestureMode;
  panDelta: SmoothedPoint | null;
  zoomDelta: number | null;
  rotateDelta: number | null;
}

The output of GestureStateMachine.update(). Contains the current mode plus computed deltas for map interaction.

  • panDelta: normalised wrist movement (0 to 1 range) when mode === 'panning', otherwise null
  • zoomDelta: signed scalar from right wrist vertical movement when mode === 'zooming', otherwise null
  • rotateDelta: signed angle in radians from wrist-to-wrist line rotation when mode === 'rotating', otherwise null

SmoothedPoint ​

ts
interface SmoothedPoint {
  x: number;
  y: number;
}

A 2-D point that has been run through the exponential moving average smoother.

Point2D ​

ts
interface Point2D {
  x: number;
  y: number;
}

A generic 2-D coordinate.

HandLandmark ​

ts
interface HandLandmark {
  x: number; // 0 to 1, normalised
  y: number; // 0 to 1, normalised
  z: number; // depth (relative to wrist)
}

A single MediaPipe hand landmark in normalised image coordinates.