How to create a simple prototype with Code Overrides in Framer X.
The second Beta release of Framer X introduced a series of new code features. Learn how they all connect in this tutorial.
Framer is an interactive design tool for macOS. We’re working on an entirely new version: Framer X, which is currently in public Beta. Learn more about it here, and sign up to get notified when we launch. It’s coming this Fall.
Getting Started
To get started, you can download my iPhone X template here. It includes a single iPhone X screen with an image, a statusBar and a bottom bar. Feel free to replace the default image fill with your own. I picked one from Unsplash.
To follow along, open the template file in Framer X. Now, the first thing we’ll need is a slider. I’ve published a Slider component to the Framer X Store, which has all of the customization options we’ll need. To install it, follow the instructions below.
- Click on the Store icon in the left panel.
- Navigate to the search bar, in the top-right corner.
- Search for “slider”.
- Click on the “Slider” package with the cyan thumbnail.
- Click “Install”.
After installation, the slider will appear in the Components tab. Navigate to the Components (the icon looks like a grid), and you should see a Slider thumbnail. Simply drag and drop it onto our iPhone X screen.
In Framer X, there are two types of components: design and code components. A design component is created by selecting an existing element on the canvas. A code component is created from scratch, using React. This means you can render plain HTML and CSS, directly on the canvas. Or you can import your own design components, NPM packages or Framer elements and build on top of them. The possibilities are endless.
The slider you’ve just installed is a code component. It can be resized and repositioned, just like any other layer. If you inspect the properties panel, you’ll notice that it has a bunch of custom properties, like Tint, Track, Min, Max and a few more. These are properties I exposed from within the component, to allow you to customize it to your liking.
Customizing the Slider
Here’s how I’ll customize the Slider for our filter app. I’ll outline the changes below. You’re free to style it any way you see fit, ofcourse.
- Set tint to
#FFF.
- Set track to
#333
. - Set the Shadow alpha value to
100.
- Set constrain to
true
.
The constrain
property influences how far the knob can reach: if it is “constrained” within the sides of the track, or if it can be dragged all the way up to the center of the knob itself. The ranges (min, max, value) will depend on the actual filter value we’d like to manipulate per slider.
I’ll duplicate the customized Slider twice, as I’d like to be able to set the Brightness, Contrast and Hue of our photo. I’ll also add some text labels to easily distinguish the sliders from one another, plus an iOS-like header. This is completely optional, ofcourse.
Slider Ranges
Let’s also set the min
, max
and value
properties. The brightness and contrast sliders start at 100
and goes up to 200, while the hue slider starts at 0
and goes all the way up to 360.
- Brightness —
min:
0,max:
200,value:
100 - Contrast—
min:
0,max:
200,value:
100 - Hue—
min:
0,max:
360,value:
0
Creating Overrides
With our slider ranges set-up properly, we’re ready to start bringing them to life. We’ll need to create a way for the slider and the image to “communicate data” to one another—a way to connect them.
In Beta 2, we introduced the Code property. Select any Frame, click Code and you’ll have the ability to connect override functions to the selected Frame. These functions allow you to override styling properties like opacity and fill— but they also allow for interactivity and animation.
Adding Overrides
To bring our sliders to life, we’ll have to add an override function to the photo, and each individual slider. To add our first override, follow the steps below.
- Select the photo.
- Click “Code” in the properties panel.
- Select the “Override” dropdown, and click “Edit Examples.tsx”.
- This will open your default code editor. For me, that’s VSCode.
In here, you’ll find a few of our example functions. We won’t need these—so feel free to either delete them, or to create a new file (select the “File” dropdown, then “New File”) to start adding our custom overrides.
First, the import. We’ll only use Override
and Data
, so we can simplify the statement on top. This imports these two objects from the Framer Library.
import { Override, Data } from "framer";
It’s important to note that unlike in Framer today, you only animate values in Framer X. These animatable values can then be applied to any property, optionally on an Event, like onClick
. The Framer Library provides a Data
object that allows you to store these animatable values.
Setting Brightness
Our first goal is to connect the brightness slider to the photo. Once that is set-up, connecting the remaining two sliders should be simple.
We’ll start by simply adding a brightness
property to the Data object, and set it to 100
, to match the default value of our brightness slider.
export const data = Data({
brightness: 100,
});
Then, we need to make sure our image can receive the property defined within our Data object. We’ll create a new constant
, which I’ll call Effects
. In Framer X, code overrides and code components use TypeScript. A syntax deep-dive is beyond the scope of this tutorial, so for now, it’s important to know that it has to be typed withOverride
to allow Framer X to recognize it.
export const Effects: Override = () => {
return {
brightness: data.brightness,
};
};
The method receives props
as its parameter (the properties of the applied element), but as we won’t use those, I omitted them from the brackets. Now, select the Effects function from the Override menu. (Given that you have already selected the file at this point. If you’ve created a new file, you may need to select that first). Please note that this won’t make the slider functional just yet.
Now for the fun part—the slider itself. We’ll need a new override function. I’ll call it BrightnessSlider
, as we’ll need to connect it to the brightness slider. Let’s start by defining the function, along with its Override
type.
export const BrightnessSlider: Override = () => {
return {},
};
Now within the returned object, we’ll add an onValueChange
function. It has a single parameter: a numeric value (a value of the type number). This function is also a property of the Slider component itself. It updates the value whenever you move the knob, for instance. Within the function, we’ll set the brightness
value to the value
the actual slider returns.
export const BrightnessSlider: Override = () => {
return {
onValueChange: (value: number) => {
data.brightness = value;
},
};
};
Now, we can go back to Framer X, select the brightness slider, click on “Code”, select and pick the “BrightnessSlider” function from the Override dropdown. (If you’ve created a new file from scratch, you’ll first need to select the right File, too. If you’ve continued within Examples, you can directly select the method.)
And voila! Now all elements relating to our brightness slider are connected. Click on the play icon in the top-right corner of the app to open the Preview window. Here, you can interact with the slider.
Connecting All Sliders
From here on out, it’s pretty simple to extend our file to support the remaining 2 sliders. Find an outline of the steps below.
- We’ll need to extend the Data object with
constrast: 100
andhueRotate: 0
. Constrast starts at 100, like brightness, and hueRotate starts at 0. - We’ll need to extend our Effects function so that it will receive all three properties. Again we’ll add
contrast
andhueRotate
properties, set todata.contrast
anddata.hueRotate
respectively. - We can duplicate our BrightnessSlider function twice, and rename one to
ContrastSlider
, and the other toHueSlider
.
I’ll attach a screenshot of the final functions file below. You can also download my complete Functions.tsx
file here, or the finished prototype below.
All that’s left is to connect the contrast and hue sliders to their own override functions. And that’s it! 4 elements, one data object and 4 functions. The sliders remain completely customizable, from their ranges to their styling options. If you want to continue playing around, you could switch up some of the filters, like changing the hue
to saturate
instead. Or have a slider affect an entirely different type of property, likerotation
or scale
.
While overrides may be tricky to grasp at first—they’re very flexible, and can be used for so much more than overriding visual properties. Hopefully this sheds some light on its capabilities. Please feel free to reach out on Twitter if you have any questions. You can download the final .framerx
file below.