Chapter 7. A Comparison of Web Animation Technologies

So far we’ve only really covered CSS for animation. From this point forward we’re going to move primarily into JavaScript—but before we do, I think it’s important to weigh all of the options you have for working in animation on the web, and the pros and cons of each, so that you know what you’re using and can pick the best tool for the job.

At the end of the chapter we’ll discuss the same tools in terms of their integration with React, primarily because they work a little differently in a React environment due to the virtual DOM.

There’s no possible way to cover every single animation library, so I will stick with those that I’ve used or that interest me a lot. Please keep in mind that these recommendations are based on my own experiences; you may have a different experience or opinion, and that’s OK.

Native Animation

Before we talk about libraries, let’s go over some native implementations. Most libraries use native animation technologies under the hood, so the more that you know about them, the better you’ll be able to understand what’s happening when the animation is abstracted.

CSS/Sass/SCSS

The reason we go over CSS so much in the beginning is because it can tend to be the Occam’s razor of web animation technologies—all things being equal, the simplest solution is sometimes the best, especially if you need to get something up and running quickly. CSS animations make it possible to transition between different states using a set of keyframes.

Pros:

  • You don’t need an external library.
  • The performance is beautiful. Preprocessors (like Sass and LESS) allow you to produce staggering effects with nth:child pseudoclasses in functions. Variables also allow for things like easing functions that you’d like to remain consistent.
  • You can listen for onAnimationEnd and some other animation hooks with native JavaScript.
  • Motion along a path is coming down the pipeline; this is very powerful for realistic motion, which has become important because of the deprecation of SMIL.

Cons:

  • The Bézier easings can be a bit limiting. Due to having a Bézier with only two handles, you can’t produce some complex physics effects, like bounces or elastic vibrations, that are pretty nice for realistic motion (but not necessary that often).
  • If you go beyond three sequences, I suggest moving to JavaScript. Sequencing in CSS becomes complex with delays and you end up having to do a lot of recalculation if you adjust the timing.You can hook into the native JavaScript events I mentioned earlier to work around this, but then you’re switching contexts between languages, which isn’t ideal either. Long, complex, sequential animations are easier to write and read in JavaScript.
  • The support for motion along a path isn’t quite there yet. You can vote on support for Firefox. Voting for support in Safari, as far as I can gather, is a little more individual. I registered to fill out a bug report and requested a motion path module in CSS as a feature.
  • CSS + SVG animation has some strange quirkiness in behavior. One example is that in Safari browsers, opacity and transforms combined can fail or have strange effects. Another is that the spec’s definition of transformation origin, when applied sequentially, can appear in a nonintuitive fashion. It’s the way the spec is written. Hopefully SVG2 will help out with this, but for now, CSS and SVG on mobile sometimes requires strange hacks to get right. This goes as well for any library that uses CSS under the hood, unless it’s done a lot of work, like GSAP has, to correct it.
  • When you write a CSS animation, you declare keyframes and then use the animation on the element itself. This means that you’re maintaining the code it takes to run the animation in two places. This can be good because you can reuse an animation, but mostly, it means legibility is compromised as you have to update things in two places.

requestAnimationFrame()

requestAnimationFrame() (rAF for short) is a native method  available on the window object in JavaScript. It’s really wonderful because under the hood, it figures out what the appropriate frame rate is for your animation in whatever environment you’re in, and only pushes it to that level. For instance, when you’re on mobile, it won’t use as high a frame rate as on desktop.  It also stops running when a tab is inactive, to keep from using resources unnecessarily. For this reason, requestAnimationFrame() is a really performant way of animating, and most of the libraries we’ll cover use it internally.

requestAnimationFrame() works in a similar fashion to recursion; before it draws the next frame in a sequence, it executes the logic, and then calls itself again to keep going. That might sound a little complex, but what it really means is that you have a series of commands that are constantly running, so it will interpolate how the intermediary steps are rendered for you very nicely.

