Animating Ember.JS

with the help of liquid-fire

By Tom Coquereau / @thaume

Summary

Which animation library for Ember.js ?

  1. Prerequisites
  2. Where we are coming from
  3. Where we're heading to
  4. Demo
  5. Questions

Prerequisites

The Ember {{outlet}}

Placeholder where the appropriate template is injected by the Router based on the current URL.


Application template

{{outlet}}

The Ember router

Definition of routes and resources

Route transition (eg: /posts/edit -> /posts/1/show)

Model transition (eg: /posts/1/show -> /posts/2/show)

Where we are coming from

jQuery animations

  • jQuery animations are 'hard-coded' for certain DOM elements
  • Hard to reuse
  • Hard to refactor

Where we're heading to

Ember-animated-outlet

The ember-animated-outlet {{outlet}}


Application template

{{animated-outlet name='main'}}

The ember-animated-outlet link-to


About template

{{#link-to-animated 'posts.show' post animations='main:slideLeft'}}Introduction{{/link-to-animated}}

The ember-animated-outlet 'transitionTo' helper


App.ApplicationRoute = Ember.Route.extend({
  showPost: function(post) {
    this.transitionToAnimated('posts.show', { main: 'slideLeft' }, post);
  }
});

Wrapping up

  • Good starting point for animations in Ember.js
  • CSS animations => limited control
  • Need to manually create an empty view for each animation
  • Impossible to define transitions between models (eg: /posts/1/show -> /posts/2/show)

Liquid-fire

What is Liquid-fire?

Like Ember itself, our goal is to cultivate shared abstractions so we're free to focus on bigger and better ideas. Good defaults. Convention over configuration. Composable pieces all the way down.

Separation of concerns

The transitions maps are defined in a transitions.js file at the root of /app

this.transition(
  this.fromRoute('projects.new'),
  this.use('toLeft')
);

The liquid-fire {{outlet}}


Application template

{{liquid-outlet}}

Animating between models


{{#liquid-with model}}

  

{{title}}


{{content}}

{{/liquid-with}}

Animating a value update


{{liquid-bind hours}}:{{liquid-bind minutes}}:{{liquid-bind seconds}}

this.transition(
  this.childOf('#liquid-bind-demo'),
  this.use('toUp')
);

Animating an 'if' condition


{{view 'select' value=vehicle content=vehicles}} {{#liquid-if isBike class='vehicles'}} {{else}} {{input type='text' value=license}} {{view 'select' value=state content=states}} {{/liquid-if}}

this.transition(
  this.fromNonEmptyModel(),
  this.hasClass('vehicles'),
  this.toModel(true),
  this.use('crossFade', {duration: 1000}),
  this.reverse('toLeft', {duration: 1000})
);

Powerful custom transitions

The custom transitions are defined in the ./app/transitions directory

import { isAnimating, finish, timeSpent, animate, stop } from "vendor/liquid-fire";

export default function fade(oldView, insertNewView, opts) {
  ...
  return AnimationPromise;
}

Wrapping up

  • The results of lots of talks around animations in Ember.js
  • JS animations => full control + speed
  • Easy and powerful transitions between models
  • Animation logic is kept away from the presentation layer

DEMO

Conclusion

Clean separation of concerns between the presentation and animations

Powerful default and custom animations map

Questions ?