Liquid Fire is a tool for managing transitions and animations in your Ember applications. It's a popular addon for Ember and since I've never used it before I thought it was be interesting to give it a shot and see how it goes.

Liquid Fire (LF) was created by Edward Faulkner who recently spoke at EmberConf 2015. He goes into a lot more detail about LF and the design behind it so check out the video if you can.

Another resource you can check out is the LF documentation. It's interactive so you can really get an idea on how it works. For this tutorial I'll just be trying out a few animations and show how you get started.

Installing

Liquid Fire is available for any version of Ember. Since Ember 1.11 is not out yet as of this writing we'll go ahead and install the 0.17.0 version.

$ npm install --save-dev liquid-fire@^0.17.0

The master version of the liquid-fire addon breaks older versions of Ember prior to 1.11, so make sure not to accidently install it if you're running 1.10 or earlier. Use 0.17.0 and that should work fine.

Transition Map

There is a few key things you need to do before you can starting adding transitions to your application. One of the most important things is the transition map. This is analogous to your normal Ember router map.

To begin create a transitions.js file in your app folder. For the purpose of this demo we'll just create a simple transition using toRight and toLeft.

// app/transitions.js

export default function(){
  this.transition(
    this.fromRoute('tut1'),
    this.toRoute('tut2'),
    this.use('toRight'),
    this.reverse('toLeft')
  );
}

This file defines what type of route transitions you want to do. You'll notice that it uses toRight and toLeft. These are a part of the predefined transitions. You also have available:

  • toLeft
  • toRight
  • toUp
  • toDown
  • crossFade
  • fade

Most of these are self-explanatory. There is a process of adding your own transitions. Check out the defining transition animations section for more information.

Transition Helpers

LF supports five template helpers.

  • {{#liquid-outlet}} Transitions between routes.
  • {{#liquid-with}} Transitions between models or contexts within a single route.
  • {{#liquid-bind}} Updates to simple bound values.
  • {{#liquid-if}} Switching between true and false branches in an #if statement.
  • {{#liquid-spacer}} Provides a smoothly growing/shrinking container that animates whenever its contained DOM mutates.

For now we just care about liquid-outlet. It can completely replace your normal {{outlet}} and you'll need to use it so the animations will be displayed.

Simple Transition Demo

Let's create a simple transition from one route to the next and have it be animated using toLeft and toRight. We'll assume you already created your project and installed LF.

Go ahead and create the app/transitions.js file. It should look exactly like the one created earlier in this post. Next we'll create a few templates.

$ ember g template tut1
$ emger g template tut2

Now let's edit the application.hbs file and add in the liquid-outlet and remove the normal outlet.

// app/templates/application.hbs
<h2 id="title">Welcome to Ember.js</h2>
{{liquid-outlet}}

Of course we'll need to add the routes to the router.js file

// app/router.js

  this.resource('tut1', function() {});
  this.resource('tut2', function() {});

Finally we'll add a simple link-to helper to tut1 and tut2 so it can easily transition between routes.

// app/templates/tut1.hbs

This is tut1
<br>
{{#link-to 'tut2'}}Tutorial 2{{/link-to}}

Now we need to update tut2 so it can go back.

This is tut2
<br>
{{#link-to 'tut1'}}Go back!{{/link-to}}

That should be it the transition animation should work. If we did everything correctly it should look like this.

Let's say you change the animation to Fade in the transitions.js file.

Here is what toUp and toDown looks like.

As you can see it's really simple to add these animation transitions to your application.

Animation Primitives

I'm not going to get into too much detail here, however the library exports these animation primitives.

  • animate(view, props, opts, label)
  • stop(view)
  • isAnimating(view, label)
  • timeSpent(view, label)
  • timeRemaining(view, label)
  • finish(view, label)

A demo featured on the LF site showed this code.

import { isAnimating, finish, timeSpent, animate, stop } from "liquid-fire";
export default function fade(oldView, insertNewView, opts) {
  var firstStep,
      outOpts = opts;

  if (isAnimating(oldView, 'fade-out')) {
    // if the old view is already fading out, let it finish.
    firstStep = finish(oldView, 'fade-out');
  } else {
    if (isAnimating(oldView, 'fade-in')) {
      // if the old view is partially faded in, scale its fade-out
      // duration appropriately.
      outOpts = { duration: timeSpent(oldView, 'fade-in') };
    }
    stop(oldView);
    firstStep = animate(oldView, {opacity: 0}, outOpts, 'fade-out');
  }

  return firstStep.then(insertNewView).then(function(newView){
    return animate(newView, {opacity: [1, 0]}, opts, 'fade-in');
  });
}

Here's what it looks like.

Future

I hope this gives you an idea how the addon works. I highly suggest reading up on the documentation if you need more information!

Have you used Liquid Fire? Leave a comment below and let me know how it went.

Image Credit Deviant Art

Adding Animations With Liquid Fire And Ember