In day one of this workshop, we're going to cover the basics of Framer studio. On day two, we'll convert a static Sketch mockup into an interactive prototype. We will publish our prototypes both to the web and to our phones.
Note: this workshop is written for Mac OS X users. Our prototype app will be an iOS prototype.
- Install the free trial of Sketch on your Mac
- Install the free trial of Framer Studio on your Mac
- Install the new Framer Preview app on your iPhone
- Open Framer studio, and choose
File > New
from the top menu to create a new prototype. - If you do not immediately see an iPhone 6s on the righthand side of the app, choose
Device > Apple iPhone 6s > iPhone 6s Silver
.- The color of your iPhone frame doesn't really natter, but I choose silver for its contrast w/ the phone's black screen)
- Choose
File > Save
and save the project asday-one.framer
on your desktop.- Worth noting: saving your project creates a folder called
day-one.framer
, rather than an individual file. This folder can be dragged onto the Framer Studio icon to open, or opened from Framer'sFile > Open
menu.)
- Worth noting: saving your project creates a folder called
Building with Framer is as easy as understanding its three main components:
- Layers
- States
- Events
Today, we're going to walk through each of these to create a simple interaction.
- To create a new layer, click the
Insert
button in the top left of Framer's UI and chooseLayer
- You should now see 2 things:
- Code that reads
layerA = new Layer
has been written for you on the left - A corresponding grey square has been created on the iPhone screen on the right
- Code that reads
- Click and drag the layer to move it around the phone's screen. As you do, you'll notice smart guides appearing to help you align your layer on the screen, while code is being written for the layer's x & y position on the left. I've positioned my
layerA
square in the center of the phone's screen. My code reads:
layerA = new Layer
x: 275
y: 567
To the left of the layerA = …
in your code, you'll notice a small square button with three lines:
If the handle is already highlighted (filled w/ a solid grey), great. If not, click the handle to highlight it. Now, turn your attention to Framer's center column. You should see the following:
These are the properties of the selected layer. You can change any of these values as you would in a visual design tool. As you do, Framer will write the corresponding code for you in the lefthand column.
Using this property inspector, change the border radius to 10
, the scale to 0.50
and change the background color to whatever you like (I've chosen a red color at 100%
opacity). Your code should look something like this:
layerA = new Layer
x: 275
y: 567
borderRadius: 10
scale: 0.50
backgroundColor: "rgba(255,0,0,1)"
On the iPhone's screen, your layer should now look like this:
This first set of properties you've now created for layerA
is the layer's default state. Keep this idea in mind as we move on.
States are variations of a layer that we can transition between. To add a state to layerA
, choose Insert > State > layerA
, like so:
You are immediately taken back into edit mode, where you can again change the properties of layerA
to whatever your desired values for this new state, already given the name of stateA
in your lefthand code editor. I've made the background white, the scale 2.00
and the rotation 45
.
My code for this new state looks like this:
layerA.states.add
stateA:
backgroundColor: "rgba(255,255,255,1)"
scale: 2.00
rotation: 45
And my layer now looks like this:
It's now time to add some interactivity to transition between this our default state and this new stateA
.
To add a Click
event to our layer, choose Insert > Event > layerA > Click > Click
, like this:
You'll see that Framer has written the following code for you:
layerA.onClick (event, layer) ->
The cursor is already indented for you to write the code for your event. This is the only line of code we need to write to add both interactivity and our transition animation:
layerA.states.next()
The full code for your event should now read:
layerA.onClick (event, layer) ->
layerA.states.next()
And you can now repeatedly click on your layer on the iPhone's screen to transition between the two states we've written.
What we just added, in programming terminology, is called a click event. How its above code reads, in human terms, is as follows:
layerA.onClick …
whenlayerA
is clicked, perform the actions listed on the below, indented lines (while we've only written one line below, we can, theoretically, add as many as we like to be performed whenlayerA
is clicked)layerA.states.next()
Whatever the current state oflayerA
, transition to the next state. Per our example:- If our square is in its default state that we first created (the small, red square), transition to
stateA
(the larger, rotated white square) - However, if
layerA
is already instateA
, transition back to its default state
- If our square is in its default state that we first created (the small, red square), transition to
- Keep Framer Studio open on your Mac
- Make sure both your iPhone and Mac are on the same Wi-Fi network
- Open the
Framer
app on your iPhone - You should see a thumbnail of your project w/ its file name listed beneath; click to open it
- You will be prompted to enter an access code from Framer Studio. Click the
Mirror
button just above the center column in Framer Studio on your Mac and enter the code shown into the Framer app on your phone (Note: your access code will be different from the one listed below):
You should now be able to interact w/ the prototype on your iPhone.
Getting Back to Framer Studio on your Mac, let's insert another State to see what happens.
Just as before, use the Insert
button to add another state:
You should now see stateB
highlighted in your code editor, and you're already in edit mode in the center panel.
For our stateB
values, I've chosen a blue background color, 8.00
for the scale (I had to enter this via my keyboard — the slider doesn't allow such a large input value) and a rotation of 180
:
stateB:
backgroundColor: "rgba(0,61,255,1)"
scale: 8.00
rotation: 180
Now, when you interact with your layer, you'll see it cycle through its 3 states — default, stateA
and stateB
— each time you click. To see this on your phone, save your file (⌘ + S) in Framer Studio w/ your prototype open on your phone. You should see a blue load bar across the top of the Framer app on your phone to indicate that your changes have been published and the prototype is reloading.
Now that we have three states to work with, change the last line in our code from:
layerA.states.next()
To instead read:
layerA.states.next('stateA', 'stateB')
Now, as you continuously click layerA
, it cycles between its stateA
and stateB
states, never returning to its default, small red square state.
Finally, we'll add one more little block of code to govern the duration of our animation (Note: this should be a code block unto itself, and not indented beneath our layerA.onClick …
code):
layerA.states.animationOptions =
time: .5
As you can see, our transitions now move a bit more quickly. Animation duration in Framer is defined in seconds, so play around with this number to see how easily you can test different durations in search of the perfect transition. Be sure to save each time you change the value, so the prototype is updated on your phone
Worth noting: what little code we 'wrote' is was simply copied & pasted from Framer's Documentation. I encourage you to have a look at the docs on your own & add/remove code to the above example to see how it affects your demo.
Animated shapes are fun & all, but let's make a real prototype.
- Download day two workshop assets here
- Unzip
workshop-assets.zip
- Place the
SF UI
folder inHard Drive > Library > Fonts
- Open the
day-two-ui.sketch
file in Sketch
- Our prototype will transition between two views,
home_page
&detail_page
- Active click/tap areas are blue
- The top status bar & bottom nav bars will be made to persist in code, so we only need them on the
home_page
artboard.
- Layer names: use underscores in lieu of spaces or hyphens for consistency, as Framer will rename them using underscores
- Layers arrangement: top-to-bottom as they appear in the artboard (personal preference - easier to visually reference in framer's tree structure & design views)
- Sketch symbols: Framer can't read symbols. So, if your design uses them right-click each and choose
Detach from Symbol
to convert them into groups. (Note: we're not using symbols in this design) - Layer groups: groups are flattened into a single layers in Framer. These can then be referenced throughout Framer by their group name.
Note: if you have made any adjustments to the file, make sure it is saved in its current state and that Sketch is not hidden before importing it into Framer Studio.
- Open Framer studio, and choose
File > New
from the top menu to create a new prototype. - Save the prototype to your desktop as
day-two.framer
- If you do not immediately see an iPhone 6s on the righthand side of the app, choose
Device > Apple iPhone 6s > iPhone 6s Silver
. - Click
Import
, choose@2x
from the drop menu. - Click
import
to bringday-two-ui.sketch
into Framer Studio.
You should now see the following code denoting your imported file:
# Import file "day-two-ui" (sizes and positions are scaled 1:2)
sketch = Framer.Importer.load("imported/day-two-ui@2x")
-
2 Things to note:
- the line beginning with a
#
is a code comment. These are helpful messages that are ignored by our prototype. - In our code, this
sketch
variable you see above will be prepended along with a.
to the names of layers imported from our Sketch file. So, a layer calledhome_page
from our Sketch document is referenced in code assketch.home_page
.
- the line beginning with a
-
You should also see the hierarchy of your artboard & layer structure in Framer's center column, and the design on the iPhone's screen.
- These layers will now be accessible by name via Framer's
Insert
menu and can thus be affected with States and Events. The layers also retain their parent/child hierarchy as they had in Sketch (and as is illustrated in Framer's center column tree structure). As such, if we movedetail_page
in Framer, everything beneath it moves, as well.
Note: you can roll over layer names in the center column to see their positions highlighted in Framer's design view, even if they are off the phone's screen.
-
With the above note in mind, if you roll over the
detail_page
, you can see it's a little too far off to the right of our screen. We want it in position to immediately transition into view when we call for it. -
For this, we need a state for our
detail_page
layer. ChooseInsert > State > detail_page
. Now, using the center column, set the x Position of our new state to 750, like this:
- We now need one line of code to instantly set our
detail_page
to this state, with no animation or transition. Add this code beneath your state code, and be sure it's not indented:
# set initial detail_page position
sketch.detail_page.states.switchInstant("stateA")
-
If you now mouse over
detail_page
in Framer's center column, you'll see that it's right where we want it, ready to be transitioned into view. -
The whole of your prototype's code should now read:
# Import file "day-two-ui" (sizes and positions are scaled 1:2)
sketch = Framer.Importer.load("imported/day-two-ui@2x")
sketch.detail_page.states.add
stateA:
x: 750
# set initial detail_page position
sketch.detail_page.states.switchInstant("stateA")
- We now need a new state where
detail_page
is in view, or at0
x Position. Using ourInsert > State > detail_page
command, add a new state, and using the center column, add set the position to0
. Its automatically inserted code should read:
stateB:
x: 0
- Now, let's add some interactivity to our blue
label_one
button on thehome_page
to slide our detail page into view. ChooseInsert > Event > label_one > Click > Click
and paste the following code beneath the resultingsketch.label_one.onClick…
code, being sure it's indented:
sketch.detail_page.states.switch("stateB")
- Our full
label_one
Click event code should now read:
sketch.label_one.onClick (event, layer) ->
sketch.detail_page.states.switch("stateB")
-
This tells Framer, when a Click is detected on our
label_one
layer,detail_page
should now transition tostateB
. Save your prototype & click the blue text button to see ourdetail_page
come flying in. -
It's now time to add a state for our
home_page
to get out of the way when thedetail_page
makes its entrance. ChooseInsert > States > home_page
and set its position to-750
. -
Repeat this process and add another state for our
home_page
where its position is 0. Your fullhome_page
states code should read:
sketch.home_page.states.add
stateA:
x: -750
stateB:
x: 0
- Add the following line to our
label_one
Click Event code:sketch.home_page.states.switch("stateA")
. The entire event should now read:
sketch.label_one.onClick (event, layer) ->
sketch.detail_page.states.switch("stateB")
sketch.home_page.states.switch("stateA")
-
Now, when we click our blue label button on the home page, we see the
home_page
exit to the left as ourdetail_page
makes its entrance. -
Functionality-wise, all that's left is to afford our
back_button
layer on the Detail page the same functionality, only backwards. ChooseInsert > Event > back_button > Click > Click
, and add the following two lines of code to our resulting Click event, making sure they're indented:
sketch.detail_page.states.switch("stateA")
sketch.home_page.states.switch("stateB")
- You should now be able to transition from the Home to the Detail page and back again using our two active buttons to which we've applied Click Events.
- First off, we want our
status_bar
andbottom_tab_bar
layers to persist throughout, just as they would on a real iOS app. To achieve this, add the following two lines of code:
# make status & nav bars persistent
sketch.status_bar.superLayer = Framer.Device.screen
sketch.bottom_tab_bar.superLayer = Framer.Device.screen
- Now, all that's left is our transition — it's way too slow. The following two lines of code will set us right:
# set our global transition animation time
Framer.Defaults.Animation =
time: .4
And that's it! For reference, here's the entirety of the code for our prototype:
# Import file "day-two-ui" (sizes and positions are scaled 1:2)
sketch = Framer.Importer.load("imported/day-two-ui@2x")
sketch.detail_page.states.add
stateA:
x: 750
stateB:
x: 0
# set initial detail_page position
sketch.detail_page.states.switchInstant("stateA")
sketch.label_one.onClick (event, layer) ->
sketch.detail_page.states.switch("stateB")
sketch.home_page.states.switch("stateA")
sketch.home_page.states.add
stateA:
x: -750
stateB:
x: 0
sketch.back_button.onClick (event, layer) ->
sketch.detail_page.states.switch("stateA")
sketch.home_page.states.switch("stateB")
# make status & nav bars persistent
sketch.status_bar.superLayer = Framer.Device.screen
sketch.bottom_tab_bar.superLayer = Framer.Device.screen
# set our global transition animation time
Framer.Defaults.Animation =
time: .4
Disco.
- Quick Tour of Framer's New Auto-Code
- Framer Documentation (Also available from within Framer studio via the
Docs
menu button) - Sketch App Sources: giant repository of free sketch UI assets & resources