Introducing Framer Joystick

The ultimate Framer module for your Gamepad prototype.

Emil Widlund
Framer
10 min readAug 1, 2017

--

After the tremendous amount of curiosity and positive feedback I received when I wrote the article “Designing & building UI-prototypes tailored for gamepad environments”, I decided to make our Framer module open-source and available for all of you.

And this time around, I will make it a bit more practical. But please note that this build is currently in an Alpha-state, so expect some bugs. We will make a simple TV app that takes input from a gamepad. So… Are you ready? Let’s have some fun!

However, before we proceed, ensure that you are running at least macOS Sierra version 10.12.6. This is because the Gamepad hooks in Safari WebKit was recently added. It might be working on previous versions, but I have only tested this on 10.12.6 and confirmed it working.

Make sure that you have the correct drivers installed for your Gamepad. Drivers for Xbox-controllers to Mac can be found here. When you have connected your Xbox-controller, please make sure that the Xbox-button is lighted. If it’s pulsating, reconnect the cable and hold down the Xbox-button again.
As far as I’m concerned, Playstation 4-controllers are natively supported on macOS. However, I had no luck make it connect to my Mac properly via cable. But via Bluetooth worked fine. A guide on how to connect Playstation 4-controllers via Bluetooth to Mac can be found here.

If you use a Playstation 4-controller, please mind that it for some reason doesn’t follow the guidelines on how the buttons should be mapped (according to the W3 specification). This practically means that some behaviour in your prototype may differ when using an Xbox-controller on a prototype designed for Playstation 4-controllers and vice versa. So my tip: Always use the controller you designed the prototype for to avoid problems. This will hopefully be fixed in future releases.

You can test your Gamepad with “GamepadViewer” here. Make sure to click on “None” in the top and select Player 1 after you’ve connected it. If it seems to be working there, then you should be ready to go.

Let’s go!

Let’s begin by opening up Framer Studio. It’s always preferred to have the latest version installed, so for this tutorial, I’ll be running Framer Studio v97. If you don’t have Framer yet, download their 14 day free trial to follow along with this tutorial.

Create your project

Create a new project and save it on a desired location. Press on the Code button in the top and choose TV in the Device window.

Download Framer Joystick

Now it’s time to download the Framer Joystick module itself. You can grab the latest version here. Unzip the package and extract the contents to your modules folder within your saved Framer project-folder. It’s important that joystick.coffee and the joystick folder are located directly under “modules”.

It should look like this

Importing the required components from the module

Time to fill the blank Framer document with some code! We will now import all the necessities we need from the module. App, View, Gamepad, Focusable, Transitions & Grid will be needed in this tutorial. So make sure to “require” them like I’ve done below.

Setting up our App and creating our first View

Adding a view to our prototype is very easy. It doesn’t even have to be declared with a size. It will have the same height and width as your Device per default. But the View has a special “background” property which may appear weird. The App will pick this up and use its properties in the App Background Canvas. You’ll understand why later.

The App component is important for a Gamepad prototype. It will handle all transitions between screens and communicate will all parts of your application. It’s however also very easy to declare, and doesn’t require any fancy properties to function. Let’s create an App instance and name it “myApp”.

Lastly, we’re loading our first View into the App.

These 8 lines of code should have made your Device window go light-grey. Pretty boring right? Well, now it’s time to get our hands on the Gamepad!

Adding Focusables and make them do cool things

A “Focusable” is a component much like the well-known “Layer”, with one big difference. They have two different states (or appearances if that sounds better) which will indicate if we are selecting it in the UI or not. As the main difference for a Gamepad prototype is the user interacting with a gamepad, not a mouse or a finger; the user has to know what he is selecting on the screen.

A Focusable has some extra properties to think about.

Okay, let’s see what we’re doing here. The parent value of our Focusable looks suspicious you may think. What’s the “safezone” property on the homeView? The safezone is an area within the view that is 90% of the view size. This is a common area when designing for TV-screens, as your content otherwise may end up being clipped, if it’s positioned too close to the edge, due to different TV-manufacturing standards. If you don’t want to place your Focusable on the safezone, simply just specify “homeView” instead of “homeView.safezone”.

The “focusProperties” property specifies the focus state when we’re selecting the specific Focusable. As in this case, we’re growing the Focusable to 1.2 in scale and changing the backgroundColor when we have it selected. The “animationOptions” property simply defines the animation behaviour when going from selected back to unselected. Normally, you would want the same time and easing for your “focusProperties.animationOptions” and “animationOptions”.

Lastly, we have an “actions” property which takes an array of actions. An action contain a keyCode and a function. The function will be fired when you have your Focusable selected and press the specified keyCode on your Gamepad. Go ahead and press “A” on your Xbox-controller or “Square” on your Playstation 4-controller. You should now see “Press!” printed out. If nothing happens, make sure that the Preview/Device window in Framer is in focus, otherwise the prototype won’t be able to pick up the Gamepad events. Sometimes you also have to press a button on your controller to “wake it up”.

