— TL;DR — Here is how to structure your JS for animations - var animations = { <animation-id which goes as data-attr in HTML> : { trigger: <eventName>, targetElementSelector:<Target element that gets the css> initial: { css: { <css properties for initial setup> }, duration: <Generally 0 unless I want to apply the starting style again for reverting> }, steps: [ {<css step - same structure as initial>}, { css:<properties>, duration:<duration>} ] } } Here is a demo of multiple animations created with the above structuring - See the Pen xbMWQp by StackHive (@StackHive) on CodePen. Fork it at @ Github https://github.com/StackHive/JS-Animations-Universal-Structuring

Simple animations can be done using CSS3 Transition and Keyframes. However, chaining and queueing for complex animations are very hard without JS.

In this article, I will explore the best practises to structure the JS for complex animations.

Problem with Animations

I have tried different techniques but more often than not it ends up getting really messy. Timeouts and events create a soup of disaster!

The screaming in your head starts when you want to chain them and have multiple steps. You can’t do that with CSS alone. You can write up your own Javascript to manage the animation timeline or utilize the $.animate function to achieve something similar but that is just too much work to make a few animations!

This is where jQuery Transit comes in. Check out Transit.js at http://ricostacruz.com/jquery.transit/

Transit.js takes care of the actual animation and chaining for you but there are still a lot of things left to consider.

Setting up the element for animation To set up an animation, we need two things: Starting State- where you want the element to be on page load, and how you want it to look. Animation- How you want the element to move around, and change with time. Transit.js takes care of animating the element. So more on defining the starting state. Starting State - Using CSS For example, if we want to move the element from top to down - the Starting State is to position the element upwards and Animation is moving the element down from the starting point. When the event is triggered (in this case - when the elements comes into view), we can use Transit.js (or any other library) to apply the animation over the element. Here I have animate css class that applies the opacity to 0 and translates the element by 150px along the Y axis. .animate { opacity:0; transform:translate(0px,150px); } When the element gets scrolled into view, we apply the animation - $(element).find(".animate").transition({opacity:0,y:0},1000); This makes the element move from 150px to 0px while changing its opacity from 0 to 1 which gives a slide effect to the element in the up direction. You can check it out in the pen below - See the Pen xbMPvj by StackHive (@StackHive) on CodePen. So what is wrong here? Well, lets say your animation javascript file fails to run due to some reason - your app becomes unusable. This is a BIG risk with almost no positives at all! Starting State - Using Javascript In my opinion, it is much better to apply the starting states to the elements using Javascript as well. In order to do so, all we need to do here is - remove the CSS code for the hidden states and apply it directly using JS. So lets remove this code from CSS - .animate { opacity:0; transform:translate(0px,150px); } $(".animate").css({opacity:'0',transform:'transform:translate(0px,150px)'}); and add this in the JS Explore it in the pen below - See the Pen EaroEO by StackHive (@StackHive) on CodePen. Now, in case the Javascript doesn’t run, only the animations of the app break. Try it by adding return false; at the top of the JS. So, adding the styling for the starting point and making the elements ready for animation should be done from Javascript as well. Managing Different Types of Animations Now that we have established that initial or hidden states need to be applied with JS, lets venture into how we can prevent the code from exploding all over our face when we have multiple animations with different initial and final states. If we keep using the code from above, we’ll have to write a ton of Javascript which will get messier every second! So, lets try and organize it to create a better animation system - Check it out - See the Pen raPpPq by StackHive (@StackHive) on CodePen. So what we have here is a much more organized code to apply different starting states and running the actual animation. applyAnimation() function that defines different animation types and applies the animation if the element matches a case. applyInitialStates() function that applies the initial hidden states to the element depending on the case it matches. In total there are 6 different animations here which get bound to HTML elements via a data attribute that defines and detect the animation type for the element. The code can be further improved for sure to eliminate redundant classes etc. So again, what is wrong here? Starting style, Animation State, Duration and any other property needed to define an animation is all over the place and scattered. Lets say you want to add multiple steps or create more animations, you’ll need to change the functions again and again; which clearly isn’t a good solution! THE Paradise for JS animations After working with a lot of Javascript Animations, I realized that we can actually create a better structure that can be independent from the underlying library and create as less coupling as possible. Things that can generally vary for the animations are - Initial Setup

Trigger (when to run the animation)

CSS Steps (applied through chaining) and duration. So lets create a JS Object to bring everything about an animation together. Here is the structure that I came up with - var animations = { <animation-id which goes as data-attr in HTML> : { trigger: <eventName>, targetElementSelector:<Target element that gets the css> initial: { css: { <css properties for initial setup> }, duration: <Generally 0 unless I want to apply the starting style again for reverting> }, steps: [ {<css step - same structure as initial>}, { css:<properties>, duration:<duration>} ] } } This structure helps in keeping all information about an animation at one place which makes is really easy to manipulate and control different aspects of the animation including chaining. Once we have this Javascript object, we can simply run through it on pageload, apply the initial hidden states to all the elements for the animations and bind events to trigger the animation when needed. I am using only the Scroll Event for this demo but you can extend it easily to create other event types. Check out the demo of creating super clean and extensible Javascript Animations. I extended the above structure to add things like repeat and offset to showcase how multiple steps of the Animation can be implemented - See the Pen xbMWQp by StackHive (@StackHive) on CodePen.

Thats it!

From here on, lets keep the JS animations clean, simple and super extensible so we don’t end up spending a lot of time when we have to come back to it! :)

You can fork the app from Github at -

https://github.com/StackHive/JS-Animations-Universal-Structuring

*Tid-bits

I am working on creating a Javascript Animation plugin inside StackHive which would follow a very similar pattern and open a new chapter of JS automation for StackHive!