Late last week, excitement buzzed here at Bocoup, when David Humphrey of Mozilla dropped us a line with links to a Firefox nightly build that had added rudimentary support for a set of DOM Joystick events. Several hours later we, along with Jason Orendorff and TedMielczarek of Mozilla, put together a couple of prototype experiments to demonstrate potential use-cases for the new event types. Additionally, we started thinking and planning an approach for authoring a JS library in conjunction with the emerging API.

Currently, Mozilla wiki page for the Joystick API specifies three new event types allow you to subscribe to joystick events such as button up/down and joystick move:

  • MozJoyButtonDown
  • MozJoyButtonUp
  • MozJoyAxisMove

All three events share a JoystickID property that is unique per connected device (allowing multiple devices).

The MozJoyButtonUp and MozJoyButtonDown events also contain a button property corresponding to the button being pressed or released. Each button on the controller will have a unique ID assigned to it.

The MozJoyAxisMove event is triggered on analog sticks move and has the following unique properties:

  • axis – an integer indicating which axis the analog stick is being moved on. Note that an axis is not just from the analog stick’s neutral position to an edge but rather from edge to edge. Depending on the manufacturer, the number of axes can vary. For example, the XBox wired controller has 4 axes (top to bottom, left to right, and two diagonals.)
  • value – The position of the analog stick on the axis it’s on. The value is somewhere between -1.0 and 1.0.

The following gist can be used to analyze the output of the above three events:

joystick.js

/*
MozJoyAxisMove
MozJoyButtonUp
MozJoyButtonDown
*/

var joyEvents = {

    MozJoyAxisMove: {
      props: [ "joystickID", "axis", "value" ],
      listen: 1
    },
    MozJoyButtonUp: {
      props: [ "joystickID", "button" ],
      listen: 1
    },
    MozJoyButtonDown: {
      props: [ "joystickID", "button" ],
      listen: 1
    }
  },
  joyEventsKeys = Object.keys( joyEvents );

// Iterate joystick events, add an event listener to the window to log events
joyEventsKeys.forEach(function( type, idx ) {

  var joyEvent = joyEvents[ type ];

  if ( joyEvent.listen ) {

    window.addEventListener( type, function( event ) {

      console.log(
        type,
        joyEvent.props.map(function( val ) {
          return val + ": " + event[ val ];
        }).join(", ")
      );

    }, false);
  }

  if ( idx === joyEventsKeys.length - 1 ) {
    console.log( "MozJoy* Events Ready" );
  }
}, joyEvents );

Our first prototype can be found here: http://jsfiddle.net/rwaldron/wPuGB/. It allows you to control video playback with your controller. The second prototype http://jsfiddle.net/iros/YtpkY/ uses Paper.js and simply allows you to move a dot across the screen using your analog stick. If you have an XBox controller you can grab the FireFox nightly build containing the event support here: Firefox 8 Nightly (Special builds) and if you are on the Mac you can get XBox controller drivers here: XBox 360 OSX Drivers.

If you don’t want to go through all of the setup, check out the video demo here:

During our brief experiments we came across a few initial issues such as the high number of events being fired. At the moment the event buffer can get overloaded pretty quickly especially when the analog stick is maxed out on an axis. Keeping the number of events high is obviously important to achieve the kind of precision we see in console games. Additionally, the diversity of controllers will ensure that single button to action mappings will be challenging to accomplish. These issues and others are ones we hope to address in some future work on Joystick.js.

The introduction of joystick events in the browser marks a milestone in the history of the web and specifically the role it plays in our everyday entertainment demands and how we interact with that experience.

Note: The Firefox 8 build is actually a “Try Server” build – not a “Nightly” as the url and title imply.

Comments