Web animations workflow with Principle and GSAP TimelineMax

Karlo Videk

Senior Front-end Developer

Learn how to create web UI animations in a simple and effective way, check out what our UI animation workflow looks like here @Degordian and how we use Principle prototype and GSAP’s TimelineMax to implement animations in the front-end phase.

As web expands, we have the need to do more than just add simple styles to our websites and apps. We want to make our websites and apps more usable, we want users to enjoy what they see and, at the same time, consume important information as soon as possible. Adding animation to our UI elements makes it interactive, makes it more functional and aesthetically pleasing. In this article, I will describe the process behind the implementation of these animations in the front-end phase – after designers handover their files and instructions. I will guide you through the whole process, from reading the animation prototype to coding. In this article, I will use a simple animation prototype my colleague Mario Šimić created for his article on animating with Principle.

Depending on the budget and time we have on a project, the fidelity of animation prototype can vary. Sometimes a simple sketch on a piece of paper that shows the start and the end state of an UI can help a lot – the duration and speed can easily be tweaked later. The important thing is that we need to define animations in the phase of design and the whole team should be involved to get a better result.

How we did it before?

Me and my fellow colleagues often left creating animations for the very end, after we would write the entire HTML structure, CSS styles, and sometimes even after implementing some back-end functionalities. I was not actually thinking about how elements would come on screen, how would they interact or depend on one another. Inputs from designer were a bit insufficient — “Just make this appear here, let it fade-in. The heading should enter from the top, the image should reveal from the right side…”. Also, we had more than a few iterations over a single animation — “Can you use a different ease, make it ease-out. Do you think this should go a bit faster? Can you refresh it again? Is this lagging a bit?”.

The end result was good, but not entirely satisfying for me and my team, not to mention the painful rewriting of the HTML structure just to make that element appear from that other position, rewriting animations in JavaScript, the dependencies between animated elements and their animations etc. Also, everything should be smooth and not trigger your computer’s cooling fans after a minute of browsing. Something needed to change because we burned more than a few hours over our budget and almost burned our MacBooks’ cooling fans on every project that had animations.

Changes. We looove changes… How we do it now?

Back to the start — animations should be defined in the design phase and then the prototype should be handovered to developers with the design files.

By making animations and animation instructions at the beginning, you make your front-end developer’s life easier and less stressful. We can prepare our markup easier, write our style rules better and save a lot of time while creating animations. Communication and cooperation in the prototype phase between designers and front-end developers is also a plus. You consolidate about stuff, make compromises and create better ideas together, and you also learn a lot from one another. It is easier for a designer to iterate in a mockup/prototype tool and make the animation perfect in e.g. Principle, than rewriting everything over and over again in CSS or JS.

To get the best possible result and to save time and resources, we adopted a new process and animation workflow.

Designers create the prototype of animations as we mentioned before. Ideally — an animation guide should consist of a video file, source file from Principle and textual guidelines that explain the animation flow. So let’s focus on Principle prototypes and working with them in the front-end phase of creating animations.

Principle offers a lot of possibilities to animate UI elements in many different ways. Everything that is prototyped inside Principle can be recreated in HTML, CSS and JavaScript. Its UI is easy to understand, and it’s very intuitive – even if you’re working with it for the first time. All the important informations are easy to read and to interpret — you can see the start and end position of all the elements, but most importantly, you can preview the entire animation timeline, events that should trigger the animation etc.
When a front-end developer receives the animation prototype, it is much easier to structure HTML because we know up front how a particular element has to behave, what CSS properties will change etc.

In this short step by step tutorial, I will not go through creating HTML structure and writing styles as the design of the example we use in this tutorial is simple and clean, and there should not be any problems in coding the layout.

Principle’s timeline helps a lot to see the durations and delays, as well as start and end points. These are some of the main features that made us use Principle in our workflow for implementing animations in websites and apps.

When we talk about mimicking Principle’s timeline, what is the best thing to use? Another timeline, of course. GSAP TimelineMax appeared to be the best tool to help us animate a sequence of elements. TimelineMax is an extended version of TimelineLite, and is a part of GSAP’s TweenMax library. Because of a larger number of useful methods TweenMax and TimelineMax have, we often use this extended version. We’ll assume you are familiar with the basics of TweenMax to follow and understand the workflow and animations written with GSAP’s library that are described in this article. If you want to know more about this awesome library and the vast possibilities it has, please feel free to read this article.

