New to Framer?
Just 3 Things to Get You Started

David Lee
Framer
Published in
12 min readJul 13, 2015

--

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’s changed People at Google, Facebook, Twitter,Dropbox, and many other companies make prototypes during their design process. Because prototyping fills a design space we tend to overlook, time. We can also name many other reasons why we prototype.

In the world of prototyping, you have a variety of tools you can choose from. If you are a developer or experienced in any kind of programming language, you probably have wider choices than others. But for those who are only comfortable with WYSIWYG tools such as Photoshop or Keynote, Framer can be the hammer of Thor.

Many designers around me tried to learn Framer but ended up lost in the world of prototyping. They say it was too hard because they had little experience in computer languages. That could be true to some extent. I understand. But I think it is not the biggest hurdle for them. It’s a matter of mindset. I don’t want to say it’s easy, but it’s just strange because it’s new. New things always seem to be harder than they are.

Framer was born to make our life easy not to torture us. If you are new to Framer or gave up before, this article is for you. I’ll explain just 3 Things to get you started.

Prerequisites

Before I go into the 3 Things, I want you to know the very basics that are common across modern computer languages. Framer uses Coffeescript which is a simpler way of writing JavaScript (JS). I can’t say it’s easy but it’s good to learn and good to know because JS is one of the most widely used computer languages in the world. So the skill you learn from this will be also applicable on the web in general.

There are a few things you need to know about Coffeescript. If you are already familiar with the basic concept of computer languages, you can skip this part.

Assign

‘=’ is not equal sign in programming languages. It means assign. The value on the right side is assigned to the left side. For example,

number = 12

In this case, number has the value 12. If you assign other types such as 0.1, then number will have 0.1.

Variable

In the example above, you would probably wonder what the number is. It is called variable. Many other computer languages including JS require you to declare before you use the variable. (e.g. var number = 12 or int number = 12) But in Coffeescript, you don’t. You can just name the variable where you want to use it for the first time. Just remember that you can’t give a variable name that starts with a number (e.g. 2nd).

Unlike other computer languages, Coffeescript doesn’t have variable types either. So you can assign any type of variables (such as Integer, Float, String, Array, Object, etc). For example,

opacityValue = 1          #Integer type
scaleValue = 1.2 #Float type
howOld = "I am 12." #String type

Dot

If you import your Sketch file into Framer Studio, you will see a new line like below. (I’ll explain about import in the later section.)

example = Framer.Importer.load("imported/example@2x")

You can think of dot notation as a connector between the name(variable) of the imported file, example and any layer you made in Sketch. For example, if you want to access (or change the properties of) the layer circles (refer to the picture above), then you can write like this:

example.circles

But it’s an incomplete sentence. It’ll produce an error. So you use dot to access its properties to assign values to them. You can assume that each layer in Framer (Object type) has its own properties you can access through dot notation. And regardless of its layer hierarchy, you can directly access any layer through example as below.

example.circles.scale = 1.2
example.circle1.opacity = 0.5
example.circle1.rotation = 90
# opacity and rotation are the properties of layer circle1.
# you don't need to do like this: example.circles.circle1...

Indentation

Indentation is used to define the structure of the language, replacing { and } in other languages such as JS. So indented lines belong to one level higher (that is less indented) lines.

function = ->
layer.animate
properties:
opacity: 1
rotation: 90
# layer.animate belongs to function while properties: belongs to layer.animate, ...

That’s it!
Of course, you will need to learn more than just the above. But I think this will already suffice for making lots of transitions and animations. Here you’ll see how.

The Three Things

The learning page of the Framer website explains well about the basics. But I tried to distill even more for the very beginners.

The basic concept of animation follows a natural phenomenon. If you push (event) something (layer), it moves (state changes). So if you click on a button, then it behaves according to the force you put into or, more easily, the way it was prescribed (state).

The 3 Things: Layer, Event, and State

So you need to know at least 3 Things to make an animation (Layer, Event, and State). (State includes animation options such as how fast it will be.) You’ll soon love the combination of those three.

Layer

You can create layers directly in Framer but I wouldn’t recommend that way because you have to set up the properties every time you make a layer. (e.g. x and y positions, width and height, background color/image, etc.) It is time-consuming and not WYSIWYG. I think setting properties in Sketch is easier for designers. Plus, I think it is better for you to focus on interactions in Framer and do the graphical work in Sketch.

