Skip to content

Gestures

Gesture modes

The system operates in one of three modes at any time:

ModeTriggerMap effect
IdleNo recognised gestureNone (map stays still)
PanningOne hand in a fistHand movement pans the map
ZoomingTwo open hands visibleMoving hands apart zooms in; together zooms out

Gesture classification

Each video frame is processed by classifyGesture(), which inspects MediaPipe's 21-landmark hand model to determine what gesture each hand is making.

Fist (pan)

A fist is detected when 3 or more fingers are curled. A finger is considered curled when its tip landmark is closer to the wrist than its MCP (knuckle) landmark, meaning the hand is closed inward. The thumb is not counted. When exactly one hand is detected and classified as a fist, the system enters panning mode.

Open palm (zoom)

An open palm is detected when all 4 fingers are extended (tips further from wrist than MCPs) and spread (fingertips are spread apart laterally). When two hands are each classified as open palms, the system enters zooming mode. The distance between the two index fingertips is tracked frame-over-frame; changes above zoomDeadzoneRatio are translated into zoom-level adjustments.

None / idle

Any hand configuration that doesn't match fist or open palm (e.g. pointing, peace sign, partially closed hand) returns 'none'. If no recognised gesture is held, the system returns to idle after the grace period.


State machine flow

The state machine sits between raw gesture classification and map interaction. It prevents accidental triggers using a dwell timer and prevents flickering using a grace period.

                  gesture classified
                        |
           ┌────────────▼────────────┐
           │          IDLE           │
           └────────────┬────────────┘
                        │ same gesture for actionDwellMs (default 80 ms)
           ┌────────────▼────────────┐
           │          ACTIVE         │  ← map interaction happens here
           └────────────┬────────────┘
                        │ gesture stops / changes
           ┌────────────▼────────────┐
           │       GRACE PERIOD      │  (releaseGraceMs, default 150 ms)
           └────────────┬────────────┘
                        │ grace period expires
           ┌────────────▼────────────┐
           │          IDLE           │
           └─────────────────────────┘

If the same gesture resumes during the grace period, the state machine returns to ACTIVE immediately without re-triggering the dwell timer.


Tuning parameters

ParameterDefaultEffect on gestures
actionDwellMs80Lower = gestures activate faster; higher = more stable but slower
releaseGraceMs150Lower = returns to idle faster; higher = more forgiving when hand tracking briefly drops
panDeadzonePx10Lower = reacts to smaller hand movements; higher = filters more tremor
zoomDeadzoneRatio0.005Lower = reacts to smaller spread changes; higher = requires more deliberate zoom gesture
smoothingAlpha0.5Lower = smoother but more latency; higher = snappier but more jitter
minDetectionConfidence0.65Lower = detects more hands in difficult conditions; higher = fewer false detections
minTrackingConfidence0.65Lower = maintains tracking in poor conditions; higher = drops tracking sooner
minPresenceConfidence0.60Lower = keeps hands in frame longer; higher = drops sooner when partially occluded

See Configuration for the full reference and code examples.