MCPcopy
hub / github.com/yoannmoinet/nipplejs

github.com/yoannmoinet/nipplejs @v1.0.4 sqlite

repository ↗ · DeepWiki ↗ · release v1.0.4 ↗
297 symbols 731 edges 58 files 2 documented · 1%
README

nipplejs

A vanilla virtual joystick for touch capable interfaces

npm npm

Documentation · Interactive Demos · Migration Guide

Table Of Contents

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);

<script src="https://github.com/yoannmoinet/nipplejs/raw/v1.0.4/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.







<script type="text/javascript" src="https://github.com/yoannmoinet/nipplejs/raw/v1.0.4/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. Only enable dynamicPage as a last resort when the zone's position changes continuously without resizing (e.g. CSS animations that shift the zone).

options.follow

Defaults to false

Makes the joystick follow the thumbstick when it reaches the border. When the base moves, the move event includes baseDelta: { x, y } with the per-frame base displacement — use vector for fine aim and baseDelta for camera/world panning.


API

NippleJS instance (manager)

Your manager has the following signature :

{
    on: Function,                       // handle internal event
    off: Function,                      // un-handle internal event
    destroy: Function,                  // destroy everything
    reposition: Function,               // recalculate joystick positions
    uid: Number,                        // unique id of the manager
    all: Map,                           // map of all joysticks by uid
    options: {
        zone: Element,                  // reactive zone
        multitouch: Boolean,
        maxNumberOfJoysticks: Number,
        mode: String,
        position: Object,
        catchDistance: Number,
        size: Number,
        threshold: Number,
        color: String,
        fadeTime: Number,
        dataOnly: Boolean,
        restJoystick: Boolean,
        restOpacity: Number
    }
}

manager.on(type, handler)

If you wish to listen to internal events like :

manager.on('event#1 event#2', function (evt) {
    // evt.type, evt.data
});

Note that you can listen to multiple events at once by separating them either with a space or a comma (or both, I don't care).

manager.off([type, handler])

To remove an event handler :

manager.off('event', handler);

If you call off without arguments, all handlers will be removed.

If you don't specify the handler but just a type, all handlers for that type will be removed.

manager.destroy()

Gently remove all joysticks from the DOM and unbind all events.

manager.destroy();

manager.uid

The unique id of this manager.

manager.reposition()

Recalculate the zone bounding box and all joystick positions. Call this after the zone element has been moved, resized, or when its layout has changed (e.g. entering fullscreen).

Note: the zone is automatically watched with a ResizeObserver, so you only need to call this manually for position changes that don't involve a resize.

manager.reposition();

Logging

Control the library's console output.

nipplejs.setLogLevel('debug');   // all logs
nipplejs.setLogLevel('info');    // info, warnings, errors
nipplejs.setLogLevel('warning'); // warnings and errors (default)
nipplejs.setLogLevel('error');   // errors only
nipplejs.setLogLevel('none');    // silent

nipplejs.getLogLevel(); // returns current level

nipple instance (joystick)

Each joystick has the following signature :

{
    on: Function,
    off: Function,
    destroy: Function,
    setPosition: Function,
    identifier: Number,
    trigger: Function,
    position: {             // position of the center
        x: Number,
        y: Number
    },
    frontPosition: {        // position of the front part
        x: Number,
        y: Number
    },
    ui: {
        el: Element,        // the joystick container element
        front: Element,     // the inner (movable) part
        back: Element       // the outer (static) part
    },
    options: {
        color: String,
        size: Number,
        threshold: Number,
        fadeTime: Number
    }
}

joystick.on, joystick.off

The same as the manager.

joystick.ui

The object that stores the joystick's DOM elements.

{
    el: Element,    // 

 — the container
    back: Element,  // 

 — the outer circle
    front: Element  // 

 — the inner circle
}

Extension points exported contracts — how you extend this code

GameInstance (Interface)
(no doc) [1 implementers]
packages/docs/src/games/types.ts
CustomMatchers (Interface)
(no doc)
packages/tests/src/_jest/setupAfterEnv.ts
CommonOptions (Interface)
(no doc)
packages/nipplejs/src/types.ts
Enemy (Interface)
(no doc)
packages/docs/src/games/dual-stick-arena.ts
NonCustomMatchers (Interface)
(no doc)
packages/tests/src/_jest/setupAfterEnv.ts
JoystickOptions (Interface)
(no doc)
packages/nipplejs/src/types.ts
Projectile (Interface)
(no doc)
packages/docs/src/games/dual-stick-arena.ts
Expect (Interface)
(no doc)
packages/tests/src/_jest/setupAfterEnv.ts

Core symbols most depended-on inside this repo

on
called by 101
packages/nipplejs/src/Super.ts
create
called by 58
packages/nipplejs/src/Factory.ts
destroy
called by 48
packages/docs/src/games/types.ts
trigger
called by 46
packages/nipplejs/src/Super.ts
init
called by 36
packages/nipplejs/src/Joystick.ts
log
called by 33
packages/nipplejs/src/Super.ts
error
called by 15
packages/nipplejs/src/Super.ts
processOnStart
called by 14
packages/nipplejs/src/Collection.ts

Shape

Function 175
Method 77
Interface 33
Class 12

Languages

TypeScript100%

Modules by API surface

packages/docs/src/games/dual-stick-arena.ts28 symbols
packages/docs/src/games/neon-snake.ts27 symbols
packages/docs/src/games/space-observatory.ts24 symbols
packages/docs/src/games/space-drift.ts23 symbols
packages/docs/src/games/asteroid-dodge.ts23 symbols
packages/nipplejs/src/Joystick.ts21 symbols
packages/nipplejs/src/Factory.ts19 symbols
packages/nipplejs/src/utils.ts17 symbols
packages/nipplejs/src/Super.ts17 symbols
packages/nipplejs/src/Collection.ts17 symbols
packages/tests/src/_jest/setupAfterEnv.ts10 symbols
packages/tools/bin/copyToGhPages.js8 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

Dependencies from manifests, versioned

@astrojs/check0.9.8 · 1×
@astrojs/mdx5 · 1×
@nipple/assetsworkspace:* · 1×
@nipple/toolsworkspace:* · 1×
@playwright/test1.49.1 · 1×
@rollup/plugin-commonjs28.0.1 · 1×
@rollup/plugin-esm-shim0.1.8 · 1×
@rollup/plugin-json6.1.0 · 1×
@rollup/plugin-node-resolve15.3.0 · 1×
@rollup/plugin-terser0.4.4 · 1×
@types/chalk2.2.0 · 1×

For agents

$ claude mcp add nipplejs \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact