Skip to content

Instantly share code, notes, and snippets.

@dclowd9901
Last active August 29, 2015 14:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dclowd9901/1e1a8cc47d5155178e2e to your computer and use it in GitHub Desktop.
Save dclowd9901/1e1a8cc47d5155178e2e to your computer and use it in GitHub Desktop.
Ember AnimatedRoute
import Ember from 'ember';
import _ from 'lodash';
export default Ember.Route.extend({
lastTransition: null,
readyToTransition: false,
transitionend: 'transitionend oTransitionEnd webkitTransitionEnd',
animationend: 'animationend',
/**
* Helper function to sequentially animate a group of items. You pass in a group
* of objects to operate on, include the delay between operations, and a function
* which will iteratively receive each item in the group.
*
* Your callback function receives two arguments: callback(item, done). `item`
* is the item currently being iterated over. `done` is an optional param
* wherein if you include its usage on your function, `sequentialAnimate` will
* await your call to it before iterating its counter toward its completion point.
*
* In other words, if you include `done` in your callback's available params
* you need to call it in order for `sequentialAnimation` to ever fulfill its
* promise.
*
* @param {Array/Collection} group Items to operate on
* @param {Number} delay Time delay of operations in milliseconds
* @param {Function} func Iterative function
*/
sequentialAnimate: _.partial(_timingOp, _, _, _, function(time, count) {
return time*count;
}),
randomAnimate: _.partial(_timingOp, _, _, _, function(time) {
return time*Math.random();
}),
actions: {
willTransition: function(transition) {
if (this.get('readyToTransition') === false) {
transition.abort();
if (this.get('lastTransition') === null) {
this.send('animationKickoff', transition);
}
this.set('lastTransition', transition);
}
},
didTransition: function() {
this.set('readyToTransition', false);
this.set('lastTransition', null);
},
/**
* Override this function to start your animation process. When complete,
* send the action 'okTransitionNow'. If not overridden, this function
* will simply call the next route to be completed.
*/
animationKickoff: function(transition) {
this.send('okTransitionNow');
},
okTransitionNow: function() {
this.set('readyToTransition', true);
this.get('lastTransition').retry();
}
}
});
function _timingOp(group, time, func, timingFunc) {
var count = 0,
doneCount = 0,
total = _.size(group);
return new Ember.RSVP.Promise(function(res) {
_.each(group, function(item) {
count++;
setTimeout(function() {
if (func.length === 1) { // If their function only has one arg, call `done` for them
func.apply(this, [item]);
done();
} else { // otherwise, it's an async thing, and they need to call it themselves
func.apply(this, [item, done]);
}
function done() {
doneCount++;
if (doneCount === (total-1)) {
res();
}
}
}.bind(this), timingFunc(time, count));
}.bind(this));
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment