SkillAgentSearch skills...

Nipplejs

:video_game: A virtual joystick for touch capable interfaces.

Install / Use

/learn @yoannmoinet/Nipplejs
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<picture> <source media="(prefers-color-scheme: dark)" srcset="./assets/nipplejs-dark.svg"> <source media="(prefers-color-scheme: light)" srcset="./assets/nipplejs-light.svg"> <img alt="nipplejs" src="./assets/nipplejs-light.svg"> </picture>

A vanilla virtual joystick for touch capable interfaces

npm npm

Documentation · Interactive Demos · Migration Guide

Table Of Contents <!-- #omit in toc -->

<details> <!-- #toc --> <!-- #toc --> </details>

Install

npm install nipplejs --save

Demo

Check out the interactive demos on the documentation website.


Usage

Import it the way you want into your project :

// CommonJS
var manager = require('nipplejs').create(options);
// AMD
define(['nipplejs'], function (nipplejs) {
    var manager = nipplejs.create(options);
});
// Module
import nipplejs from 'nipplejs';

nipplejs.create(options);
<!-- Global -->
<script src="./nipplejs.js"></script>
<script>
    var manager = nipplejs.create(options);
</script>

:warning: NB :warning: Your joystick's container must have a CSS position value set (relative, absolute, or fixed). Without it, the joystick will not be positioned correctly. The library warns in the console if position: static is detected.


Options

You can configure your joystick in different ways :

var options = {
    zone: Element,                  // active zone
    color: String,
    size: Integer,
    threshold: Float,               // before triggering a directional event
    fadeTime: Integer,              // transition time
    multitouch: Boolean,
    maxNumberOfJoysticks: Number,   // when multitouch, what is too many?
    dataOnly: Boolean,              // no dom element whatsoever
    position: Object,               // preset position for 'static' mode
    mode: String,                   // 'dynamic', 'static' or 'semi'
    restJoystick: Boolean|Object,   // Re-center joystick on rest state
    restOpacity: Number,            // opacity when not 'dynamic' and rested
    lockX: Boolean,                 // only move on the X axis
    lockY: Boolean,                 // only move on the Y axis
    catchDistance: Number,          // distance to recycle previous joystick in 'semi' mode
    shape: String,                  // 'circle' or 'square'
    dynamicPage: Boolean,           // Enable if the page has dynamically visible elements
    follow: Boolean,                // Makes the joystick follow the thumbstick
};

All options are optional :sunglasses:.

options.zone

Defaults to 'body'

The dom element in which all your joysticks will be injected.

<div id="zone_joystick"></div>

<script type="text/javascript" src="./nipplejs.js"></script>
<script type="text/javascript">
    var options = {
        zone: document.getElementById('zone_joystick'),
    };
    var manager = nipplejs.create(options);
</script>

This zone also serve as the mouse/touch events handler.

It represents the zone where all your joysticks will be active.

options.color

Defaults to 'white'

The background of your joystick's elements. Sets the CSS background property, so any valid value works — colors, gradients, images, etc.

Can be a single string (applied to both parts) or an object with front and back keys to style the thumb and base independently.

// Simple color
color: 'rebeccapurple',

// Gradient
color: 'linear-gradient(135deg, #818cf8, #6366f1)',

// Different front (thumb) and back (base)
color: {
    front: 'linear-gradient(135deg, #818cf8, #38bdf8)',
    back: 'rgba(99, 102, 241, 0.12)',
},

// Background image
color: {
    front: 'url(thumb.png) center/cover',
    back: 'radial-gradient(circle, rgba(99,102,241,0.15) 40%, transparent)',
},

options.size

Defaults to 100

The size in pixel of the outer circle.

The inner circle is 50% of this size.

options.threshold

Defaults to 0.1

This is the strength needed to trigger a directional event.

Basically, the center is 0 and the outer is 1.

You need to at least go to 0.1 to trigger a directional event.

options.fadeTime

Defaults to 250

The time it takes for joystick to fade-out and fade-in when activated or de-activated.

options.multitouch

Defaults to false

Enable the multitouch capabilities.

If, for reasons, you need to have multiple nipples in the same zone.

Otherwise, it will only get one, and all new touches won't do a thing.

Please note that multitouch is off when in static or semi modes.

options.maxNumberOfJoysticks

Defaults to 1

If you need to, you can also control the maximum number of instances that could be created.

Obviously in a multitouch configuration.

options.dataOnly

Defaults to false

The library won't draw anything in the DOM and will only trigger events with data.

options.position

Defaults to {top: 0, left: 0}

An object that will determine the position of a static mode.

You can pass any of the four top, right, bottom and left.

They will be applied as any css property.

Ex :

  • {top: '50px', left: '50px'}
  • {left: '10%', bottom: '10%'}

options.mode

Defaults to 'dynamic'.

Three modes are possible :

'dynamic'

  • a new joystick is created at each new touch.
  • the joystick gets destroyed when released.
  • can be multitouch.

'semi'

  • new joystick is created at each new touch farther than options.catchDistance of any previously created joystick.
  • the joystick is faded-out when released but not destroyed.
  • when touch is made inside the options.catchDistance a new direction is triggered immediately.
  • when touch is made outside the options.catchDistance the previous joystick is destroyed and a new one is created.
  • cannot be multitouch.

'static'

  • a joystick is positioned immediately at options.position.
  • one joystick per zone.
  • each new touch triggers a new direction.
  • cannot be multitouch.

options.restJoystick

Defaults to true

Reset the joystick's position when it enters the rest state.

You can pass a boolean value to reset the joystick's position for both the axis.

var joystick = nipplejs.create({
    restJoystick: true,
    // This is converted to {x: true, y: true}

    // OR
    restJoystick: false,
    // This is converted to {x: false, y: false}
});

Or you can pass an object to specify which axis should be reset.

var joystick = nipplejs.create({
    restJoystick: {x: false},
    // This is converted to {x: false, y: true}

    // OR
    restJoystick: {x: false, y: true},
});

options.restOpacity

Defaults to 0.5

The opacity to apply when the joystick is in a rest position.

options.catchDistance

Defaults to 200

This is only useful in the semi mode, and determine at which distance we recycle the previous joystick.

At 200 (px), if you press the zone into a rayon of 200px around the previously displayed joystick, it will act as a static one.

options.lockX

Defaults to false

Locks joystick's movement to the x (horizontal) axis

options.lockY

Defaults to false

Locks joystick's movement to the y (vertical) axis

options.shape

Defaults to 'circle'

The shape of region within which joystick can move.

'circle'

Creates circle region for joystick movement

'square'

Creates square region for joystick movement

options.dynamicPage

Defaults to false

Nuclear option: forces a recalculation of the joystick position on every single move event. This has a notable performance cost.

In most cases you don't need this — the zone is automatically watched with a ResizeObserver that handles size changes. For one-off layout changes (e.g. entering fullscreen, opening a sidebar), call manager.reposition() instead.

Related Skills

View on GitHub
GitHub Stars1.9k
CategoryContent
Updated4d ago
Forks194

Languages

TypeScript

Security Score

100/100

Audited on Mar 22, 2026

No findings