Events

Events

nipplejs uses an event system that bubbles upward through three layers: Joystick -> Collection -> Factory. You can subscribe at any level using .on(type, handler) and unsubscribe with .off(type, handler).

All handlers receive a single argument (evt) with evt.type, evt.target, and evt.data.

Joystick Events

These events are emitted on individual joystick instances.

start

Fired when the joystick is activated (user pressed down).

joystick.on('start', (evt) => {
    console.log('Joystick activated', evt.data.uid);
});

end

Fired when the joystick is deactivated (user released).

joystick.on('end', (evt) => {
    console.log('Joystick released');
});

move

Fired continuously while the joystick is being moved. evt.data contains:

{
    position: { x: number, y: number },
    force: number,          // 0-1 normalized strength
    distance: number,       // pixels from center
    pressure: number,       // touch pressure 0-1
    angle: { radian: number, degree: number },
    vector: { x: number, y: number },  // unit vector
    raw: { distance: number, position: { x: number, y: number } },
    instance: Joystick,
    direction?: { x?: string, y?: string, angle?: string },
    baseDelta: { x: number, y: number }  // base movement when follow: true
}

baseDelta contains the per-frame displacement of the joystick base when follow: true is active and the thumb exceeds the joystick radius. Always { x: 0, y: 0 } when follow is disabled or the thumb is within bounds. Useful for separating fine aim (vector) from camera/world panning (baseDelta).

manager.on('move', (evt) => {
    console.log(evt.data.vector);      // { x: 0.71, y: -0.71 }
    console.log(evt.data.force);       // 0.85
    console.log(evt.data.baseDelta);   // { x: 3.2, y: -1.5 } when following
});

dir

Fired when the joystick crosses a directional threshold. Uses a 45-degree split to determine one of four cardinal directions: up, down, left, or right.

You can listen to all directional changes or subscribe to a specific direction:

  • dir — any direction change
  • dir:up — moving upward
  • dir:down — moving downward
  • dir:left — moving left
  • dir:right — moving right
manager.on('dir', (evt) => {
    console.log(evt.data.direction); // { angle: 'up' }
});

manager.on('dir:left', (evt) => {
    console.log('Moving left');
});

plain

Fired using a 90-degree split, which means two plain events can fire simultaneously (e.g. plain:up and plain:left when the joystick is in the upper-left quadrant).

  • plain — any plain direction change
  • plain:up — moving upward
  • plain:down — moving downward
  • plain:left — moving left
  • plain:right — moving right
manager.on('plain:up plain:left', (evt) => {
    console.log('Upper-left region');
});

shown

Fired at the end of the fade-in animation when the joystick becomes visible. Not emitted in dataOnly mode.

hidden

Fired at the end of the fade-out animation when the joystick finishes disappearing. Not emitted in dataOnly mode.

rested

Fired when the joystick thumb has returned to the rest (center) position after being released.

added

Fired when a joystick element is added to the DOM.

removed

Fired when a joystick element is removed from the DOM. Only fires in dynamic mode where joysticks are created and destroyed per touch.

joystickCreated

Fired when a new joystick instance is created.

joystickDestroyed

Fired when a joystick instance is destroyed.

attached

Fired when a joystick is attached to a touch or pointer identifier. This links the joystick to a specific finger or pointer so it can track movement.

detached

Fired when a joystick is detached from its touch or pointer identifier. This happens when the user lifts their finger or the pointer is released.

pressure

Fired when the pressure value changes (on devices that support force touch or 3D touch). The value ranges from 0 to 1.

joystick.on('pressure', (evt) => {
    console.log(evt.data); // 0.0 - 1.0
});

Collection Events

All joystick events bubble up to the collection (manager). You can listen for any joystick event at the collection level:

const manager = nipplejs.create(options);

manager.on('move', (evt) => {
    // Fires for any joystick in this collection
    console.log(evt.data.instance.uid, evt.data.vector);
});

To target events from a specific joystick, prefix the event name with the joystick’s uid:

manager.on('0:move', (evt) => {
    // Only fires for joystick with uid 0
    console.log(evt.data.vector);
});

In addition to the bubbled joystick events, collections emit:

collectionCreated

Fired when the collection is initialized after calling nipplejs.create().

collectionDestroyed

Fired when the collection is destroyed via manager.destroy().

Factory Events

All collection events bubble up to the factory (nipplejs.factory). This means you can listen for any joystick or collection event at the factory level, across all collections.

nipplejs.factory.on('move', (evt) => {
    // Fires for any joystick in any collection
    console.log(evt.data.instance.uid, evt.data.vector);
});

In addition to the bubbled events, the factory emits:

factoryCreated

Fired when the factory singleton is initialized.

factoryDestroyed

Fired when the factory is destroyed.