There’s more information about requestAnimationFrame() in Chapter 15, so if you’re interested in learning more, flip ahead.

Canvas

Despite the fact that canvas is raster-based and SVG is vector-based, you can still work with SVGs in canvas. Because it is raster-based, though, the SVGs won’t look as crisp as they normally do without a little bit of extra work:

var canvas = document.querySelector('canvas'),
       ctx = canvas.getContext('2d')
       pixelRatio = window.devicePixelRatio,
       w = canvas.width,
       h = canvas.height;

canvas.width = w * pixelRatio
canvas.height = h * pixelRatio

ctx.arc (
  canvas.width / 2,
  canvas.height / 2,
  canvas.width / 2,
  0,
  Math.PI * 2
)
ctx.fill();
canvas.style.width = w + 'px';

It doesn’t take much code, but if you’re used to SVG being resolution-independent, this can be a small gotcha. There’s a great video on egghead that breaks this down.

I don’t work with SVGs in this environment much, but I’ve seen Tiffany Rayside and Ana Tudor do some great stuff on CodePen with it. It’s worth exploring their profiles.

Web Animations API

The Web Animations API is a common language for browsers and developers to describe animations on DOM elements, in native JavaScript.  This allows you to create more complex sequential animations without loading any external scripts (or it will, anyway, when support climbs—for now, you’ll probably need a polyfill). This API was created to distill all of the great libraries and work that people were already making with JavaScript. The Web Animations API is part of a movement to align the performance of CSS animations and the flexibility of sequencing in JavaScript under one roof, natively.

Pros:

  • Sequencing is easy and super legible. Dan Wilson has a great example that compares CSS keyframes and the Web Animations API.
  • Performance seems to be really great at this point. It’s always a good idea to run your own performance tests, though.

Cons:

  • At the time of publishing, the support was not great. There are good polyfills for it, but it’s still changing, so until the spec is closer to final I would be cautious about running it in a production environment. This stands to be the future of web animation, though, so it might be worth at least playing around with in the meantime.
  • There are still a lot of things about the timeline in  GSAP that are more powerful. The important ones for me are the cross-browser stability for SVG and the ability to animate large swaths of sequences in a line of code; you might not care about these things, though.

External Libraries

GreenSock (GSAP)

GreenSock is currently the most sophisticated animation library on the web, and I favor working with it. Please understand that this bias comes from working, playing around with, and bumping my head badly on a lot of different animation tooling, so when I give my strong endorsement, it’s through blood, sweat, and tears. I especially like it for SVG. The GreenSock Animation API has almost too many cool benefits to list here without missing something, but they have extensive docs and forums you can explore.

Pros:

  • It’s extraordinarily performant for something that’s not native—as in, performs as well. Which is a big deal.
  • There are still a lot of things about the GSAP timeline that are more powerful than current implementations of the Web Animations API: for me, the important ones are the cross-browser stability in regards to SVG and the ability to animate long sequences in a line of code.
  • GreenSock has a ton of other plug-ins if you want to do fancy things like animate text, morph SVGs with an uneven number of points, etc.
  • Motion along a path with GreenSock’s BezierPlugin has the longest tail of support available.
  • It solves SVG cross-browser woes, as mentioned previously. Thank goodness for this one. Especially for mobile.
  • GreenSock’s Ease Visualizer offers nice, realistic eases. It even allows you to create custom eases from an SVG path.
  • Since you can tween any two integers, you can do cool stuff like animate SVG filters for some awesome effects. The sky’s the limit on what you can animate. More on this in Chapter 15.

Cons:

  • You have to pay for licensing for use of the plug-ins. But there are some CodePen-safe versions that you can play with before you buy.
  • When you’re managing external libraries, you have to watch which versions you are using in production; because new versions come out regularly, upgrading involves testing (this is probably true of any library, ever).

Mo.js

Mo.js is a library by an awesome fellow, Oleg Solomka, who goes by LegoMushroom. He’s an extremely talented animator, and has already made some awesome demos for this library that have me really excited. The library is still in beta, but it’s getting very close to being released now. See Chapter 13 for more details on how to use it.

