Ember.js Router: How to animate state transitions

11,052

Solution 1

Billy's Billing just released an Ember module that supports animated transitions.

Solution 2

I'll expand on Lesyk's answer. If you need to apply it to multiple views in a DRY way, you can create a customization class like this:

App.CrossfadeView = {
  didInsertElement: function(){
    //called on creation
    this.$().hide().fadeIn(400);
  },
  willDestroyElement: function(){
    //called on destruction
    this.$().slideDown(250);
  }
};

And then in your code you apply it on your various view classes. As Ember depends on jQuery you can use pretty much any jQuery animation.

App.IndexView = Ember.View.extend(App.CrossfadeView);
App.PostView = Ember.View.extend(App.CrossfadeView);

Solution 3

I know this is pretty old, but the best solution for this context-specific animation today is probably ember liquid fire.

It allows you to do things like this in a transition file:

export default function(){
  this.transition(
    this.fromRoute('people.index'),
    this.toRoute('people.detail'),
    this.use('toLeft'),
    this.reverse('toRight')
  );
};

Solution 4

Ran into this same requirement on my app. Tried Ember Animated Outlet, but didn't give the granularity I needed (element specific animations).

The solution that worked for me was as follows --

Change linkTo to be an action

{{#linkTo "todos"}}<button>Todos</button>{{/linkTo}}

Becomes...

<a href="#/todos" {{action "goToTodos"}}><button>Todos</button></a>

Create Method for goToTodos in current controller

App.IndexController = Ember.Controller.extend({
    goToTodos: function(){

        // Get Current 'this' (for lack of a better solution, as it's late)
            var holdThis = this;

        // Do Element Specific Animation Here
            $('#something').hide(500, function(){

                // Transition to New Template
                    holdThis.transitionToRoute('todos');

            });

    }
});

Finally -- To animate in elements on the Todos Template, use didInsertElement on the view

App.TodosView = Ember.View.extend({
    didInsertElement: function(){

        // Hide Everything
            this.$().hide();

        // Do Element Specific Animations Here
            $('#something_else').fadeIn(500);

    }
});

So far, this is the most elegant solution I've found for element specific animations on transition. If there is anything better, would love to hear!

Solution 5

I've found another drop-in solution that implements animations in Views: ember-animate

Example:

App.ExampleView = Ember.View.extend({

    willAnimateIn : function () {
        this.$().css("opacity", 0);
    },

    animateIn : function (done) {
        this.$().fadeTo(500, 1, done);
    },

    animateOut : function (done) {
        this.$().fadeTo(500, 0, done);
    }
}

Demo: author's personal website

Share:
11,052

Related videos on Youtube

david8401
Author by

david8401

Updated on September 14, 2022

Comments

  • david8401
    david8401 over 1 year

    Has somebody found a good way to animate state transitions?

    The router immediately removes the view from the DOM. The problem with that is that I can't defer that until the end of the animation. Note: I'm using v1.0.0-pre.4.

    • MilkyWayJoe
      MilkyWayJoe over 11 years
      Have you considered adding the transition classes to your view through Ember.View#willDestroyElement?
    • max
      max over 7 years
      fwiw, my answer below about ember liquid fire is considered the best practice today for this type of situation :)
  • david8401
    david8401 about 11 years
    I do know those hooks, however none of those helps me get the job done. The problem is that didInsertElement and willDestroyElement are specific to that very view. To make a transition smooth, I'd need to know whether the other view, the one that the router is transitioning to, is ready, then do the animation/transition and then detroy the previous view. So in other words I'm looking for a more async-behaviour.
  • graup
    graup over 10 years
    The end of the first code snippet is wrong, brackets don't match up :) Maybe you could edit that.
  • graup
    graup over 10 years
    The willDestroyElement animation doesn't work for me (1.0-rc4). It seems that the view is already gone before the animation renders. Do you have a working example?
  • Bojan Markovic
    Bojan Markovic over 10 years
    Here is an (unfinished) example using that. The animation works tho: jsbin.com/imahog/21/edit Do note that I'm using rc6 tho, and you were right abut the brackets (fixed it above).
  • graup
    graup over 10 years
    Thanks. fadeIn works indeed, but the slideDown in willDestroyElement is not visible, at least for me.
  • mpowered
    mpowered over 10 years
    You're not talking about state transitions if you're animating individual elements. ember-animated-OUTLET is for outlets, which is purportedly different than the OP's use case. Furthermore, actions break the URL support of the app :-(
  • Giacomo1968
    Giacomo1968 over 8 years
    Given how EmberJS has truly fluctuated like crazy during upgrades, any new info on an old post should be welcome. So thank you!
  • Benjamin
    Benjamin over 7 years
    I am just starting with ember. The linked page says: "Things to be aware of: [...] Animations are not executed when transitioning to the same route with a different model. This is due to the way Ember reuses the same DOM element, and will likely not be fixed until animation support lands in Ember core in 1.1." So my question - is this answer up to date? What is the best option with emper 2.10 to animate routes?