Making Framer Prototypes Talk To Each Other

A step-by-step tutorial for easily prototyping interactive TV + remote prototypes in Framer.

Manas Vaze
Framer
8 min readDec 18, 2017

--

Original photo by: Sarah Dorweiler

Editor’s note: We’ve made some big changes to Framer, and this article refers to a deprecated tool. Learn more about what Framer is today →

Framer has quickly become my main go-to tool for prototyping ideas, interactions and animations for my design work.

As a designer who stayed away from code, I felt that Framer does have a bit of a steep learning curve and I did drop off it a couple of times. But now I see the possibilities of what a designer can do once they are comfortable with it. It has also taught me different ways of approaching problems, thinking about the implementation as a part of the design process.

If you are new to Framer and are keen to learn the basics, the following tutorials should be a good starting point. They do go in detail and have a step-by-step method of doing things.

  1. New to Framer? Just 3 Things to Get You Started
  2. Framer Tutorial: Animating Layers

In this particular post, we are going to look at how to make two Framer prototypes talk to each other.

What’s the need for prototypes to talk to each other?
If you are working on a product/company that has a set of apps/devices that form the eco-system, its very important to know the interaction model and possibilities occurring between these devices/apps.

Think Google or Amazon, with a range of devices/apps that usually work together and form an eco-system. The continuity and seamless interaction between these devices forms the crux of the user experience.

The Setup

To begin, lets have a look at all the elements that will be used in making the prototypes work and talk with each other.

The setup consists of 3 main parts:

  1. The Smart TV
  2. The Remote Control
  3. Server

If you don’t already have Framer, you can download a free 14 day trial. Apart from the basics in Framer, we will be making use of WebSockets.

WebSockets is an advanced technology that makes it possible to open an interactive communication session between the user’s browser and a server. You can read more about WebSockets here.

1. The Smart TV

This prototype will behave as the TV. The primary job of this prototype is to listen to swipe gestures and handle the UI navigation accordingly.

Lets begin by creating some app icons that can appear on the TV Home Screen.

# Create App Icons and Build the TV UI in a container layercontainer = new Layer
width: Screen.width
height: Screen.height
backgroundColor: "EAEAEA"

container.center()
# An array to hold all the app icons of the TV
icons = []
# Create app icons of the TV in a loop and push them onto the array
for i in [0...5]
icon = new Layer
width: 200
height: 200
x: (280 * i) + 60
y: 60
borderRadius: 6
backgroundColor: Utils.randomColor()
parent: container
icons.push(icon)

(Use the devices dropdown to enable the TV Device in Framer Preview Window.) Once you write the above code, your result should look something like this:

Smart TV Prototype — Preview Mode in Framer

Now, lets create the focus/hover interaction that we usually find in most Smart TV UIs these days. For this, we are going to make use of a Framer module rather than write the complete logic by ourselves.

(Think of modules as a bunch of code/library of code, that we can import into our prototypes to automate certain tasks, like handling the UI focus interaction in our case.)

Focus Engine Module by blackpixel

Copy the FocusEngine.coffee file and paste it in the ‘/modules’ folder of your project. Next, we need to add the following line of code in Framer to include this module.

# Command to include the FocusEngine Module in our TV Prototype
fe = require "FocusEngine"

Now that we have imported the module into our prototype, it needs to be fed with the app icon layers we created earlier to make them interactive.

# Initialize the focus engine with the app icons, all the layers that can be controlled with the remote need to be fed into the focus engine
fe.initialize(icons)
# Set the first icon to be on focus at the beginning
fe.placeFocus(icons[0])

Once the FocusEngine is initialised, your result should look something like this:

You should be able to see the first layer on focus like above.

Next, we add in the following code into our TV Prototype. What this does basically is to listen to swipe gestures and changes the focus accordingly.

ws.onmessage = (event) ->
if event.data == "left"
fe.changeFocus("left")
else if event.data == "right"
fe.changeFocus("right")
else if event.data == "up"
fe.changeFocus("up")
else if event.data == "down"
fe.changeFocus("down")

Our TV Prototype set-up is done.

2. The Remote Control

This prototype will be the Remote control to the TV. It’s main job is to enable a touch surface that will act as a remote control and pass the swipe gestures to the TV.

Create another Framer project and name it “remote-control”. In this prototype we will be using the RemoteLayer module to create an apple TV remote touch surface that can be used to send gestures to the Smart TV prototype.

