GithubHelp home page GithubHelp logo

yoannmoinet / nipplejs Goto Github PK

View Code? Open in Web Editor NEW
1.7K 29.0 177.0 1.46 MB

:video_game: A virtual joystick for touch capable interfaces.

Home Page: https://yoannmoinet.github.io/nipplejs

License: MIT License

JavaScript 66.34% HTML 25.10% CSS 8.56%
joystick frontend dom vanilla-javascript dependency-free

nipplejs's Introduction

alt tag

A vanilla virtual joystick for touch capable interfaces

npm npm

Table Of Contents

Install

npm install nipplejs --save

Demo

Check out the demo here.


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';
<!-- Global -->
<script src="./nipplejs.js"></script>
<script>
    var manager = nipplejs.create(options);
</script>

⚠️ NB ⚠️ Your joystick's container has to have its CSS position property set, either absolute, relative, static, ....


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,
    maxNumberOfNipples: 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 😎.

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 color of your joystick's elements.

Can be any valid CSS color.

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.maxNumberOfNipples 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

Enable if the page has dynamically visible elements such as for Vue, React, Angular or simply some CSS hiding or showing some DOM.

options.follow defaults to false

Makes the joystick follow the thumbstick when it reaches the border.


API

NippleJS instance (manager)

Your manager has the following signature :

{
    on: Function,                       // handle internal event
    off: Function,                      // un-handle internal event
    get: Function,                      // get a specific joystick
    destroy: Function,                  // destroy everything
    ids: Array                          // array of assigned ids
    id: Number                          // id of the manager
    options: {
        zone: Element,                  // reactive zone
        multitouch: Boolean,
        maxNumberOfNipples: 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, data) {
    // Do something.
});

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.get(identifier)

A helper to get an instance via its identifier.

// Will return the nipple instantiated by the touch identified by 0
manager.get(0);

manager.destroy()

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

manager.destroy();

manager.ids

The array of nipples' ids under this manager.

manager.id

The incremented id of this manager.

nipple instance (joystick)

Each joystick has the following signature :

{
    on: Function,
    off: Function,
    el: Element,
    show: Function,         // fade-in
    hide: Function,         // fade-out
    add: Function,          // inject into dom
    remove: Function,       // remove from dom
    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,
        front: Element,
        back: Element
    },
    options: {
        color: String,
        size: Number,
        threshold: Number,
        fadeTime: Number
    }
}

joystick.on, joystick.off

The same as the manager.

joystick.el

Dom element in which the joystick gets created.

<div class="nipple">
    <div class="front"></div>
    <div class="back"></div>
</div>

joystick.show([cb])

Will show the joystick at the last known place.

You can pass a callback that will be executed at the end of the fade-in animation.

joystick.hide([cb])

Will fade-out the joystick.

You can pass a callback that will be executed at the end of the fade-out animation.

joystick.add()

Add the joystick's element to the dom.

joystick.remove()

Remove the joystick's element from the dom.

joystick.destroy()

Gently remove this nipple from the DOM and unbind all related events.

joystick.setPosition(cb, { x, y })

Set the joystick to the specified position, where x and y are distances away from the center in pixels. This does not trigger joystick events.

joystick.identifier

Returns the unique identifier of the joystick.

Tied to its touch's identifier.

joystick.trigger(type [, data])

Trigger an internal event from the joystick.

The same as on you can trigger multiple events at the same time.

joystick.position

The absolute position of the center of the joystick.

joystick.frontPosition

The absolute position of the back part of the joystick's ui.

joystick.ui

The object that store its ui elements

{
    el: <div class="nipple"></div>
    back: <div class="back"></div>
    front: <div class="front"></div>
}

Events

You can listen events both on the manager and all the joysticks.

But some of them are specific to its instance.

If you need to listen to each joystick, for example, you can :

manager.on('added', function (evt, nipple) {
    nipple.on('start move end dir plain', function (evt) {
        // DO EVERYTHING
    });
}).on('removed', function (evt, nipple) {
    nipple.off('start move end dir plain');
});

manager only

added

A joystick just got added.

Will pass the instance alongside the event.

removed

A joystick just got removed.

Fired at the end of the fade-out animation.

Will pass the instance alongside the event.

Won't be trigger in a dataOnly configuration.

