Introduction
In my previous tutorial about Framer, you learned how to use layers, states, and events to create simple mock-ups for your iOS and Android apps. Framer has a lot more to offer though. In this tutorial, I am going to focus on a few more advanced features of the framework that allow you to add more complex interactions and effects to your mock-ups.
1. Nesting Layers
Because a layer can be embedded inside another layer, you can create complex layer hierarchies with Framer. An embedded layer is called a sublayer and the layer that it is embedded in is called its superlayer. The following code snippet shows you how to embed a layer within another layer using the superLayer
property.
var layer1 = new Layer({ width:200, height:200 }); var layer2 = new Layer({ width:100, height:100, superLayer: layer1 // makes this layer a child of layer1 });
You can make use of layer hierarchies to simulate multiple screens in your mock-ups. Let me show you how to do this with the help of an example. Consider a mock-up that has two screens, a login screen and a welcome screen.
The login screen contains input fields for the username and password, and a submit button. The welcome screen contains an image and a few lines of text.
To create such a mock-up, you could consider the login and welcome screens as superlayers and the user interface elements they contain as sublayers. Let’s start by creating the superlayers first.
var loginScreen = new Layer({ width: Screen.width, height: Screen.height, }); var welcomeScreen = new Layer({ width: Screen.width, height: Screen.height, });
As you can see, loginScreen
and welcomeScreen
are blank Layer
objects for now. Let’s add some sublayers to the loginScreen
layer.
// The CSS styles to be applied to the layers var style = { paddingTop: "25px", color: "#999", background: "#FFF" }; //Create the username field var usernameField = new Layer({ width: 500, height: 100, y: 100, html: "Username", style: style, superLayer: loginScreen // child of loginScreen }); usernameField.centerX(); // Create the password field var passwordField = new Layer({ width: 500, height: 100, y: 220, html: "Password", style: style, superLayer: loginScreen // child of loginScreen }); passwordField.centerX(); // Create the submit button var submitButton = new Layer({ width: Screen.width, height: 100, y: Screen.height - 100, html: "LOGIN", style: { paddingTop: "25px", color: "#FFFFFF", fontWeight: "bold" }, backgroundColor: "#2196F3", superLayer: loginScreen // child of loginScreen });
In the same way, let’s now add some sublayers to the welcomeScreen
layer.
// Create a layer to show a profile pic var profilePic = new Layer({ width:400, height: 400, borderRadius: 200, image: 'profile.jpg', y:100, superLayer: welcomeScreen // child of welcomeScreen }); profilePic.centerX(); // Create a layer for the welcome text var text = new Layer({ width: 400, height:100, y:600, html: "Welcome Jenny", backgroundColor: "", style: { color: "#FFFFFF" }, superLayer: welcomeScreen // child of welcomeScreen }); text.centerX();
At this point, if you try to view your prototype in a browser, it will look a bit messy. Both superlayers (loginScreen
and welcomeScreen
) are visible at the same time.
To hide a layer, you set its visible
property to false
. Here’s how you keep the welcomeScreen
layer hidden when the mock-up starts:
welcomeScreen.visible = false;
To change the view from the login screen to the welcome screen, you can simply hide the loginScreen
layer and turn on the visibility of the welcomeScreen
layer. The following code snippet shows you how to do so inside the click
handler of submitButton
:
submitButton.on("click", function(){ loginScreen.visible = false; welcomeScreen.visible = true; });
Go back to the browser and refresh the page to see your mock-up making more sense now. Remember that the browser you’re using to view the mock-up should be WebKit-based, such as Chrome or Safari.
If you don’t like the instant switch, you can animate the transition by using the animate
function to animate, for example, the opacity
of the layers.
submitButton.on("click", function(){ welcomeScreen.opacity = 0; welcomeScreen.visible = true; // welcomeScreen is still invisible // because its opacity is zero loginScreen.animate({ properties: { opacity: 0 } }); welcomeScreen.animate({ properties: { opacity: 1 }, time: 2 // Duration of animation is 2 seconds }); });
This is what the transition looks like now:
2. Using Layer Effects
Framer allows you to apply a variety of image effects, such as gaussian blur, hue rotation, brightness/contrast adjustment, color inversion, sepia tone addition, and more, to your Layer
objects.
The following code snippet shows you how to use the blur
effect to create a blurred background:
// Create a background layer var bg = new BackgroundLayer({ image: "bg.jpg" }); bg.blur = 5; // Set the gaussian blur to 5 pixels
This is what the result looks like:
The rest of the effects are used in a similar manner. For example, to reduce the contrast of the bg
layer, you need to modify the contrast
property:
bg.contrast = 50;
3. Creating Scrollable Layers
To make a layer scrollable, you need to embed it in the content layer of a ScrollComponent
object. Creating a ScrollComponent
is similar to creating a Layer
object:
var scroll1 = new ScrollComponent({ width: Screen.width, height: Screen.height, });
The following code block shows you how to embed a Layer
object within the content
of scroll1
:
var layer3 = new Layer({ width: 2000, height: 2000, image: "pattern.jpg", superLayer: scroll1.content // Embed inside content of scroll1 });
Here’s what a ScrollComponent
looks like in action:
Note that scrolling is possible only if the dimensions of the layer are larger than the dimensions of the ScrollComponent
it is embedded in.
4. Displaying Paginated Data
Sometimes, instead of continuous scrolling, you might want to present your data as a set of pages. For example, you might want to create an interface where a user swipes through a set of images. This can be done using a PageComponent
. The PageComponent
class is derived from the ScrollComponent
class and has an identical constructor.
To add a Layer
to a PageComponent
, you need to use the addPage
function. The following code shows you how to create a PageComponent
and add a few image layers to it:
// Create a PageComponent that fills up the screen var pageComponent = new PageComponent({ width: Screen.width, height: Screen.height }); // Create three images layers var image1 = new Layer({ width: Screen.width, height: Screen.height, image: "pink.jpg" }); var image2 = new Layer({ width: Screen.width, height: Screen.height, image: "grey.jpg" }); var image3 = new Layer({ width: Screen.width, height: Screen.height, image: "blue.jpg" }); // Add all the image layers to pageComponent pageComponent.addPage(image1); pageComponent.addPage(image2); pageComponent.addPage(image3);
The result looks like this:
5. Managing Animations
You already know that you can use the animate
function to animate the properties of a Layer
object. However, calling animate
starts the animation immediately. If you want to have control over when an animation starts or stops, you can use Animation
objects instead.
Here’s how you create an Animation
object:
var animation1 = new Animation({ layer: mylayer, // name of the layer that should // be animated // Properties that should change properties: { x: 400 } });
You can then use the intuitively named start
, stop
, and reverse
functions to manage the animation. For example, to start the animation invoke the start
function:
animation1.start();
You can also add event handlers to Animation
objects, using the on
function. This feature can be used to create chained animations. For example, here’s a code snippet that reverses animation1
when the animation ends:
animation1.on(Events.AnimationEnd, function(){ // Create a reversed copy of animation1 and play it animation1.reverse().start(); });
The animation would look like this:
6. Changing Device Orientation
All the examples I showed you till now rendered the mobile device in portrait orientation. If you want to use the landscape orientation, you need to assign the value 90 to the orientation
property of the DeviceComponent
.
device.orientation = 90;
In the browser, the device will now look like this:
To animate the change in orientation, you use the setOrientation
method, passing in true
as its second parameter.
device.setOrientation(90, true);
Conclusion
In this tutorial, you learned how to make use of Framer’s more advanced features, such as nested or embedded layers, layer effects, scrolling containers, and animation events. With a little bit of creativity and effort, you can now create stunning prototypes using the Framer framework. Here are some beautiful mock-ups to inspire you.
Refer to Framer’s Documentation to learn more about this powerful prototyping framework.