Classes, Loops and Arrays in Framer
Alright, so designers — listen up. Programming is awesome. In the beginning, it feels a little bit like magic. Once I figured out how to build my own designs in code, I felt incredibly empowered. Thanks to tools like Framer, pioneering new interactions is easier than ever before. This gives me as a designer the power to quickly try out how a complex interaction could work, instead of having to spend valuable time with engineers, just to try out an idea we might never even run with.
But before I got to that point, there was a fair bit of copy/pasting snippets from the web, error messages, head-scratching, hair-pulling, misunderstandings and frustration. That’s usually how it is when I’m picking up a completely new skill, regardless of what it is. Learning a new skill is hard and accepting that it’s going to take a while to understand the basic concepts of a new skill isn’t something that’s necessarily easy to do. But once I passed that initial learning curve, it was oh-so ridiculously rewarding. This image pretty much sums up how I felt when I began learning code.
When I first started learning how to prototype in Framer, my biggest frustration was the lack of fidelity I could achieve, without having ridiculously long files. Most of the prototypes I made was just adding some click events to images. Essentially pushing users back and forth between those images. I wasn’t satisfied with the level of complexity I could achieve, relative to the effort I put into building my prototypes. I simply didn’t think they were high-fidelity enough, because I had seen what other people online were doing with the same tools that I had at my disposal.
Over time I learned that most of the techniques that were used to create really high fidelity prototypes, wasn’t really that hard to figure out. They just weren’t readily available to me, because they were programming concepts — not design concepts. I didn’t know what to search or look for, so I just did what I’d do in any standard static design software; duplicate and modify tiny bits of the same object, and slowly but surely venture down a deep, dark path to complete spaghetti-code hell. I learned automation the hard way, probably like most people.
So without further ado, here’s a few concepts that I really wish I knew when I started off!
I use custom classes in Framer for modeling/designing more complex interface components. (i.e: A product detail view, a card or something similar with multiple objects, states, events and whatnot.) This allows me to properly manage consistency across different parts of a prototype, because I can just call my new class to generate a detail view template, and easily modify the base class to quickly iterate on my designs. Let’s dive in!
TLDR: Classes in Framer lets you make reusable interface components that includes interactions, states and animations for your prototypes.
Example 1: Class with state
There’s a bunch of funky stuff going on in this prototype. I’ll break down the parts that are not so obvious, so download the source code and fire up Framer!
Imagine that you’re making a prototype of maybe just one interaction. You spend some time perfecting the timings, positions and whatnot, present it the stakeholders and get something like this in return: “This looks and feels great. But can we add this other thing to the prototype as well? That would be really great”.
That might not be so easy to do without rewriting a lot of your prototype. Your code might be all over the place, if you only planned to demonstrate one specific interaction, and not a bunch of different interactions in the same prototype.
Classes helps you stay organized when you’re building complex interface components, since everything is kind of linked together. As I mentioned before, every component that’s used inside Framer is class based, this means that they are extensible — which means you can get all the awesome-sauce that the Framer team built into for example, the Layer class, and then add your own code and design on top of that!
The basic principle used in this example is extending the Layer class that the Framer team already created. We can do that like this:
class Card extends Layer
constructor: (options) ->
options.width = 500
options.height = 700
options.backgroundColor = "#28affa"
In the example above, I have done exactly that. Everything that has to do with that card is completely contained within the Card class, so just like you would add a new layer, I can now call my new class in order to generate a new card with my custom design without having to copy/paste crazy amounts of code, over and over again! You can make a new instance of your class, just like you would create a new layer, or any other object. Like this:
cardA = new Card
Within a class you can do anything you can imagine doing to a regular prototype. You can add sub-layers, events, states, if/else statements, etc. It’s almost like a mini-prototype within your prototype! Classes really shine when you start building very large prototypes with a lot of different stuff going on, maybe even with real data, as opposed to demonstrating a single interaction.
Add custom options
Now, this wouldn’t be perfect without having our new cards contain some unique data, right? Ever wonder how and why the properties are set up for a Layer the way they are? It’s pretty much class-based, just with a higher level of complexity. But it doesn’t have to be! You can make your own options that lets you add a bunch of new “keywords” that you can use for your class. In this case I added a title, that lets me write a custom title, with text. There’s also a description and a custom photo field where the cover photo for the card goes.
Custom options can easily be made by creating new keywords inside whatever property you want to customize. In our case we want to have a custom text field for our card description. Here’s a small excerpt from the the description layer in our example above.
description = new Layer
The keyword here is options.description, which tells our class that we want the new object to accept some type of value here. In this case, a text string, as that’s the data type that the html property accepts. Here’s what it looks like in reality when you’re making a new instance of your class with your custom options.
cardA = new Card
title: "My cool custom card"
description: "This is my first custom card class component. Cool!"
Thanks to this method, we can give our interface unique content, giving our prototype a look that is even closer to the real thing, instead of using repeat content over and over again.
Loops and Arrays
“But Øyvind, I still have to repeat myself a bunch of times! This class-thingy-snippet just lets me copy/paste less code now!”
Don’t worry. You won’t have to, this is where Loops and Arrays come in. Let’s dig into the next example.
Example 2: Loop generated Cards with custom data
Grab the source: http://share.framerjs.com/qukn2sbd85oi/
Building on the example we had before, in this example we’re using a Loop to generate a bunch of instances of the Card we created earlier.
In short, a loop is essentially a block of code that will run a given amount of times. They generally look something like this:
for i in [0..4]
print "This code is looping!"
That code would print the text “This code is looping!” five times. Now, this might be a little confusing because it doesn’t actually say five (5) in the loop statement that we wrote, but four (4). The reason why it’s running the code five times is because our loop starts counting from zero (0), not one (1). If you want to make your loop slightly more semantic you can write something like this:
for i in [1..4]
print "This code will loop four times!"
for i in [0...4]
print "This code will loop four times!"
So in our case, we create an instance of our Card as we normally would, just inside the loop this time, so that the loop will do all the hard work of making multiple copies of this for us.
for i in [0..4]
layer = new Card
Setting up our Array
Remember that we made some custom options for our class earlier? We could have a custom title, description and a cover photo?
Before we can insert the data into our cards, we need to model it. There’s a bunch of different ways you can do this but I’m going to cover the most basic one, which is just manually storing information in arrays. An array is simply an element that holds a bunch of different items, like other variables, strings, numbers. Essentially it’s a list of things. If you’re not familiar with the basic concept of arrays, check out David Lee’s article on how to use Arrays efficiently.
For our case, a few simple arrays with some text strings will suffice.
titles = ["New York City", "Amsterdam", "Rome", "Oslo"]
Note that an array is always enclosed with square brackets . Every item within an array has it’s own number, or index, if you will. The first item in an array is referred to as , the next one , and so forth. So for example:
Would print the text string “Oslo” to the console.
Looping over the data in our Array
Using this information, in order to populate our cards with different types of data, all we have to do is reference our loop variable when we’re calling our array, inside our loop.
for i in [0..4]
layer = new Card
This way, the loop is counting the objects in the array, and mapping each text string to it’s own title, as our loop is making cards for us.
Using all of the techniques above, combining arrays with loops, generating custom components from your own classes and all other kinds of cool techniques — you should be able to create some pretty high-fidelity work!
Hopefully after reading this article, you’ll feel a little more like this guy, when you’re building your next prototype.
Click here to download all the source files used in this article, in case you missed them earlier.
And remember, that when in doubt––there is a great community built around Framer that I highly advise everyone that uses Framer for anything to join. Check out the official Facebook group, in addition to the Slack team where you can ask for help in #realtime.
If you found this story useful, I would love it if you hit the recommend button below. And if you’d like, follow me to get notified when I release new content! Best of luck with your prototyping.