w2olves w2olves - 5 months ago 23
Javascript Question

Jquery Dragabale containment radius

I am trying to emulate the behavior of a joystick. You can push the joystick in any direction but it has a limit to how far you can push and it reverts back to its original position once you release the stick. I am using jquery dragable. Reverting the position is easy, the problem I am facing is keeping the joystick inside the circle.

HTML:

<div class="demo">

<div id="draggable4" class="draggable draginvalid ui-widget-content">
drag me
</div>


</div>


JS:

$( ".draginvalid" ).draggable({
distance: 1,
revert: "invalid"
});


I have a fiddle to show this behavior

http://jsfiddle.net/mGWfP/12/

Any ideas on how I can achieve a behavior where the joystick is contained within the circle ? TIA

Answer

Here a place to start:

$( ".draginvalid" ).draggable({ 
  distance: 1,
  revert: "invalid",
  drag: function(e, d) {
    console.log(d);
    d.position.left = Math.max(-40, Math.min(40, d.position.left));
    d.position.top = Math.max(-40, Math.min(40, d.position.top));
  }
});

It currently only allows a variation of 40 in each direction. It is not yet keeping it perfectly in the circle of course but with the right formula you can get there.

Also have a look in your console. I am printing the object that you can influence the position with.

Hope this helps :)

EDIT: here the code for the perfect circle. You just need to adjust the position of your inner circle a bit. It is not exactly in the middle. Also you might need to change the number 44 which is the maximum of pixels you can move the joystick in each direction.

$( ".draginvalid" ).draggable({ 
  distance: 1,
  revert: "invalid",
    drag: function(e, d) {
      maxMove = 44;
      maxMoveSqr = 44*44;
      l = d.position.left;
      t = d.position.top;
      len = l*l+t*t;
      if (maxMoveSqr < len) {
        d.position.left = l / Math.sqrt(len) * maxMove;
        d.position.top = t / Math.sqrt(len) * maxMove;      
      }
    }
});

Feel free to optimize ;)