It is easy to follow the graphical timeline in Principle and to create a timeline in code using tween methods with TimelineMax (animators define a tween as a small animation that has some kind of a change between two states over a period of time, and in this article we will also call single animations — tweens). Timeline created with TimelineMax is in the end a sequence of tweens, where each tween itself represents one animated UI element in the timeline.

TimelineMax enables us to overlap certain tweens or delay their playback — you can place a tween anywhere in the timeline. If needed, you can even play it in reverse, nest timelines or trigger some other animations or functions at any time during the timeline, with built-in callbacks. TimelineMax gives you full control over your animations.

Step by step animation coding tutorial

Before transferring each tween from Principle to code, we have to set some general stuff for our animation to look better. To avoid a strange flash of animated elements, we first hide them (this can still happen with JS powered animations if the JS file takes longer to load). This can be done via CSS, but in this example we used TweenMax’s .set() method to select all animated elements (selected via “data-animated” attribute in our example) and set their opacity and visibility properties to be “invisible” when the page is loaded.

Code example:

HTML of an animated element

<h1 class="h1" data-animation data-js="title">Collection 2017</h1>

JS

var animatedElements = $('[data-animation]');
TweenMax.set(animatedElements, {
  autoAlpha: 0
});

After setting the visibility of animated elements, we store all of them in variables for easier manipulation and better readability of the code. In this example, I selected all elements via “data-js” selector using a simple jQuery shorthand.After setting the visibility of animated elements, we store all of them in variables for easier manipulation and better readability of the code. In this example, I selected all elements via “data-js” selector using a simple jQuery shorthand.

Code example:

JS

