JCAnim – a jQuery & CSS3 animation engine

Sometime recently I wanted to make some sweet-ass parallax stuff. Fun times would be had, but what a lot of effort it was going to be.

There were several great solutions out there, and I eventually decided upon jparallax as being the most complete. However, that still didn't allow me the flexibility I wanted - I needed to be able to do more than just move elements, I wanted to stretch parts of my parallax to achieve faux-sideon perspective. And then I started thinking about other things you could do, and decided the best way to approach such an engine would be to allow modification to any css property and decide what effects were workable later.

The other thing I generally have a problem with in JavaScript animation in general is 'the stutter'. You don't get it constantly, and on modern browsers / faster machines not at all, but for those of us on laptops and phones the stutter in our animation ruins the fuildity of the experience we're trying to create. CSS transitions are there and are supported by all the major browsers now (except, of course, IE (edit: IE10 does support them now)) so there's no reason not to be using them. Transitions run on the GPU in most cases, freeing up CPU resources being used to control the animation in JavaScript for other purposes and smoothing out animation by using framesyncing and other techniques only available on hardware.

Provided keyframe positions were known ahead of time or it didn't matter if there was a slight lag to the animation (indeed in many cases this can be appealing), there didn't seem to be any reason one couldn't leverage CSS transitions and the GPU to add fluidity to JavaScript animations updated at a low sampling rate. So that's exactly what I did with JCAnim and the parallax effect I implemented with it. There is a demo linked on the project page showing it in action - I've yet to implement a fallback animation engine for older browsers, so IE10+ please (;

Features

I will be back to document this later, but for now I hope the flexibility of JCAnim's design is evident in its source code. The engine allows extension via a fairly comprehensive API:

  • Addition of custom input and output handlers, allowing JCAnim to respond to other events I haven't thought of yet and to manipulate other CSS properties easily. The library should be future proof enough to use with any new technologies as they are implemented. Custom callbacks can also be used to determine the movement range of new CSS properties on target layer elements, allowing complete automation of new animations as with the core set.
  • Binding of multiple viewport & layer controllers to the same elements, allowing combinations of parallax effects, cumulative parallax when hovering over certain areas etc (i.e. windows within windows).
  • Flexible enough to allow parallax instances with different framerates to access the same elements.
  • Contain update methods for recalculating cached coordinates used in computations so as to allow other movement of its DOM nodes whilst operating.
  • Multiple input & output animators per layer, with separate ranges and animatable attributes

Looking under the hood: JCP-TransitionInterval

At the core of the framework is jcparallax.TransitionInterval (excuse the toplevel object naming, this was the original name of the library). This class determines browser support for both transitions and their JavaScript callbacks (it is rare, but someĀ intermediary versions do involve this), and acts accordingly when running animations. TransitionInterval objects are created independently at different framerates so that one can mix and match within the same document. They accept an asynchronous callback to run on each timer tick, a sampling rate for updating the animation when running with transition support, andĀ (eventually) a second sampling rate (typically much higher) to update at when support is unavailable.

All in all it seems to be a pretty effective way of running animations, and I hope it starts to see some wider use once I finish it off!