As I mentioned before, Playstation 4-controllers and Xbox-controllers differs in the Gamepad-keycode structure. Keycode 0 is mapped to “A” on Xbox-controllers but “Square” on Playstation 4-controllers.

You should now also be able to navigate between the three Focusables on your screen with your left stick and gamepad arrows.

Setting up transitions to other views

Let’s create an additional view which we can transition to when pressing keyCode 0 on our Focusables.

  • On Line 25, we instructed our Focusable to fire the transitionToView-function on our App instance. We also gave it a transition called “goIn”. Framer Joystick comes with two transitions that you can use. “goIn” and “goOut” for simple in-out transitions. If you want to pass it a custom transition that suits your app better, you could find some details here.
  • On Line 30, we declared a new View called “anotherView”. We gave it some background-properties, but as you can see we also gave it an action. Views can also have actions like Focusables, but instead, it doesn’t matter what you’re selecting on the screen. The action will fire if the keyCode specified is pressed. This is great for a back action, as you want to be able to navigate backwards without having to select a specific Focusable. Also note that we’re passing the “goOut”-transition to the “transitionToView”-function, to simulate an outgoing feeling.
  • Lastly, on Line 41, we’re adding a simple text layer to our “anotherView” View.

Now, press key 0 on your gamepad (“A” on Xbox-controller & “Square” on PS4-controller). You should now have been transitioned into “anotherView”. To go back again, simply press key 1 on your gamepad (“B” on Xbox-controller & “X” on PS4-controller).

Using the Gamepad for more than simple navigation

As you may have noticed, we never had to setup any Gamepad-code to get the navigation up and working. It works automatically thanks to the App instance that controls all of it.

If you want to use the Gamepad anything besides regular navigation between focusables, you can use it like this:

You can print out the event parameter to see what keyCode the button pressed has. The example above prints out what direction you’re pointing the left gamepad-stick.

You may notice that gamepad events are not really emitted as often as you may want. This is to get a nice feeling when navigating between Focusables. However, if you really need more frequent Gamepad events, you can set the “throttle” property on the Gamepad object to false. But this will also affect navigation, and you will end up navigating between Focusables insanely fast. So please use it with caution. Make sure to set “throttle” back to true when you’re done with the frequent Gamepad events.

Using the Grid for proper alignment

To get coherent alignment across your prototype, you can use the Grid component when defining sizes, margins, etc. The Grid is by default set to 24 columns of your Screen Safezone, and between every column is a 10px gutter. A row is 10px with no gutters in between.

Let’s imagine that your Screen is 1920 x 1080. The Screen Safezone is then 1728 x 972. Defining a Layer size with the Grid will result in following:

On my team at EA, we always depend heavily on the Grid. Just to make sure that everything is perfectly aligned. It makes everything so much easier.

Build a Gamepad-friendly component

Let’s build a component that behaves like a ScrollComponent, but more friendly to our Gamepad. This is what we’ll be building:

As you can see, the scroller automatically scrolls so the Focusable fits inside the Safezone. Curious on how we achieve this effect? Let’s take a look.

As you can see, we are making a class called “CardCarousel” which extends the ScrollerComponent. We declare a new CardCarousel and mount a few Focusables on its content-layer. It works exactly like a normal ScrollComponent, but behaves a bit differently. The “scrollToCard” method in the CardCarousel fires everytime a Focusable within itself is selected. If its bounds are outside of the Safezone, it automatically scrolls to that Focusable. This is just a simple example on how you can build useful components that uses Focusables within itself.

Well, I think that concludes everything at this point. Please remember that this module is in an Alpha-mode, and there may be bugs. I would be extremely happy if you reach out to me on Twitter if you encounter anything weird.

But before I end, I just want to give you a few tips & tricks!

Tips & Tricks

  1. Views & Focusables are extensions of the Layer component in Framer. So you can do the same stuff to them as you can do to a regular Layer.
  2. You can listen on the “change:view” and “change:focusedElement” events on the App instance if you want to know when views are entering or Focusables are focused.
  3. If you populate an image in the “background”-property on a View, the image will stay back covering the canvas, even when you’re doing a transition. That image will not be attached to the View-element itself, which the normal “image”-property on the View would. It’s the same for “backgroundColor”.
  4. If your gamepad doesn’t seem to work, try to reconnect it and push a few buttons. Sometimes, it behaves a bit weird, but a reconnection often solves the problem. Also reload your prototype after a reconnection.
  5. You can use your computer arrows to navigate between Focusables. The Enter key on your keyboard will trigger keyCode 0 and the Backspace key will trigger keyCode 1. This is very useful when debugging, and you don’t want to fiddle with your gamepad.
  6. If you have a Layer as a child to a Focusable, you can add a “focused”-state to that layer if you want it to change when the parent Focusable is selected.

Thanks for making it to the bottom. I am very glad you took the time and read my introduction for this module. Now, go out and make beautiful things, and please let me know how you used this module. I want to see all your amazing creations!

Follow me on Twitter.

--

--