Gesture Recognizers

← Events and Gestures
STRVCT

Higher-level state machines that interpret sequences of events as meaningful gestures.

Unified Input Architecture

The browser provides two separate event families for pointing—mouse events on desktop and touch events on mobile—with different semantics, coordinate systems, and lifecycle patterns. Without an abstraction layer, every interactive view needs parallel code paths for both input types, plus logic to prevent ghost clicks and handle edge cases where both fire simultaneously.

Gesture recognizers eliminate this complexity:

  • They consume raw mouse and touch events internally and present a single, input-agnostic interface to the view.
  • A SvPanGestureRecognizer works identically whether driven by a mouse drag or a finger swipe—the view implements onPanBegin once and it works on every device.
  • New interaction features are automatically cross-platform from the first line of code, with no per-device testing or branching required.

Mouse input naturally supports single-finger gestures (tap, pan, long-press, slide). Multi-finger gestures (pinch, rotation) require touch input or desktop Shift-click multi-touch emulation.

1. Raw Mouse / Touch Input Stream Unified input abstraction 2. SvGestureRecognizer State Machine Tracks finger count, timing, movement, hold; Tap, Pan, Pinch, Rotation, LongPress, Slide 3. SvGestureManager Singleton Arbitration Arbitrates competing gestures; Cancels conflicts across view hierarchy 4. Delegate Phase Messages Sent to View onGestureBegin → onGestureMove → onGestureComplete (or onGestureCancelled if interrupted) 5. Application Handler Executes

How Gestures Work

A gesture recognizer is a state machine attached to a view via addGestureRecognizer(). When gesture conditions are met, the recognizer sends delegate messages to the view:

acceptsGestureType(gesture)     — Optional: can the view accept this gesture?
onGestureTypeBegin(gesture)     — Gesture recognized and started
onGestureTypeMove(gesture)      — Gesture in progress
onGestureTypeComplete(gesture)  — Gesture completed successfully
onGestureTypeCancelled(gesture) — Gesture interrupted or cancelled

Complete Gesture Recognizers Suite

Recognizer ClassDetectsPrimary Configuration Settors
SvTapGestureRecognizerSingle or multi-tapsetNumberOfTapsRequired(), setNumberOfFingersRequired(), setMaxHoldPeriod()
SvPanGestureRecognizerClick-and-drag panningsetMinNumberOfFingersRequired(), setMaxNumberOfFingersAllowed()
SvPinchGestureRecognizerTwo-finger pinch/zoomFixed to 2 fingers
SvRotationGestureRecognizerTwo-finger rotationFixed to 2 fingers
SvLongPressGestureRecognizerPress-and-hold gesturesetTimePeriod() (default 500ms)
SvSlideGestureRecognizerDirectional slide`setDirection("left""right""up""down"), setMaxPerpendicularDistToBegin()`
SvEdgePanGestureRecognizerPan starting at view edgeSubclasses for left, right, top, bottom edges
SvScreenEdgePanPan starting at screen boundarySubclasses for left, right, top, bottom screen boundaries

Adding Gestures & Convenience API

// Convenience methods on SvDomView
view.addDefaultTapGesture();       // Single tap
view.addDefaultDoubleTapGesture(); // Double tap
view.addDefaultPanGesture();       // Drag panning

// Custom recognizer configuration
const gesture = SvLongPressGestureRecognizer.clone();
gesture.setTimePeriod(800); // 800ms hold requirement
view.addGestureRecognizer(gesture);

// View implements callback handler
onLongPressComplete (gesture) {
    this.openContextMenu();
}

Global Arbitration (`SvGestureManager`)

SvGestureManager is a singleton that coordinates competing gestures globally across the entire view tree:

  • Priority & Hierarchy: Child views can steal control from parent views.
  • Active Lock: Once a gesture is accepted, competing gestures on the same or ancestor views are automatically cancelled.
  • Explicit Cancellation: Views can cancel gestures programmatically: view.cancelAllGesturesExcept(panGesture).

Cleanup, Teardown & Memory Safety

When a view is retired and unmounted from the DOM hierarchy, prepareToRetire() executes a 3-step cleanup pipeline:

  1. removeAllGestureRecognizers(): Stops each recognizer, removes DOM listeners, and clears the view target.
  2. removeAllListeners(): Unbinds all element-level DOM event listeners.
  3. cancelAllTimeouts(): Clears any pending gesture hold timers.

Weak Reference Timers:

Gesture recognizers use addWeakTimeout() for internal hold delays. addWeakTimeout() holds only a WeakRef to the view target, enabling unmounted views to be reclaimed cleanly by JavaScript's garbage collector without timer leaks.

Multi-Touch Desktop Emulation

On desktop browsers, holding Shift while clicking simulates a second touch point. This allows testing multi-finger pinch, zoom, and rotation gestures using a standard mouse.