Pros:

  • There are things like shapes, bursts, and swirls that are really easy to work with and spin things up for you—so you don’t need to be the world’s best or most creative illustrator to get something nice going.
  • Mo.js offers some of the best and most beautiful tooling on the web, including players, timelines, and custom path creators. This in and of itself is one of the most compelling reasons to use it.
  • There are a couple of different ways to animate—one is an object, one is plotting a change over the course of an ease—so you can decide which way you feel more comfortable.

Cons:

  • It doesn’t yet offer the ability to use an SVG as a parent for the custom shapes (I believe LegoMushroom is working on this), so working with coordinate systems and scaling for responsive development is less intuitive and harder to make work on mobile. This is a fairly advanced technique, though, so you might not need it.
  • It doesn’t correct cross-browser behavior like GreenSock does yet, which means you might need to write hacks, like you do with CSS. LegoMushroom has mentioned he’s also working on this.

Bodymovin’

Bodymovin’ is meant for building animations in Adobe After Effects that you can easily export to SVG and JavaScript. Some of the demos are really impressive. I don’t work with it because I really like building things from scratch with code (so this defeats the purpose for me), but if you’re more of a designer than a developer, this tool would probably be really great for you. The only con I really see to that part is that if you change it later, you’d have to re-export it, so it might be a weird workflow. Also, outputted code is usually kind of gross, but I haven’t seen that affect the performance too much, so it’s probably fine.

Not Suggested

SMIL

SMIL (Synchronized Multimedia Integration Language) is the native SVG animation specification: it allows you to move, morph, and even interact with SVGs directly within the SVG DOM. There are a ton of pros and cons to working with SMIL, but the biggest one will lead me to omit it entirely: it’s losing support. I wrote a post on how to transfer over to better-supported techniques to get you going, though.

Velocity.js

Velocity offers a lot of the sequencing that GreenSock does, but without a lot of the bells and whistles. I no longer really use Velocity due to the cons listed here. Velocity’s syntax looks a bit like jQuery, so if you’ve already been using jQuery, the familiarity might be a big boon for you.

Pros:

  • Chaining a lot of animations is much easier than with something like CSS.
  • There are many out-of-the-box easings, and spring physics is available. You can also use step-easing to pass an array.
  • The documentation is comprehensive, so it’s easy to learn and get up and going.

Cons:

  • The performance isn’t great. Despite some claims to the contrary, when I ran my own tests I found that it didn’t really hold up. I suggest you run your own, though, as the web is always moving and this chapter is frozen in time.
  • GSAP has more to offer, for performance and cross-browser stability without more weight. jQuery used to lose performance tests, but that might have changed since their rAF adoption; Velocity isn’t bad by any means, but it loses out in comparison.

Snap.svg

A lot of people think of Snap as an animation library, but it’s really not. I was going to run performance benchmarks on Snap, but even Dmitri Baranovskiy (the incredibly smart and talented author of this library, and its predecessor, Rafael) says on the SVG Immersion Podcast that it’s not the correct tool for this. In a personal message to me, he said, “Just a note: Snap is not an animation library and I always suggest to use it with GSAP when you need a serious animation.”

That said, jQuery is not great with SVG, though it does now support class operations. If you need to do a lot of DOM manipulation with SVG, Snap is a recommended tool.

There is a library called SnapFoo that extends Snap’s realm to animation. I haven’t played with it myself yet, but it looks pretty cool.

React-Specific Workflows

Before we talk about React, let’s cover why we have to treat animations in React differently. The main difference lies in the Document Object Model (DOM), which is how we create a structured document with objects, and is mostly expressed as a tree.