(Remember, modules are a bunch of code/library of code, that we can import into our prototypes to automate certain tasks, this module will handle the swipe gestures automatically for us.)

Copy the RemoteLayer.coffee file and paste it in the ‘/modules’ folder of your TV Remote Framer project. Next, we need to add the following line of code in Framer to include this module.

# Command to include the Remote Control Module in our Remote Prototype
RemoteLayer = require "RemoteLayer"

Next, lets create a Remote Layer instance and define some events/actions that it should do when a user swipes on it.

# Create a remote control layer in a container layer and define the action it should do on swipes (left, right, up and down)container = new Layer
size: Screen.size
backgroundColor: "EAEAEA"
myRemote = new RemoteLayer
parent: container
swipeUpAction: ->
ws.send("up")
swipeDownAction: ->
ws.send("down")
swipeLeftAction: ->
ws.send("left")
swipeRightAction: ->
ws.send("right")

In brief, the lines “ws.send(“up/down/left/right”) are sending the messages to the web-socket server, based on the type of interaction/swipe.

Once you do the above, your remote control prototype should look something like this:

The module we are using is creating an apple TV remote object for us.

3. Server

Awesome! Now that we have both the Smart TV and Remote-control prototypes set up, we will now look into connecting both of them.

For this, we shall host a Node Server on our laptop/local machine. You can visit this website to download the npm package and install it by following instructions.

Next, we need to open terminal app and navigate to the TV prototype folder and type the following command. This will create a “package.json” file that node server will use.

npm init --yes

Next, We need to install “express” in the same folder. Use the following command.

npm install --save --save-exact express

We will also install a couple of other dependencies such as “BufferUtils” and “UTF-8 validate”

npm install --save --save-exact ws bufferutil utf-8-validate

(For WebSockets, we’ll install the ws module as well as bufferutil and utf-8-validate. Only ws is necessary, but the other two provide a performance boost.)

Next, create a new file in the same folder and name it “server.js”, as shown below.

server.js file to be created inside the remote control project folder

Now, open this file in your favourite text editor and paste the following code and save the file.

'use strict';const express = require('express');
const SocketServer = require('ws').Server;
const path = require('path');
const PORT = process.env.PORT || 3000;
const INDEX = path.join(__dirname, 'index.html');
const server = express()
.use((req, res) => res.sendFile(INDEX) )
.listen(PORT, () => console.log(`Listening on ${ PORT }`));
const wss = new SocketServer({ server });wss.on('connection', (ws) => {
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
ws.on('message', function incoming(data) {
console.log(wss.clients.size);
console.log(data);
wss.clients.forEach((client) => {
client.send(data);
});
})
});

To understand what this code does, you can read more about it here. In brief, the code here is creating a new node/express server and defining the path and other parameters for it.

We also declare that we are hosting this locally and the server shall listen to port “3000". Now, lets verify the same by running the server. Lets run the server by executing the following command on the terminal.

node server.js
Confirmation of the server running. It should say “Listening to 3000”

Congratulations! You have just setup a Node Server locally and its running fine. :)

The last step is to make the TV Prototype listen to the Remote control prototype.

For this, we need to add some javascript in the index.html file of both the TV and Remote control Prototypes.

(Please note that this code has to go inside the <body> </body> tags of the index.html file)

<script>
var HOST = "ws://localhost:3000";
var ws = new WebSocket(HOST);
ws.onmessage = function (event) {
};
</script>
Open the index.html file in your favourite text editor and paste the above javascript in it.

This javascript is basically creating web-socket objects and the function ws.onmessage() will send across the “message” or “swipe-gestures” in our case.

Hit Refresh on both TV and Remote Prototypes and you are ready to go! Our set of prototypes are connected and can start working together.

Snapshot of both the TV and Remote Prototypes talking to each other :)

Conclusion

I hope you found this tutorial helpful in creating prototypes that can communicate with each other. This also opens up new ways to think about interaction between apps and devices. Excited to see what the community builds using Framer and web-sockets.

You can download the Prototype files from here.

Special thanks to all the people on Framer slack channel that have helped me so far, including Sergey, Steve, nvh, Muhammad Athar and many more….

If you ever want to talk more about Framer or Sketch or related stuff feel free to get in touch on Twitter. Also check out the Framer JS group on Facebook, there is always a ton of great designers/developers helping each other there.

Thank you for reading this! Please let me know if you have any thoughts, questions or suggestions for improvements.

--

--