manager and joysticks

Other events are available on both the manager and joysticks.

When listening on the manager, you can also target a joystick in particular by prefixing the event with its identifier, 0:start for example.

Else you'll get all events from all the joysticks.

start

A joystick is activated. (the user pressed on the active zone)

Will pass the instance alongside the event.

end

A joystick is de-activated. (the user released the active zone)

Will pass the instance alongside the event.

move

A joystick is moved.

Comes with data :

{
    identifier: 0,              // the identifier of the touch/mouse that triggered it
    position: {                 // absolute position of the center in pixels
        x: 125,
        y: 95
    },
    force: 0.2,                 // strength in %
    distance: 25.4,             // distance from center in pixels
    pressure: 0.1,              // the pressure applied by the touch
    angle: {
        radian: 1.5707963268,   // angle in radian
        degree: 90
    },
    vector: {                   // force unit vector
      x: 0.508,
      y: 3.110602869834277e-17
    },
    raw: {                      // note: angle is the same, beyond the 50 pixel limit
        distance: 25.4,         // distance which continues beyond the 50 pixel limit
        position: {             // position of the finger/mouse in pixels, beyond joystick limits
            x: 125,
            y: 95
        }
    },
    instance: Nipple            // the nipple instance that triggered the event
}

dir

When a direction is reached after the threshold.

Direction are split with a 45° angle.

//     \  UP /
//      \   /
// LEFT       RIGHT
//      /   \
//     /DOWN \

You can also listen to specific direction like :

  • dir:up
  • dir:down
  • dir:right
  • dir:left

In this configuration only one direction is triggered at a time.

plain

When a plain direction is reached after the threshold.

Plain directions are split with a 90° angle.

//       UP               |
//     ------        LEFT | RIGHT
//      DOWN              |

You can also listen to specific plain direction like :

  • plain:up
  • plain:down
  • plain:right
  • plain:left

In this configuration two directions can be triggered at a time, because the user could be both up and left for example.

shown

Is triggered at the end of the fade-in animation.

Will pass the instance alongside the event.

Won't be trigger in a dataOnly configuration.

hidden

Is triggered at the end of the fade-out animation.

Will pass the instance alongside the event.

Won't be trigger in a dataOnly configuration.

destroyed

Is triggered at the end of destroy.

Will pass the instance alongside the event.

pressure

MBP's Force Touch, iOS's 3D Touch, Microsoft's pressure or MDN's force

Is triggered when the pressure on the joystick is changed.

The value, between 0 and 1, is sent back alongside the event.


Contributing

You can follow this document to help you get started.

nipplejs's People

Contributors

alexanderhenne avatar alexistm avatar bealeofsteel avatar bhavishya-sahdev avatar davestevens avatar dependabot[bot] avatar emepetres avatar graemef avatar hippiewho avatar htshah avatar icholy avatar iodev avatar johnshaughnessy avatar kr4b avatar mcarth avatar mlknz avatar nekocode avatar ollwenjones avatar philippemorier avatar rowlowles avatar sjml avatar yoannmoinet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nipplejs's Issues

Broken dataOnly parameter.

Created dynamic nipple with dataOnly: true parameter.
On touch having this in Chrome / Ubuntu:
nipplejs.js:336 Uncaught TypeError: Cannot read property 'stylize' of undefined

In code:
this.buildEl().stylize();

At the very beggining of buildEl function:
if (this.options.dataOnly) { return; }

how to show degree

html
<div id="myElement">
	joystatus: <span id="joystatus"></span>
	angle: <span id="angledegree"></span> i need to show angle degree here
	distance: <span id="distance"></span> i need to show distance here
</div>

<script>
function joystick(){
        var joystick = nipplejs.create({
            zone: document.getElementById('joystick'),
            mode: 'static',
            position: { left: '50%', top: '50%' },
            color: 'red',
            size: 100,
			        });
		console.log(joystick);
		joystick.on("end move"
		, function (evt) {		
		//Modifiable
		var joystatus = (evt.type == 'end')?'stop' : evt.type;
		debug(data);
		var angledegree = data.angle.degree;
		var distance = data.distance;
		document.getElementById("distance").innerHTML = distance;
		//--Modifiable	
                });
		


  };		