React has a virtual DOM, which is an abstraction of this structure. React does this for a number of reasons, the most compelling of which to me is the ability to figure out what’s changed and update only the pieces it needs to. This abstraction comes at a price, of course, and some of the old tricks that you’re used working with will give you trouble in a React environment. jQuery, for instance, will not play nice with React, as its primary function is to interact with and manipulate the browser’s native DOM. But I’ve even seen some strange CSS race conditions. Here are some of my recommendations for nice animations in a React workflow.

React-Motion

React-Motion by Cheng Lou is considered to be the best way to animate in React, and the community has pretty much adopted it over the old ReactCSSTransitionGroup. I like React-Motion a lot, but there are some keys to working with it that will have you banging your head for a little while if you don’t get them.

React-Motion is pretty similar to game-based animation, where you give an element mass and physics and send it on its way, and it gets there when it gets there—you aren’t specifying an amount of time like you do with CSS or any other traditional web-based sequential motion. The motion can look realistic, which can be beautiful. But the hard part is that if you have two different things that have to fire at the same time and get there at the same time, it can be tough to line them up exactly.

Recently, Cheng Lou added in onRest, which allows for this kind of callback workflow. It hasn’t advanced much, though, as it’s counter to the original premise of the tool. It’s still not easy to write a loop (without writing an infinite loop, which is bad for a whole slew of reasons). You might never come across this use case, but I did once.

Pros:

  • The animation can look really beautiful and realistic, and the spring options are nice.
  • The staggering effect is pretty unique—staggering is available in most JS libraries (like GSAP and Velocity) but the spring is based directly off of the last element’s movement, not duplicating the last one, so there are some nice motion possibilities.
  • This is probably the animation tool that plays with React the best.

Cons:

  • It’s not super plug-and-play like some other libraries or native, which means you end up writing quite a bit more code. Some people like this about it; some people don’t. It’s not kind to beginners, though.
  • Because of the complex nature of the code, the sequencing is not as straightforward or legible as with some of the alternatives.
  • onRest still doesn’t work for staggering parameters.

GSAP in React

GreenSock has so much to offer that it’s still worth using in a React environment. It takes a bit more finessing than usual, and some things that should work (and do with the DOM) don’t in React. That said, I’ve gotten it working a few different ways:

  • Hook into the native React component lifecycle methods.
  • Hook it up to something you call for interaction.For interaction, I create a function, and then hook it into an event like onClick.
  • There’s a nice post by Chang Wang about how to hook it into ReactTransitionGroup, which is a pretty cool way of doing it.
  • You can use a library like React-Gsap-Enhancer. React-Gsap-Enhancer seems like a good tool for when you’re doing very complicated sequencing. For something very simple, it’s probably overkill, and you could just use GSAP straight out with lifecycle methods.

Canvas in React

Canvas itself works beautifully in React. You can choose to bypass the DOM entirely and attach a single node, in which you can create all of your animations. It has the same benefits and limitations we discussed previously (see “Canvas”). You can also break a canvas into React components, but the implementation details can get much more complicated due to the virtual DOM.

There are a couple of good libraries for working with canvas in React. React-Canvas was developed by the Flipboard team because they wanted 60 fps animation with the DOM. The repo hasn’t been updated in a while, though, and it really does focus on only UI elements, so any other kind of animation will take some work.

React Konva is an interesting, very declarative way of working with canvas and React. It creates beautiful shapes incredibly easily, but the animation performance is a little lacking. The developer acknowledges this right in the docs, so it’s possible that if you’re willing to submit a pull request (PR) you could improve it and help him work on it.

CSS in React

CSS has had a resurgence lately because it’s likely the easiest way to create animations in React. I like working with CSS animations for little things like UI/UX interactions, but have seen them behave a little strangely if you try to chain things using delays. Other than that, they’re pretty great, especially for small UI adjustments.

Covering Ground

Unfortunately, it would be impossible to go into all of these wonderful tools in great depth—this book would be 10 times as long! We’ll focus primarily on the GreenSock Animation API, due to its power and multitude of uses. We’ll also cover mo.js, React-Motion, and requestAnimationFrame() so you know how to work with JavaScript at a bare-metal level.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.113.193