The easier way is here. You can just import layers from Sketch (or Photoshop). Then Framer will setup all the properties for you as you set in Sketch. So you don’t need to change properties again in Framer.

If you want to change the properties of layers, you can either import again after you edit in Sketch or of course directly edit in Framer. (Sometimes it’d be better to make a layer in Framer if you want certain CSS transformation effects such as dynamic sizes of radiusCorner. I’ll cover those cases in the next articles.)

Okay. Before we get started, you need FramerStudio on your Mac. For Windows and other OS users, you can download framer.js and include in your favorite IDE such as Sublime Text or WebStorm.

FramerStudio 1.1

Please download this Sketch file for the following exercises.

Import layers from Sketch

First, import your Sketch (or Photoshop) file into Framer. Just click the import button on the top left and on the popup layer click import Sketch button. Only available (currently running) apps will be activated. If you’re successful, you will see a new line like below. You can change the variable name on the left. I changed it to the inbox which will be our example app.

inbox = Framer.Importer.load("imported/framer101_inbox@2x")

Now you can access all the layers in the Sketch file through the variable inbox and change their properties. For instance,

inbox.fab.scale = 1.2     # fab is floating action button
inbox.overlay.opacity = 0.5

So there are not many things to do in this stage because Framer already did laborious tasks for you by importing layers from Sketch.

Event

The next thing you need to think about is what event you will add to a layer you want. The layer will start listening to the event you assigned. You can’t interact with layers unless you add events on it.

Framer supports many input event listeners such as Click, TouchStart, TouchEnd, Drag, Scroll, etc. You’ll probably know how they work by their names. Let’s see how Click and Touch events work since they are perhaps the most common input methods.

Let’s first describe what we want for the layer in human language.

let this layer listen to click event.
(when clicked) do this.

If we change it to Coffeescript language,

inbox.fab.on Events.Click, ->   # equivalent to inbox.fab.onClick ->
inbox.fab.opacity = 0

The first line of the code above will equip the button (fab) to be ready for click events. The next indented line defines what action to be done. In this case, the button will disappear (opacity = 0) upon click.

You can also divide click events into two separate events, namely TouchStart (pressed) and TouchEnd (released).

inbox.fab.on Events.TouchStart, ->
inbox.fab.opacity = 0
inbox.fab.on Events.TouchEnd, ->
inbox.fab.opacity = 1

In this case, the button will disappear while you’re pressing it and appear again upon release.

You may wonder what .on, comma and arrow(->) notations are. But you can just think this is the way to assign an event to a layer. You’ll always use it in the same way whenever you add an event. (For those who are still wondering, please refer to the framer docs about .on and function. But it may make things more complicated at this moment.)

You can check if the event works by seeing the state change of the button (opacity). Alternatively, you can use print command before you apply any specific action to an event.

inbox.fab.on Events.Click, ->
print "clicked!"
Upon click, the FAB disappears and the message “clicked!” is printed.

State

Now you are able to make a layer that responds to a click event. But it disappears suddenly which is not natural. State is magic dust and the reason why Framer is powerful.

You can simply think of the state as a preset animation between states A and B. Normally you have the initial state of a layer (state A) as it’s imported from Sketch. Then all you need to do is to add state B. For example,

inbox.fab.states.add
fadeout: # name of the state
opacity: 0
scale: 1.5
# indentation defines the structure (hierarchy and block).

So this is state B, fadeout where state A is default (opacity: 1, scale: 1).

Now you can apply fadeout state to the click event as below. So when you click the button, the default state becomes fadeout state. You can see it for yourself. Isn’t it cool?

inbox.fab.on Events.Click, ->
inbox.fab.states.switch("fadeout")
# alternatively, you can use .next() instead of .switch("state").

But the duration and the way it is changed is not quite satisfactory. Because it animates according to the default option set by Framer. Let’s change the animation option below.

inbox.fab.states.animationOptions = curve: "spring(300, 30, 0)"

There are some ways to define the type of animations. But spring gives the most natural results. So most of the time you use spring instead of linear or ease. The three values inside the parentheses are tension, friction, and velocity in order.) I mostly find the right animation by adjusting tension and friction leaving velocity as 0. I just start with “300, 30, 0” then change them later. You can play with them on Noah Levin’s tutorial page. (FYI, @cemregungor also tend to start with “300, 30, 0” while @jordandobson starts with “500, 50, 0” and @benjaminnathan with “400, 30, 0”)

