Introduction
These days, you don’t need image editing software like Adobe Photoshop or Gimp to create user interface mock-ups for your mobile apps. An app that conforms to Google’s Material Design language is usually composed of only simple geometric shapes, solid colors, icons, and text. A user interface prototype for such an app can be created easily using just code.
In this two-part series, you are going to learn the basics of Framer, an open source Javascript framework that lets you programmatically create interactive and realistic prototypes with beautiful animations for iOS and Android apps.
Prerequisites
To follow this tutorial, you will need:
- the latest build of the Framer framework
- Google Chrome or any other WebKit-based browser
- Python 2.7 or higher
- a text editor
- a basic understanding of HTML, CSS, and Javascript
1. Initial Setup
Step 1: Create an HTML Page
Because a Framer prototype is nothing but an ordinary web page written in HTML, CSS, and Javascript, let’s start by creating a blank HTML page. I am going to call this page index.html.
<!doctype html> <html> <head> </head> <body> </body> </html>
To make use of Framer’s API on this page, you should add a script
tag that points to the framer.js file you downloaded.
<script src="framer.js"></script>
Step 2: Create an HTTP Server
As Framer makes use of protocol-relative URLs to load various resources, you can’t simply double-click the file you created to open it in a browser. Doing so will lead to network errors. Instead, you should access it through an HTTP server.
To quickly create an HTTP server that is capable of serving your web page, you can use Python’s SimpleHTTPServer
module.
Open a terminal, navigate to the directory that contains the web page you created, and execute the following command.
python -m SimpleHTTPServer 8000
This will start a server that runs on port 8000 by default. You can now open Google Chrome and view your web page by visiting http://localhost:8000/.
Step 3: Draw a Device
To make your prototype feel realistic on a desktop browser, you should display all its elements inside the frame of a mobile device. Framer lets you draw a variety of popular mobile devices, such iPhones, Nexus phones and tablets, iPads, Apple Watches, and more. For this tutorial, I will be using a pink iPhone 5c.
To draw a device, you should first create an instance of the DeviceComponent
class and call its setupContext
method. You can then change its deviceType
to the device of your choosing. Add another script
tag to the HTML page you created earlier and add the following code to it:
var device = new Framer.DeviceComponent(); device.setupContext(); device.deviceType = "iphone-5c-pink";
When you refresh your web page, you should see the following in your browser window:
If you want, you can also render a hand holding the device by adding -hand at the end of the deviceType
string. If the device looks too big or too small, you can use the setDeviceScale
method to change its size.
// Display a hand with the device device.deviceType = "iphone-5c-pink-hand"; // Change the size device.setDeviceScale(0.3);
This completes the initial setup. The result should looks like this:
2. Drawing Boxes, Text, and Images
Almost every element in your Framer prototype will be an instance of the Layer
class. A Layer
is very similar to an HTML div
element and can be used to draw rectangles, images, and text.
To create a Layer
you have to call its constructor and pass it a JSON object that defines various properties of the Layer
. While creating a Layer
, you usually specify its dimensions (width
and height
) and position (x
and y
). You can also use the centerX
and centerY
methods to center it horizontally and vertically. Here’s an example of how to create a Layer
.
// Draw a white square var whiteSquare = new Layer( { backgroundColor: "#FFFFFF", width: 400, height: 400, y: 20 } ); // Center horizontally whiteSquare.centerX();
To display an image, you have to create a Layer
whose image
property points to the image file you want to display.
// Draw an image var pic = new Layer( { image: "painting.jpg", width: 400, height: 400, y: 440 } ); pic.centerX();
To display text (or HTML), you can use the html
property. You can also add CSS styling to a Layer
using its style
property.
// Write text var text = new Layer( { width: Screen.width, height: 100, y: 860, html: "This is a prototype", style: { fontSize: "50px", textAlign: "center", color: "#f1f2f3", paddingTop: "18px" } } );
With the three Layer
objects we created in this step, the prototype would look like this:
3. Adding Events
You can attach event handlers to a Layer
using the on
method. The on
method is much like Javascript’s addEventListener
method. It takes the name of an event as its first parameter and a function as its second parameter.
Here’s how you add a click
handler to the text
layer we created in the previous step:
text.on("click", function(){ text.html = "I was clicked"; });
You will see more event handlers later in this tutorial.
4. Adding Animation
Framer stands out from its competition thanks to its advanced animation effects. With Framer, you can animate nearly every property of your Layer
objects using the animate
method. The animate
method takes as input a JSON object that specifies the properties that should be animated.
The JSON object can also include various configuration details of the animation, such as its duration and behavior.
As an example, let me show you how to create an animation that turns whiteSquare
into a circle by changing its borderRadius
.
// Animate borderRadius whiteSquare.animate({ properties: { borderRadius: whiteSquare.width/2 }, time: 2, // duration is two seconds curve: "ease-in-out" // apply easing });
Here’s another example that shows how to animate the shadow of whiteSquare
when it is clicked.
// Animate Shadow whiteSquare.on("click", function(){ // Set the shadow color first whiteSquare.shadowColor = "#555555"; whiteSquare.animate({ "properties": { shadowBlur: 40, shadowSpread: 10, } }); });
Note that only those properties whose values are numbers can be animated. As shadowColor
is not a number, it should be set before calling animate
.
5. Using States
If you are using Framer, it is likely that you are trying to create a highly interactive prototype with lots of animations. Calling the animate
method multiple times on a Layer
can get tedious. Instead, you can associate a list of states with a Layer
and just switch between the states when needed.
Every Layer
has a states
property that is an instance of the LayerStates
class. To add new states to a Layer
, you call the add
method on the states
property. In the following code snippet, we add two new states to the pic
object.
// Add two states pic.states.add({ "myState1" : { borderRadius: 100 }, "myState2": { borderRadius: 200 } });
Adding a state doesn’t result in an immediate visual change. However, when a Layer
switches from one state to another, you will be able to see the animation. To change the state of a Layer
, you call the switch
method on the states
property of the Layer
object. The following code snippet shows you how to change the state of pic
when it is clicked.
// Change state when clicked pic.on("click", function() { // Switch to myState2 pic.states.switch("myState2"); });
To cycle through the states of a Layer
, you can call the next
method of its states
object.
pic.states.next();
6. Changing Backgrounds
To add a background color or image to your prototype, you create a BackgroundLayer
object. A BackgroundLayer
is a Layer
whose dimensions are equal to the dimensions of the device’s screen. Here’s how you add a grey BackgroundLayer
:
var bg = new BackgroundLayer({ backgroundColor: "#BDBDBD" });
Because the Framer prototype is just an ordinary HTML page, you can also use CSS to style it. For example, if you aren’t happy with the white color surrounding the device, you can change it by applying a new style to the web page’s body
tag.
<style type="text/css"> body{ background: #C5CAE9 } </style>
With these changes, the prototype will look like this when the animations are finished:
7. Handling Drag Operations
To make a Layer
draggable, all you have to do is set its draggable.enabled
property to true
.
// Allow dragging pic.draggable.enabled = true;
If a Layer
is draggable, you are able to add event listeners to it that respond to various dragging related events, such as dragend
and dragmove
. For example, here’s a dragend
event handler that returns pic
to its original position:
// Handle dragend pic.on("dragend", function(){ pic.animate({ "properties": { x: Screen.width/2 - pic.width/2, // Place at Center y: 440 // Original Y } }); });
Conclusion
In this tutorial, you learned the basics of creating interactive prototypes for mobile apps using Framer. As your Framer prototypes are static web pages, you can upload them to any HTTP server to share them with your friends and clients.
I’d also like to tell you that, if you are competent with Adobe Photoshop, you don’t have to create the user interface elements of your prototypes programmatically. You can design the layout in Photoshop and convert the layer groups in your PSD into Framer’s Layer
objects. You also have the option to purchase and use Framer Studio, an IDE built specifically for working with Framer projects.
To learn more about the Framer framework, you can refer to Framer’s documentation. In the second part of this series, I will dive deeper into navigation, scrolling, and animation.