joystick(document.querySelector("#joystick"));	
</script>

how can i show angle degree and distance tell me plz

Container div offset causes weird hitbox issues

The div that is created by nipplejs to contain the two circle divs has a very odd offset where the top-left corner is the centre. You can see in the screenshot below via. Chrome. You can also see this in the hosted demos by selecting the element in your browser's developer tools.

The problem is twofold:

  1. It overlaps with other elements, stealing their clicks.
  2. It makes the area that controls the joystick inconsistent.

This bug seems to have been masked by the fact that it isn't evident if you have a large enough area for your joystick to work in.

njs_hitbox

Joystick is not released when moved out of the window only chrome and IE

For a static joystick, when we drag the joystick outside the position where it exists, the joystick is not released and we have to do an extra click to release it.

Steps:

  1. drag the joystick outside the position where it is created (like into the white space.)
  2. Observe that it is not released.

Add an option `follow` to the joystick

This will make the joystick follow the finger/cursor when going farther than the back circle.

This way, it will allow to have a revert movement way faster and shorter than with a fixed joystick.

Idea: Create the d.ts Typescript type definitions

Being the best touch-joystick lib available on the market you could maybe publish on DefinitelyTyped the d.ts definitions to support Typescript.

This will help both the users of your library and you by promoting it :)

Just an idea....

custom domain

If you are interested in an additional custom domain for free (e.g. _nipple.js.org_) check out dns.js.org

Possible bug when changing orientation?

Hi!

First of all, thanks for your contribution, it's being very useful in my project. Second, I'm kind of newbie in web design, so please, bear with me if this is just my fault and not a real bug!

I realized that when using a virtual joystick (in static mode) in a tactile device, if you perform a window rotation in the precise moment you are also pressing the joystick, the object gets frozen and it's impossible to use it again. I tried to .destroy() the joystick object when detecting a window.onorientationchange event, and then inject it again, but apart from not elegant, that created me some other problem with other elements event/handlers.

I am the only one who has experienced that behaviour? I also tried it in the demo web-page and I had the same issue. Any idea to workaround this?

Thanks!

Help to make nipplejs works on React Native

Hi,

I would like to get nipplejs works on React Native, or alternative package on react native also helpful.
Do you have any plan to support/porting nipplejs to React Native? Or can you give me a quick guide?

Thank you.

How to delicately remove the nipple?

First, kudos for this tool!

I have a need to create 2 nipples, on the same el, the second after shutting down the first, with some other parameters. Or maybe there is a way to change a nipple size after initialisation?

Simultaneous touch events

Has anyone experimented with a way to emulate the ability to simultaneously use the joystick and touch other elements like buttons, dragging a map around, etc. ?

I have luck getting multiple joysticks to work together, but have not had any luck getting a joystick and a button to work together.

mouse coords offset

I have a nipple working in a div with class scPanner which is enclosed in a flexbox

.scPanner {
    position: absolute;
    width: 88px;
    height: 88px;
    background: yellow;
}

and create it the following code...

            scope.nipple = element[0].querySelector('.scPanner');

            var options = {
                zone: scope.nipple,
                mode: 'static',
                color: 'red',
                position: {
                    left: '50px',
                    top: '50px'
                },
                size: 44
            };

            var nipple = nipplejs.create(options);

When I click on the nipple, the inner circle shoots up to the top. If I drag the mouse down so the mouse pointer is below the scPanner div about the height of scPanner (~88px) then the inner circle will center and if I continue moving the mouse down, the inner circle will drop below the nipple's vertical centerline.

Any idea what is confusing the nipple's mouse coordinate code? Only tried it in Chrome53 on Win10.

Refresh 'center' coordinates for nipple

Hiya. I'm working with nipplejs and have a function that builds nipples from a configuration json file. My web app uses shapeshift to make things draggable. So, essentially all my of modules (including my nipples) get built in a div like this:
image
And then the shapeshift function is called to sort everything to look like this:
image
However, there's one small issue. Since the nipples first rendered as in the first photo, the createNipple function set the 'center' (I guess x,y position) there, so when shapeshift moves everything around, the nipples still think the 'center' x,y positions are originally where they were created.
I made a fix for this by just creating the container div's for the nipples, calling shapeshift, and then having the nipples be created after the fact so that they work properly (as in the second photo). I was wondering if there was a way to update the x, y position for a certain nipple, or all nipples, whenever the location of their div moves around?

