Animated Route with full async support

I’ve hosted it at this gist: https://gist.github.com/dclowd9901/1e1a8cc47d5155178e2e

You extend a new route from it. That route then gets a new action, animationKickoff, as well as a few methods for free such as sequentialAnimate and randomAnimate, wherein you can provide a list of things you want to act on, act on them, and then call a passed done method once they’ve completed (or not – the done function is only for async, similar to Jasmine or Mocha’s done params).

Here’s an example:

import AnimatedRoute from './animated-route';
import $ from 'jquery';

export default AnimatedRoute.extend({
  model: function() {
    return this.store.find('posting', { truncation: 1, per_page: 10 });
  },

  actions: {
    animationKickoff: function() {
      // Out of postings entirely
      var $postings = $('.post-single');

      this.sequentialAnimate($postings, 70, function(post, done) {
        $(post).addClass('leave');
        $(post).on(this.transitionend, done);
      }.bind(this))
      .then(function() {
        this.send('okTransitionNow');
      }.bind(this));
    }
  }
});

When I go to navigate away from this route, if I’ve overridden animateKickoff, I now have control over a final action that I can perform asynchronously before I move to the next location.

The helper methods sequentialAnimate and randomAnimate provide a way to do common “out” animations, where you might want to sequentially animate, say, a group of rows of information out of a view in an aesthetically pleasing way. You only have to pass the group of things you want to operate on, the time involved (in sequential, it’s a delay, and in random, it’s the full amount of time you want it to take), and a function of what to do on each iteration.

The methods receive both each item being iterated upon, as well as a done method, which should be called by the consumer whenever their task has finished. In the example above, you can see it being called whenever that particular element is done transitioning. Each time done is called, an internal counter determines whether or not you’ve iterated through all items. Once all have been iterated through, it fulfills its promise, and then you can kick off your next event, which will typically be to send the action okTransitionNow, to complete the transition process.

Here’s what the finished product looks like:

https://dl.dropboxusercontent.com/u/7236372/animated_route.gif