$.js = function (el) {$.js = function (el) { return $('[data-js=' + el + ']')};

var $header = $.js('header'),
    $headerSolidBlock = $.js('header-solid-block'),
    $title = $.js('title'),
    $subtitle = $.js('subtitle'),
    $articleNumber = $.js('article-number'),
    $articleParagraph = $.js('article-paragraph'),
    $visual = $.js('visual'),
    $visualInner = $.js('visual-inner');

Another thing we should set up before continuing to code the timeline are custom easings if there are any. Principle’s default easing curve is used in iOS and OSX and is not a standard/default CSS or GSAP’s ease. To convert the default Principle’s ease, we have to include an extension for TweenMax — GSAP’s Custom ease plugin. To create the easing curve and to understand more how it works, you can use GSAP’s ease visualizer.

Our ease should look something like this.

Code example:

JS

CustomEase.create("principleDefault", "M0,0 C0.25,0.1 0.25,1 1,1");

Now, when we have all the prerequisites for our timeline, we can declare it.

Code example:

Please note that in our live codepen example we have some additional options and callbacks defined inside the timeline object, but that is only for mockup purposes. It is not mandatory for our timeline to be declared and to work.

JS

var stagingTimeline = new TimelineMax();

Now when we have our timeline, we can start adding tweens to it and build our animation. By clicking on each element on the left artboard, we can see the starting values of an animated element’s properties, and by clicking on the same element on the right artboard, we can read the ending values of element’s animated properties.

(Principle’s artboards with start and end states of our screen)

In Principle’s timeline panel, we can see animated elements and animated properties on the left side, and graphical timeline on the right side.

(Principle’s timeline panel)

We start with the element that comes on stage first — in our case it’s a solid block UI element which has a starting point at the very beginning of the timeline at 0 seconds. To read the duration and the exact time value, we can click and hold the tween handle.

(Click and hold the tween hande to display accurate timeline values)

It is not very practical and, in my opinion, it’s a feature that Principle’s developers should improve a bit more, but it works and gives good results. When we have read the duration, we can add the tween to our timeline.

Code example:

We use TweenMax’s .fromTo() method because it is very practical and we do not need to set the starting values of animated properties via CSS.

JS


var stagingTimeline = new TimelineMax({
  delay: 0.5, // mockup purposes only
  onStart: function() {
    $replayButton.removeClass('is-visible');
  },
  onComplete: function() {
    $replayButton.addClass('is-visible');
  }
})

We continue to add other tweens and extend our animation simply by chaining TweenMax methods inside the timeline for each animated element.

Code example:

JS


stagingTimeline
.fromTo($headerSolidBlock, 1.5, {
  x: "100%"
}, {
  x: "0%",
  ease: "principleCustom"
}, "+=0.5")
.fromTo($title, 0.93, {
  autoAlpha: 0,
  y: -20
},{
  autoAlpha: 1,
  y: 0,
  ease: "principleDefault"
}, "-=0.8") // Overlap parameter (previous tween “end value” - this tween “start value”)
.fromTo($subtitle, 0.71, {
  autoAlpha: 0,
  y: -10
},{
  autoAlpha: 1,
  y: 0,
  ease: "principleDefault"
}, "-=0.5");

Please note that each tween inside TimelineMax by default starts after the previous ends, and that is not the behaviour we have in our animation prototype. Tweens overlap, so we have to add overlaps to each tween that should start before the previous one ends. We just need to add the overlap parameter to our tween. Basically, it is the difference of the end value of the previous tween and the starting value of the next tween.

After adding all the tweens, our timeline should look something like this.

Code example:

JS


stagingTimeline
.fromTo($headerSolidBlock, 1.5, {
  x: "100%"
}, {
  x: "0%",
  ease: "principleCustom"
}, "+=0.5")
.fromTo($title, 0.93, {
  autoAlpha: 0,
  y: -20
},{
  autoAlpha: 1,
  y: 0,
  ease: "principleDefault"
}, "-=0.8")
.fromTo($subtitle, 0.71, {
  autoAlpha: 0,
  y: -10
},{
  autoAlpha: 1,
  y: 0,
  ease: "principleDefault"
}, "-=0.5")
.fromTo($articleNumber, 0.42, {
  autoAlpha: 0,
  y: -30
},{
  autoAlpha: 1,
  y: 0,
  ease: "principleDefault"
}, "-=0.4")
.fromTo($articleParagraph, 0.49, {
  autoAlpha: 0,
  y: -10
},{
  autoAlpha: 1,
  y: 0,
  ease: "principleDefault"
}, "-=0.24")
.add("imageReveal", "-=0.73")
.fromTo($visual, 1.38, {
  y: "100%"
}, {
  y: "0%",
  ease: "principleDefault"
}, "imageReveal")
.fromTo($visualInner, 1.38, {
  y: "-30%"
}, {
  y: "0%",
  ease: "principleDefault"
}, "imageReveal");

Our timeline is now a very accurate representation of the prototype previously built in Principle. If we compare the Principle prototype and the animation we built with HTML, CSS and JS, we can see that the look and feel is the same. For this example, I have built a pen on codepen for presentational purposes, but the code would look very much the same on a live project that has staging animations. Also, in the pen we have a “Replay” button, so it would be easier to start the animation over again.

Final result
https://codepen.io/karlovidek/full/przdXO/

Benefits of using Principle prototypes

As we said before, Principle is very intuitive and simple to use – that’s its main advantage. You can prototype and experiment with various animations very fast, and important information you need for transferring the animation to code is available in few clicks. Everything you create with it can be reproduced in code. In Principle, you animate the same properties that you would animate with CSS or JS.

While some of the properties and values are very easy to read from Principles panels, some of them are not so easy to get (as we mentioned in the example with tween handles inside the timeline), but I am sure that developers are thinking about us other developers and will add some export features etc.

Principle enables us to iterate faster and simpler, but there are no simple export option for front-end developers. We have to do a lot of manual work, like reading out some values, but it’s still way faster than coding everything “by hand” and without a reference.

Our animation workflow helps us create great UI animations, but we constantly try new tools and methods to improve it. Feel free to share your opinion on this subject, and also share the process and tricks you use to create aesthetically pleasing, functional and interactive web animations.

For more interesting pens with buttery-smooth animations, follow me on codepen, and feel free to view and download all example source files I talk about in the blog.

Author

Karlo Videk

Senior Front-end Developer

A fun-loving front-end developer with a serious case of nomophobia. A kidult who's as good at making static things come alive as he's good at winning FIFA games on World Class difficulty. Passionately in love with UI interactions & tech, just don't tell that to his wife.

All stories by Karlo

SIGN UP FOR OUR MONTHLY NEWSLETTER

Get more digital stories directly in your inbox.
Your email is saved
Join the discussion

No Comments

Share your thoughts

Let's work together  →
Go to top
css.php