Gamepad API and Xbox Controller on Mac

By  on  

The Mozilla MozVR team was demonstrating the open WebVR standard as well as A-Frame at GDC a few weeks ago and people were intrigued; some were surprised the web could handle VR, some probably just thought our VR line was smaller (it was by miles), and others saw the Xbox controller next the VR headsets and wanted to know how Microsoft Xbox controller + VR + Mac + browser even worked.  I was so excited about all of this that I jumped on it immediately upon return from GDC.  Let's see how it all works!

Step One:  Xbox Controller Driver (360Controller)

The 360Controller project provides a list of Mac driver releases for the Xbox, Xbox 360, and Xbox One.  The latest (0.15.0) is required for Xbox One support.  Download and install the package provided and you'll see a "Xbox 360 Controllers" label and icon in your System Preferences app.  This preferences pane provides information about the Xbox controller selected and also provides controls for overriding settings:

Xbox Controller on Mac

You must connect your Xbox controller via USB for the Mac to detect the controller  -- wireless wont work.  Press the buttons and watch each button's representation in the app light up.  You can even press the left and right trigger buttons and the Xbox controller will shake.  Solid!

Step Two:  Gamepad API

The JavaScript GamePad API provides access to controllers within the browser.  Start by calling `navigator.getGamepads()` to get a listing of gamepads plugged in:

var gpads = navigator.getGamepads(); // Array[Gamepad]

The user may plug in a device during gameplay (or any time for that matter) so you can use two handy event listeners to detect connection and disconnection:

// Listen for the connection
window.addEventListener('gamepadconnected', function(e) {
  var gpad = navigator.getGamepads()[e.gamepad.index];

  // Start the game / animation
  
});

// Oh nooooo, disconnected
window.addEventListener('gamepaddisconnected', function(e) {

  // Pause the game
  
});

A GamePad object provides the following information:

Gamepad {
  axes: Array[6],
  buttons: Array[15],
  connected: true,
  id: "45e-2d1-Xbox One Wired Controller",
  index: 0,
  mapping: "",
  timestamp: 5142195.495
}

The buttons property is interesting: an array of GamepadButton objects, each having a boolean pressed values describing if the button is currently being pressed.  You're were probably hoping (like I did) that there would be an event listener for button presses but there isn't -- you have to do button press checks within your game's loop (requestAnimationFrame).  It's likely done that way so that lag, latency, etc. don't cause havoc between a listener and game state.  Here's a quick example:

GamepadButton {
  pressed: false,
  value: 0
}

You can see more button press and reaction examples on MDN.  You can also check out HTML5 Gamepad Tester to experiment with button pressing and axis state for any given controller.

Step 3:  The Game: Tanx

The game showcased with VR + Xbox controller + Gamepad API was a special 3D build of Tanx by PlayCanvas.  The visual was amazing and people loved the game in an enhanced 3D state.  Sorry, I don't have a link to a public version at this time!

There you have it -- you can connect your Xbox controller to Mac and play HTML5 games that support the Gamepad API with a special driver and a bit of JavaScript magic!

Recent Features

  • By
    Convert XML to JSON with JavaScript

    If you follow me on Twitter, you know that I've been working on a super top secret mobile application using Appcelerator Titanium.  The experience has been great:  using JavaScript to create easy to write, easy to test, native mobile apps has been fun.  My...

  • By
    Create a CSS Cube

    CSS cubes really showcase what CSS has become over the years, evolving from simple color and dimension directives to a language capable of creating deep, creative visuals.  Add animation and you've got something really neat.  Unfortunately each CSS cube tutorial I've read is a bit...

Incredible Demos

  • By
    Basic AJAX Requests Using MooTools 1.2

    AJAX has become a huge part of the modern web and that wont change in the foreseeable future. MooTools has made AJAX so simple that a rookie developer can get their dynamic pages working in no time. Step 1: The XHTML Here we define two links...

  • By
    Assign Anchor IDs Using MooTools 1.2

    One of my favorite uses of the MooTools JavaScript library is the SmoothScroll plugin. I use it on my website, my employer's website, and on many customer websites. The best part about the plugin is that it's so easy to implement. I recently ran...

Discussion

  1. Hello, David,

    reading your blog post it reminded me on a conversation I had with Andrzej about 1,5 years ago.

    There ARE (or were?) events fired on buttonpress or axes movement:
    https://github.com/end3r/gamepad-api-test/blob/9550007263a56b1ca59ac91eac1391ea501ccd33/index.html#L56

    I even did some research back then to figure out, that less known devices don’t make use of them:
    https://github.com/end3r/gamepad-api-test/issues/1

    It’s a pity that the demo at html5rocks went down :-(

    Kind regards

    André

  2. Excellent explanation, David. The integration of the Gamepad API with Xbox controllers on macOS is clearly outlined here. Your step-by-step approach makes it much easier to understand the technical flow from driver installation to JavaScript implementation.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!