That was the 3 Things! With Layer, State, and Event, I think you’re now ready to go through the real-life prototyping!

Example: Google Inbox

Google introduced material design guidelines about a year ago. One of their noticeable design components is FAB (floating action button). We’re going to make a transition effect for FAB in Google Inbox app. Here’s what we’re going to make.

Inbox 1–1

Okay. Let’s get started. Take a moment to look around the .sketch file inside the .framer folder. I believe you have already imported the Sketch layers below.

The first thing we need to do is to hide the circular option buttons and the white overlay. We’re going to hide them first and then make them appears when the FAB is clicked. In order to do so, we need to know the names and structure of the layers in Sketch file. Because we’ll access them by their names in Framer.

It consists of four top layers (options, fab, overlay, and bg). We want to access and hide options and overlay layers. We also need to hide the write(pen) icon in FAB because it should appear when clicked.

inbox.options.opacity = 0   
inbox.overlay.opacity = 0
inbox.iconWrite.opacity = 0
# opacity 0 is transparent while 1 is completely opaque.

Before adding a click event to the FAB, let’s define associated states first. If we click the FAB, the white overlay and circular option buttons should appear. So we add states for them.

inbox.overlay.states.add
on:
opacity: 1
# equivalent to on: { opacity: 1 }

inbox.overlay.states.animationOptions = curve: "spring(300, 30, 0)"
inbox.options.states.add
on:
opacity: 1
inbox.options.states.animationOptions = curve: "spring(300, 30, 0)"

We just registered on states for overlay and options layers. Let’s make them alive upon click.

inbox.fab.on Events.Click, ->
inbox.overlay.states.switch("on")

Alright. Now let’s make the overlay gone when you click on it.

inbox.overlay.on Events.Click, ->
inbox.overlay.states.switch("default")

We haven’t defined the default state. But as I mentioned before, default state will be automatically registered once you add a state. So we can say the default state is the state when you imported from Sketch (unless you change the properties before you add the state).

Let’s now repeat the same process with the options layer.
Then voila! It works!

Yeah I know.. But it’s too early to be disappointed. We have more magic dusts to put into. Let’s make a rotating animation for the icons (write and plus) in FAB.

We’ll set the write icon rotated in minus 90 degrees. We already set its opacity to zero before.

inbox.iconWrite.rotation = -90

Then we add a state for it. Note that I increased the tension value.

inbox.iconWrite.states.add
on:
opacity: 1
rotation: 0 # it will rotate 90 degrees clockwise.
inbox.iconWrite.states.animationOptions = curve: "spring(500, 30, 0)"

Then add the state to the click events.

inbox.fab.on Events.Click, ->
inbox.iconWrite.states.switch("on")
inbox.overlay.on Events.Click, ->
inbox.iconWrite.states.switch("default")

For iconPlus layer, you can add a state like below.

inbox.iconPlus.states.add
on:
opacity: 0
rotation: 90
# equivalent to on: { opacity: 0, rotation: 90 }
inbox.iconPlus.states.animationOptions = curve: "spring(500, 30, 0)"

Once we put all together, it’ll be like below.

We still have one more magic dust left. Let’s make a scale animation for the circular option buttons. You can download and look around another Framer file.

Inbox 1–2

We first set the initial scale to 0.5 for all the face layers.

initialFaceScale = 0.5inbox.face1.scale = initialFaceScale
...
inbox.face5.scale = initialFaceScale

Then add states.

inbox.face1.states.add
on: { scale: 1 }
inbox.face1.states.animationOptions = curve: "spring(500, 30, 0)"
...

Then add it to the click events. You can optionally tweak some vertical transition effects for name layers. That’s it!

If you think it was too easy for you, you can look into the link below which you can learn how to minimize code and understand why Framer is powerful over other tools.

Inbox 1–3

If you are still thirsty, you can add more click events on the circular options buttons. Below is one example you could practice on your own.

Inbox 1–4

A hint for the delayed animation: Events.AnimationEnd or Utils.delay

Wrap Up

I hope you found a common pattern that makes animations in Framer. Just remember the 3 Things. You can already make tons of interactions that you may have in your mind.

  • Set properties of Layers
  • Define States
  • Add Events

I’m open to any corrections that could improve this tutorial. For questions, you can get great support from the Framer community. https://www.facebook.com/groups/framerjs/

The next article came out! Please check this out as well.

Thanks to junu for the title inspiration :)

--

--