Twitter Heart animation tutorial in FramerJS

Baisampayan Saha
6 min readJun 25, 2017

--

Framer has come a long way as a prototyping tool. One of the recent update saw the inclusion of Design window along with the code window.

We will recreate this animation in Framer Studio

twitter heart animation

Press “A” to open the artboard window on the righthand side or click the artboard icon on the lefthandside and choose Google Nexus 5X as the artboard.

Create an artbaord to start designing in Framer Studio

Press “O” to activate oval tool and then click drag on the artboard to create two ovals. If you press and hold “shift” “option”and click drag, the ovals will scale proportionally and be circles. Then press “R” to activate rectangle tool and click drag to create a rectangle. Press and hold “shift” “option” again to create a sqaure. Rotate the square to 45º.

Create another rectangle. This will be used to contain the colored dots that come out of the heart when tapped.

The artboard should seem something like this after creation of all the elements.

The Fill of the elements is put as “#D6E4FF” and Fill percentage as “100%

elements of the heart

We will group all the elements to form the heart shape and should seem something like the screen below. Try out different sizes and arrange them together to create the heart shape.

I have renamed the elements as — rectangle1 : heart, rectangle2 : wrapper, oval1 : part1, oval2 : part2

Now drag the oval layers which we have named as part1 and part2 and the wrapper layer under the rectangle layer named heart. This would make the heart layer as a parent layer for all the elements. The wrapper layer should be at the bottom so that it is not visible.

Elements ordered properly

Right click on each element and click on “create target”. This would enable us to target this layers for animation in the code window. Concentric blue dots should appear in the right hand side when you create a target.

Targets created for each elements

Now select the heart layer from the left hand side and lock the constraints of the layer in the position setting in the right hand side. This would keep the hear layer in the center in any resolution. Try and play with all the settings to see which fits your purpose.

A simulation can be seen when you hover your mouse over the position setting box.

Now lets code this thing up in the code window.

Lets create a background for the animation. This layer can be used later to reset the animation.

bg = new BackgroundLayer

The heart I have created is too big. So I decided to scale it down a bit.

heart.scale = 0.6

Our aim is to generate few colored circles from behind the heart and traveling randomly in every direction when heart is tapped and to change the color of the heart to a shade of red.

To do all this we need to create few functions which would do all the animations for us.

A function is a small spinet of code which can be reused again and again. For example, if we write a function to change the background color of layers, then this function can be used to change any layer in the prototype. Thus instead of writing a block of code for each layer which would change its background color, the function can be called to change it thus saving time and making the whole code succinct.

The syntax for writting a function is :

The “layer” in someFunction is a parameter of the function. When the fucntion is called, the parameter effects the output of the function. The parameter can be a “value” or even can be a “layer” in the prototype or can be “anything”.

Sometimes a function does not have a parameter and is self contained. In that case “(layer)” is not written after the “=” sign and is simple written as

To create random circles in different direction lets create a function which would create random (x,y) coordinates for the circles.

We need another function which would randomly change their opacity so that the circles would have different opacity and look random during the animation.

randomXY = -> 
return Utils.randomNumber(-300,300)
randomColorAlfa = ->
return Utils.randomNumber(0,1)

Utils.randomNumber generates random numbers between two set of numbers

randomXY would generate random values of x and y between -300 and 300

randomColorAlfa would generate random values between 0 and 1

You might have noticed “return” used in the function. This returns a value when the function is run.

Now lets create another function which would change the color of the heart.

changeHeartColor = (layer) ->
layer.animate
backgroundColor: “#FB0271”
options:
time: 1

We can animate a layer by adding “.animate” after the layer’s name and the targeting the attributes we would like to change during animation. Here we wanted to change the backgroundColor and also effect the time in which the animation should complete.

Lets create another function which would create an array of circles, animate them and then after the end of animation destroy the circles.

To do that we need to create an array of circles. The syntax of creating an array is :

For this tutorial we don’t need to use array but we need to create an array of layers which we would style them as circles.

# function to create the colored circles and then animate them. animation_cirlces = -># this creates 11 circles of "#FB0271" color.
for i in [0..10]
circles = new Layer
width: 19
height: 19
parent: wrapper
x: Align.center
y: Align.center
borderRadius: 20
backgroundColor: "#FB0271"
opacity: randomColorAlfa()
# we have used a function here randomXY() which was defined in the beginning and which generates random coordinates between 2 limits that we have specified in the begining. This would make the circles fly away in random directions circles.animate
properties:
x: randomXY()
y: randomXY()
scale: 0
options:
time: 1
delay: 0.2
# we need to clear the circles created to give an effect of fireworks exploding. we can either reducde the opacity to zero or destroy the circles. If we reduce the opacity than the circles would start accumulating after few uses and the prototype would become sluggish. To destroy we can do that by writing circles.destroy(). We can write the same thing in shorthand by this.destroy() or @destroy() circles.onAnimationEnd ->
@destroy()
# this creates another set of 11 circles of "#50E3C2" color.
circles2 = new Layer
width: 19
height: 19
parent: wrapper
x: Align.center
y: Align.center
borderRadius: 20
backgroundColor: "#50E3C2"
opacity: randomColorAlfa()
circles2.animate
properties:
x: randomXY()
y: randomXY()
scale: 0
options:
time: 1
delay: 0.2
circles2.onAnimationEnd ->
@destroy()

The code can show errors due to the spacing. In that case, delete the indents and use “tab” to give indents. If you are not confident enough, download the tutorial from the link below and check out the code.

I have tried to cover basics of arrays, for loop and function in this tutorial.

Happy prototyping and if you have any queries, comment and I would try to answer them as soon as possible.

You can play with the framer prototype from here

Check out another tutorial:

“Floating Action Button with Gooey effect tutorial in FramerJS”

--

--