Let me know if you want to see my code or if I need to explain things better. Thanks!

Gonzo

Unable to scale up distance

Hi I need a more precise distance, to control my RC car with this.
It works ok with out of 100 distance, but for turning left and right I need 10x more accuracy, because the distance is linked to the angle of the direction of the car.
Is there a way to modify it to show value between 0-1000 instead of 0-100?

I cannot simply multiply the distance by 10, because when it maps to servo angle, it will skip some degrees of the angles. The servo works on the frequency of PWM between 1000-2000. 1500 is mid. 1000 is total left. 2000 is right.
So when I map it, it goes like this....
1 = 10
2 = 20
3 = 30

I want to be able to go into more angle instead of jumping 10 steps all the time.

Is there anything I can modify to achieve it?

Add a more interactive demo

A little and basic spaceship game.
Dual joystick for touch interfaces (shoot and move).
Solo joystick for mouse interfaces (shoot). Move will be done with WASD.

IIssue with IE 11

Hello!

I have the following issue. We have deployed the NipplesJS to the following software. Please see link: http://ec2-54-78-224-212.eu-west-1.compute.amazonaws.com/et/pano/show/1441792/separate On the right bottom corner there is deployed the nipplesJS.

The issue is that in IE11 there is no the so called Joystick ball (it doesn't show up) The Firefox and chrome are displaying joystick ball correctly. No problems with FF and Chrome.

If you debugg it you will see error Object doesn't support property or method 'contains'. You can debugg it yourself.

Please help, any suggestions what we have to do to make joystick ball to show up in IE 11.

Thanks in advance,

Christo

Calling `stylize` after init

Is it possible to call stylize after I have inited static nipple? I would like it to recalculate the size and position if I change the options.

Suggestion: Reset events on release

Just a small suggestion (reproducible via your demo too) for improving usage of "dir" events:

  • move joystick up => the dir:up event is triggered
  • release
  • move joystick up => the dir:up event is NOT triggered (seems u cache the last status)

Would help a lot getting an event each time the direction changes. Basically after release all "events" should be reset to None or something.

Just an idea

Merry Xmas!

Static/semi mode on touch devices creates new nipples or are not dragable

Very cool library, but have some issues on touch devices in static and semi mode

image1
On Ipad Air 2, new instances will be created on each touch also in static and semi mode.

On Sony Z2 Tab, most of the time it will not create a new instance, but often the existing instance is not working/dragable (this could be reproduced in chrome developer console by using touch device mode).

Set the position of the joystick and disable user control.

I'm creating an app and there are two ways to drive, one is by controlling it directly by moving the joystick and the other way is to use phone rotation data. The joystick reacts to the phone rotation as feedback.

How would I disable touch/click control on the joystick and set the position of the joystick in the code?

Thanks for helping.

'onresize' should use addEventListener

I notice that the window onresize listener is attached by setting the property "window.onresize = function() {...}".
I suggest changing this to use addEventListener instead to avoid risking clash with existing code that also attaches to onresize.

Stop Joystick swapping back

Hi yoannmoinet, Love your work!
Is there a way to station the joystick knob where the user moved it to without it swapping back to its original position?
I want to achive this -

nipplejs

Thanks!

Changing dynamically the color when moving.

I wish to change dynamically the color of joystick from "gray" when iddle to other color when moving, and back to "gray" on "end" event.
How to do that ?
I have tried to change niddle.options.color in "move" function processing, but nothing occurs
Best regards.

Multiple static joysticks

Hi

Amazing lib!

I am trying to setup 2 static joysticks in 2 different zones.
Something like: http://jsfiddle.net/k2xcey8j/4/

It seems to work until I try to move both joysticks in the same time (multitouch): one of them gets stuck and the other one continues to work well :( No chance to 'revive' the dead one, it remains dead until the next refresh.

I reproduce the behavior on Windows Phone and Android (real devices).I don't have a touchscreen display to try on PC.

Is this a bug or the configuration is not supported?

Thanks in advance!

Best regards
TG

Make joystick visible by default in semi mode

I want to show joystick once plugin is initialized, not on click. I tried static mode but in that I want just the joystick to move and keep outer circle stationary as it is now. I'd like to have your recommendations. Thanks

How to update Nipple JS container after device orientation change?

Hi, thank you so much for your Nipple JS efforts. This plugin is AMAZING and really a life saver when it comes to all these iOS updates breaking other methods of implementing DPAD and joystick controllers. I found Nipple JS to be the BEST javascript plugin out there and it works universally on every device, which is totally impressive.

ISSUE/QUESTION: I have my Nipple JS created in a HTML element that is POSITION:FIXED; and it works really good, except when I change my device orientation, it then needs its coordinates adjusted, or else the Nipple JS events launch, but the coordinates it returns are offset by a lot. Is there a clean way to tell Nipple JS to update its container coordinates? Or should I unbind it and recreate it everytime (I hope not!)

Thanks!

joystick get stuck on iphone

There is method prepareCollections() on Manager.prototype, but when it is called it doesnt work. You can test it via safari remote debug in console.

a = [];
a.test = function(){console.log('test')};
a.test(); // returns undefined for first time
a.test(); // returns 'test' every other attempt

I think that is the reason why it get stuck. You can test it on your DEMO (dynamic) as well, just open it on iphone and quickly repeat different touches, best with two fingers. Same for chrome or safari. It seems to me like a bug in safari, but you should fix it anyway, because there is lot of users with iphones.

screenshot

Not on bower?

Attempting to install using bower returns an error that the package cannot be found, and searching on the Bower returns no results.

Joystick gets stuck

I'm using Nipple.js on two separate transparent elements, overlaid on top of an HTML canvas - a 'left' and 'right' element. This allows me to use two joysticks for a 'twin stick shooter' style game.

I'm having a lot of trouble determining when this actually happens, but it is happening quite frequently: the right joystick "locks up", frozen at the max extent of its bounds, and cannot be released without a page refresh. The left joystick never seems to lock up (it is defined first in my code).

Part of the difficulty in debugging this is that it only happens when using a phone to visit the website, and as such my debugging tools (namely access to the browser console) are practically non-existent. In the browser, I cannot reproduce the bug.

It also seems to happen only when there are 2 joysticks active at once. If only 1 joystick is used (despite both having been instantiated), the problem doesn't seem to surface.

Any ideas? I'm digging through your code to see if I can spot where this bug might come from, but figured I would bring it up in case you are able to spot the issue more easily.

Might not be relevant, but here's my usage:

function initializeMovementJoystick(){
    movementJoystick = NippleJS.create({zone: leftDiv});
    var currentOctant = null;
    var octants = new Array(8);
    octants[0] = function(state){InputHandler.setInputState("strafeRight", state);};
    octants[1] = function(state){InputHandler.setInputState("strafeRight", state);InputHandler.setInputState("forward", state);};
    octants[2] = function(state){InputHandler.setInputState("forward", state);};
    octants[3] = function(state){InputHandler.setInputState("strafeLeft", state);InputHandler.setInputState("forward", state);};
    octants[4] = function(state){InputHandler.setInputState("strafeLeft", state);};
    octants[5] = function(state){InputHandler.setInputState("strafeLeft", state);InputHandler.setInputState("backward", state);};
    octants[6] = function(state){InputHandler.setInputState("backward", state);};
    octants[7] = function(state){InputHandler.setInputState("strafeRight", state);InputHandler.setInputState("backward", state);};

    movementJoystick.on('end move', function(event, data){
        if (event.type === 'move'){
            if(data.distance < 15){
                if (currentOctant !== null){
                    //un-fire current
                    octants[currentOctant](false);
                    currentOctant = null;
                }
            } else {
                let angle = data.angle.degree;
                let octant =  Math.floor(((angle + 22.5) % 360) / 45.0);

                if(octant !== currentOctant){
                    if(currentOctant !== null){
                        //changed from one to another, un-fire last
                        octants[currentOctant](false);
                    }
                    //fire current
                    octants[octant](true);
                    currentOctant = octant;
                }
            }
        } else if (event.type === 'end'){
            if (currentOctant !== null){
                octants[currentOctant](false);
                currentOctant = null;
            }
        }
        //console.log(event);
        //console.log(data);
    });
}

function initializeRotationJoystick(){
    rotationJoystick = NippleJS.create({zone: rightDiv});
    var currentOctant = null;
    var octants = new Array(8);
    octants[0] = function(state){InputHandler.setInputState("turnRight", state);};
    octants[1] = function(state){InputHandler.setInputState("turnRight", state);InputHandler.setInputState("boost", state);};
    octants[2] = function(state){InputHandler.setInputState("boost", state);};
    octants[3] = function(state){InputHandler.setInputState("turnLeft", state);InputHandler.setInputState("boost", state);};
    octants[4] = function(state){InputHandler.setInputState("turnLeft", state);};
    octants[5] = function(state){InputHandler.setInputState("turnLeft", state);InputHandler.setInputState("shoot", state);};
    octants[6] = function(state){InputHandler.setInputState("shoot", state);};
    octants[7] = function(state){InputHandler.setInputState("turnRight", state);InputHandler.setInputState("shoot", state);};

    rotationJoystick.on('end move', function(event, data){
        if (event.type === 'move'){
            if (useRelativeOrientation){
                InputHandler.setInputState("targetAngle", data.angle.degree);
            } else if(data.distance < 15){
                if (currentOctant !== null){
                    //un-fire current
                    octants[currentOctant](false);
                    currentOctant = null;
                }
            } else {
                let angle = data.angle.degree;
                let octant =  Math.floor(((angle + 22.5) % 360) / 45.0);

                if(octant !== currentOctant){
                    if(currentOctant !== null){
                        //changed from one to another, un-fire last
                        octants[currentOctant](false);
                    }
                    //fire current
                    octants[octant](true);
                    currentOctant = octant;
                }
            }
        } else if (event.type === 'end'){
            if (currentOctant !== null){
                octants[currentOctant](false);
                currentOctant = null;
            }
        }
        //console.log(event);
        //console.log(data);

    });
}

Is it possible to get -X/+X and -Y/+Y and/or min/max value going from center?

Hi!

How can I get the distance from the nipple to center like a cartesian system ?

I'm trying to implement your nipplejs code in my small project https://github.com/miharix/miharix-wifi-rc/
To do this, I need the X/Y max/min value (optimal would be if I can define the range) so I can calculate the responding ° for the servo move. Or least the X and Y distance from center that contains +/- depending on the direction.

Is this possible in current nipplejs version?

Dev build workflow.

Npm install failed at [email protected].

Npm run build fails (cannot find module core-util-is in format task).

Also i suggest having dev branch ahead of master (had nowhere to merge but master which is not good).

Node v6.2.0, npm v3.7.3, ubuntu 14.04.

Help with initialising joystick

Hello, I am relatively new to node.js. This package is exactly what I need for a little hobby project of mine, but I am unable to initialize the joystick in a web app. What .html, .js, and .css code is needed for the bare minimum joystick on a blank web app? I can figure things out from there, would really appreciate any help in getting started.

Semantic switch `Manager` => `Collection`

The Manager as we know it today will become a Collection.
There can be multiple instances of Collections, and this is what is returned by the nipplejs.create() function.
And we'll welcome the Manager that will handle all the Collections.
It is the general factory and exists only as one instance, it can be found under nipplejs.factory (for now).

zone "div" not used but parent node used

I have created two "div" in a jqxWindow area.
I need to create two joysticks, one in each "div"
The joysticks are created with position relative to jqxWindow and not relative to "div".
What can be the explaination ?

Nipple hijacks events on iPad?

After updating to version 0.6.7 I have had some problems on iPad:
The problem is that after I first touch the joystick/nipple other events on my page will not work anymore.

To reproduce open the demo page:
https://yoannmoinet.github.io/nipplejs/
on an iPad and click the static tab, and touch the nipple.
Then try to change to one of the other tabs (dynamic or semi)

Edit: it is also a problem in "semi" mode, but then you have to touch it twice before it "breaks"
The problem is not there in v0.6.6

Allow having a permanently shown (faded out) joystick

If the user releases the joystick, we should be able to have a persistent joystick shown.
Instead of having it disappeared each time.

  • faded element when released and full opacity when pressed.
  • the tip should go back to its initial position when released.
  • when re-pressed in the joystick's zone, directly move the tip and let the back at its position.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.