Skip to content

Instantly share code, notes, and snippets.

@ppcano
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ppcano/7c1a934e434546cb747e to your computer and use it in GitHub Desktop.
Save ppcano/7c1a934e434546cb747e to your computer and use it in GitHub Desktop.
Ember Route Animation
// Component which send `animationEnd` action when
// a transitionEnd event is fired in a property defined included at `animatedProperties`
var AnimatedLayoutComponent = Ember.Component.extend({
action: 'animationEnd',
animatedProperties: null,
transitionEnd: function(evt) {
var animatedProperties = this.get('animatedProperties').split(' ');
var propertyName = evt.originalEvent.propertyName;
if (animatedProperties.indexOf(propertyName) !== -1) {
this.sendAction();
}
}
});
// a dummy example
var ApplicationLayoutComponent = AnimatedLayoutComponent.extend({
classNames: ['application-layout'],
classNameBindings: ['isIndex', 'isSettings', 'isAccount', 'isAccountDetail'],
position: null,
isIndex: Em.computed.equal('position', 0),
isSettings: Em.computed.equal('position', 1),
isAccount: Em.computed.equal('position', -1),
isAccountDetail: Em.computed.equal('position', -2)
});
// transitions are defined at stylesheet at application-layout.{is-index, is-settings, is-account...}
{{#application-layout elementId="application-layout" position=position
animatedProperties="left"}}
{{render 'account/detail' controller='account/detail'}}
{{render 'account/index' controller='account/index'}}
{{render 'index' controller='index'}}
{{render 'settings' controller='settings'}}
{{/application-layout}}
import Evented from "ember-runtime/mixins/evented";
var BaseAnimatedRoute = Ember.Route.extend(Evented, {
/*
Return a promise which is resolved when the animation ends.
*/
animationPromise: function(transition, fn) {
// return a promise which will be resolved when the fromTransitionRoute
// receives the `animationEnd` event
var infos = transition.router.currentHandlerInfos;
var lastRouteName = infos[infos.length-1].name;
var route = this.container.lookup('route:' + lastRouteName);
return new Ember.RSVP.Promise(function(resolve, reject){
route.one('animationEnd', function() {
resolve();
});
fn();
});
},
renderTemplate: function() {
//do nothing
// all my templates are rendered at this time to make smooth animations
},
actions: {
animationEnd: function() {
// when the animationEnd action sent,
// `animationEnd` event is fired whose setup listener will resolve the animation promise
// The action is sent from the fromTransitionRoute because
// when the animation has finished, the transition is still not completed
// and the route is still at the fromTransitionRoute
this.trigger('animationEnd');
}
}
});
import EventDispatcher from 'ember-views/system/event_dispatcher';
export default {
name: 'event-dispatcher',
initialize: function(container, application) {
var CustomEventDispatcher = EventDispatcher.extend({
events: {
....
.....
transitionend: 'transitionEnd'
},
canDispatchToEventManager: false
});
container.register('event_dispatcher:main', CustomEventDispatcher);
}
};
var AccountIndexRoute = BaseRoute.extend({
animation: function(transition) {
var applicationController = this.controllerFor('application');
return this.animationPromise(transition, function() {
// whenevet position change, a new CSS class is set to the
applicationController.set('position', -1);
});
}
});
@ppcano
Copy link
Author

ppcano commented Sep 8, 2014

You must also extend your eventDispatcher to listen transitionEnd events. This could be avoided if the animation is done with JS and listen the animation end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment