Input System

Unified pointer events, gestures, and coordinate transformation.

Object-Level Events

import { ElementObject } from "@snap-engine/core";

const object = new ElementObject(engine);
object.element = myElement;

object.event.input.pointerDown = (props) => {
  console.log(props.position.x, props.position.y);
};

object.event.input.pointerMove = (props) => {
  console.log(props.position.cameraX, props.position.cameraY);
};

object.event.input.pointerUp = (props) => {
  console.log(props.position.screenX, props.position.screenY);
  console.log(props.cancelled);
};

object.event.input.mouseWheel = (props) => {
  console.log(props.delta);
};

Global Events

object.event.global.pointerMove = (props) => {
  console.log(props.position.x, props.position.y);
};

object.event.global.mouseWheel = (props) => {
  console.log(props.delta);
};

Drag Gestures

object.event.input.dragStart = (props) => {
  console.log(props.start.x, props.start.y);
};

object.event.input.drag = (props) => {
  console.log(props.position.x, props.position.y);
  console.log(props.delta.x, props.delta.y);
};

object.event.input.dragEnd = (props) => {
  console.log(props.end.x, props.end.y);
  console.log(props.event.target, props.cancelled);
};

Gesture handoff

Only active derived gestures expose handoff: dragStart, drag, pinchStart, and pinch. The destination may be a connected ElementObject or its engine object ID.

handle.event.input.dragStart = (props) => {
  props.handoffTo(draggable);
};

Drag handoff transfers native pointer capture and changes targeted delivery for later drag events. It does not emit cancellation to the previous owner and does not turn global subscriptions into owner callbacks. Invalid, destroyed, cross-engine, headless, or disconnected destinations throw synchronously. Pinch handoff moves only pinch/pinchEnd delivery; each finger’s native capture and pointer/drag delivery remain with its origin.

Native capture begins when a drag or pinch is recognized, not on pointerDown, so nested buttons and other pre-threshold controls retain their normal click targeting.

handoffTo is intentionally absent from pointerDown, pointerMove, pointerUp, dragEnd, and pinchEnd.

Pinch Gestures

object.event.input.pinchStart = (props) => {
  console.log(props.start.distance);
  console.log(props.start.pointerList);
};

object.event.input.pinch = (props) => {
  const scale = props.current.distance / props.start.distance;
  console.log(scale);
};

object.event.input.pinchEnd = (props) => {
  console.log(props.end.pointerList);
  console.log(props.cancelled);
};

Targeted bubbling and global fan-out

Targeted handlers run on a snapshot of the original owner-to-parent path, leaf first. A handler failure is isolated, so later ancestors and global listeners still run. There is no propagation-stop API.

Global listeners run after targeted delivery. Claiming a pointer suppresses non-terminal global delivery for that gesture; terminal events still fan out so already-engaged listeners can clean up.

Event Position

PropertyDescription
screenX, screenYBrowser viewport coordinates.
cameraX, cameraYCoordinates relative to the engine container.
x, yWorld coordinates after camera conversion.

Event Names

EventScope
pointerDownObject and global
pointerMoveObject and global
pointerUpObject and global
mouseWheelObject and global
dragStartObject and global
dragObject and global
dragEndObject and global
pinchStartObject and global
pinchObject and global
pinchEndObject and global