Framer, Prototype
Image Gallery Prototype

Image Gallery Prototype

In this prototype, we’ll look at creating an image gallery, where each image is clickable and brings the image front and center. This prototype was inspired by Framer’s Learn and Teach examples.

We’ll first create a scrollable set of images using Sketch. To get started, download the scrollable template provided by Framer. This template has one column of images but for this prototype I’m going to make it two columns and add in a tab bar.


To create our images, we’ll create a rectangle that has a width that is half the screen size (375px) and then duplicate it into rows and columns using the “Make Grid” function. 

Sketch Make Grid

Once you have the placeholders for the images, you can select them all and use the handy Content Generator Sketch plugin to insert random photos.

Sketch Content Generator

When we import to Framer, we need to make sure that our image layers are grouped, even though there is only one layer inside the group, so we can access them. Also make sure the structure is correct with masking so the scroll component will function correctly.


We can then import the Sketch file with one click using the Import button in the toolbar. We can rename the imported layer name to something else — in my case, I’m calling it “sketch”.

To make the layers scroll, we’ll create a ScrollComponent by using the wrap function, assign it to a variable and pass in the content group from our Sketch file.

When we scroll to the bottom, you’ll notice the last two pictures get cut off because of the tab bar. 


To display the images above the tab bar, we can set the bottom value of the ScrollComponent’s contentInset property to be the height of the tab bar.

Since we only want to scroll vertically, we can disable the horizontal scroll.

We’ll also want to set the ScrollComponent’s propagateEvents property to false. This prevents any draggable subLayer from passing events to its superLayer.

We are going to want to set the same properties and click events to each image so to save time, instead of setting each image individually, we’ll store the images in an array and loop through them to set them all at one time.

Another way to write this is with each layer on its own line without a comma. You’ll need to be sure to indent properly.

We’ll also store the navigation bar, tab bar, and scroll component so we can hide and show them when an image is clicked.

Now that we’re setup, we can go through each image and apply some logic. We’ll use a for loop to go through all 20 images. 

When we click an image, we’ll pass in the event and layer argument. The event provides information, like where the click took place. The layer is the layer that the click event happens on.

We’ll want to make sure that we aren’t scrolling when the click event happens. We can use the not keyword and isMoving property to check.

Another way to write this is

When we detect a click, we’ll make a copy of the image and place it behind the navbar layer using the copy and placeBehind function.

We’ll set its frame, which contains the x and y position, which we can return to later, to the screenFrame and hide the layer.

Since we don’t want the click event for all the images that we previously set to go off, we can set the ignoreEvents property for all the images to ignore any events.

In CoffeeScript, we can also write it like this:

We’ll then animate the copied image to the middle of the screen by setting its midX and midY property to half the screen height and width. We’ll also scale the image to the width of the screen by setting the scale property to the screen width divided by the current width. 

We can also play with the curve to get the feel and timing of the animation right.

We’ll then hide the nav bar, tab bar and ScrollComponent by looping through the array we created earlier and setting their opacity property to 0.

To return to our initial screen, we’ll give the zoomed in image a click event that will set its scale to 1 and x and y position to the screenFrame x and y position we saved earlier. We can use “this” instead of typing out currentImage.animate since currentImage is the event we’re listening to.

When the animation ends, we’ll want to show the original layer again and remove the copied layer using the destroy function.

Since we’re returning to our initial screen, we’ll need to also show our nav bar, tab bar and ScrollComponent array again by setting it’s opacity to 1.

Finally, we can set the ignoreEvents for all the scroll images back to false.

Here’s what the entire for loop looks like:

Just like that we have a prototype of a gallery of images that can be clicked on to zoom in and out. Here’s what my prototype looks like:


You can check out my Image Gallery Framer project and the full code here.

Also, be sure to check out the version the Framer team put together and all of their Teach and Learn examples.

You can try expanding this prototype by adding additional properties to the zoomed in image, changing the gird layout, or adding additional events.

Do you want to see more Framer prototype tutorials like this? Leave a comment below or share your thoughts with me on Twitter (@kennycheny). If you want to know when I post new content, join the mailing list and be the first to know.

Want more Framer content like this?

Share this Story

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

About Kenny Chen

Hi, I'm Kenny - a UX Designer from Los Angeles who believes that beautiful, subtle movement enhances the user experience and makes products more engaging, dynamic, and memorable. My goal with Prototyping with Framer is to help you design amazing interaction and animation prototypes.