Creating a Touch Controlled Joystick in HTML5 with Javascript

Too Long; Did Not Read

You can find all the code for this joystick on GitHub. Dependencies are jquery, underscore, and backbone. The images are just sprites that can be replaced with anything. Joystick views triggers events for horizontal and vertical changes.

Live Demo

True Story Follows

So I’m on the grind playing around with a page where I wanted a user to be able to touch the screen rather than move some arrows around. Surprisingly, I didn’t find many good resources out there, so I just made my HTML5 joystick using backbone.

There’s nothing super earth-shattering about what I did, so I’ll instead just present this to the internets with a bit of javascript that’s free for that taking, and here I’ll try and explain some of the not immediately intuitive choices I made.

The Code

I used Backbone and underscore just because that’s what I know. Backbone makes it easy to map events to actions, and using a template allows the size of the joystick to be variable.

The Weird Stuff

Check out this craziness:

            var joystickView = new JoystickView(150, function(callbackView){
                $("#joystickContent").append(callbackView.render().el);
                setTimeout(function(){
                    callbackView.renderSprite();
                }, 0);
            });

Don’t judge. I did some crazy callbacks because I found that if you tried to render a sprite before the image had loaded, nothing got rendered, and you had to actually go re-render before anything would show up. So I made the view use a callback function once everything had finished loading and it was safe to render.

But why the setTimeout you ask? I don’t remember honestly. Maybe you don’t even need it. I think I was troubleshooting something. You probably don’t need it. Who knows.

    _retractJoystickForInactivity: function(){
        var framesPerSec = 15;
        var self = this;
        setTimeout(function(){
            var currentTime = new Date().getTime();
            if(currentTime - self.lastTouch >= SECONDS_INACTIVE * 1000){
                self._retractToMiddle();
                self.renderSprite();
            }
            self._retractJoystickForInactivity();
        }, parseInt(1000 / framesPerSec, 10));
    },

Alright so peep this: the joystick will behave differently depending on mouse or touch events. For iOS devices at least, the “touchend” event never actually fired, so I got the undesirable behavior of the joystick just staying in place.

So I instead set a half second timeout where inactivity would trigger the joystick to slowly move back to the center. That’s what that’s all about.

The Cool Stuff

A few small touches I put in that I feel make this joystick kind of cool:

  • The canvas is actually a square, but some math was added so that the joystick never moved beyond a set radius. If you finger exceeds the radius, the math is done to find the point that would intersect the invisible circle between your mouse/finger and the center.
  • Getting mouse x and y values in a canvas is easy. Getting TOUCH x and y values aren’t as straightforward because the same values aren’t present in the event. A lot more involved logic was added to account for those cases.
  • The graphics here are easily interchangeable.
  • The size of the joystick is easily set.
  • The joystick triggers events which you can use to avoid tightly coupling other code with the joystick.

The End

  • Anselme Chorein

    Good work ! 🙂

  • Nice work.
    (Y) 🙂

  • Arthur Kovacs

    Good work!, I have only one question, why did you choose to do it in Canvas ? Are there any real considerations / limitations to doing it in HTML or was it just your preference ?

    • Scott Benedict Lobdell

      I would not know where to start if I did pure HTML 🙂

      I wanted free reign for the joystick position

      • Arthur Kovacs

        Ok, all cool, I thought that you might’ve hit some walls while trying it the html way. Thanks!