Liquid Fire is a toolkit for managing animated transitions in an Ember application. 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.
Transitions need to be implemented within the view layer, but deciding what kind of transition to do at any given time is a higher-level question, dependent on the relationships between different routes and models.
Therefore, we split the responsibility between three key pieces: template helpers, the transition map, and transitions.
The library provides helpers
like <LiquidOutlet />
, <LiquidIf />
,
etc, that are nearly drop-in replacements for the equivalent normal
Ember helpers. The key difference is that they don't update instantly
when bound data changes. Instead they consult your application's
transition map, and if they discover a matching transition, they give
the transition control over both the old and new content
simultaneously. Read more about Template
Helpers.
The transition map is analogous to your normal Ember router
map. It's a single place to declaratively capture rules about how
the pieces of your application relate to each other. By convention,
the transition map goes in app/transitions.js
, and it
looks something like this:
export default function () {
this.transition(
this.fromRoute('people.index'),
this.toRoute('people.detail'),
this.use('toLeft'),
this.reverse('toRight'),
);
}
LiquidFire.map
. There is an example here.
Read more about the Transition Map.
The transition map above mentions two named
transitions: toLeft
and toRight
. These are
both predefined transitions that come with the library. But you can
compose new transitions too. They look like this:
import { animate, stop } from 'liquid-fire';
export default function fade(oldView, insertNewView) {
stop(oldView);
return animate(oldView, { opacity: 0 })
.then(insertNewView)
.then(function (newView) {
return animate(newView, { opacity: [1, 0] });
});
}
(In these examples, opacity: [1, 0]
uses velocity's "force-feeding"
capability to specify [endValue, startValue]
, so the
meaning is "animate the opacity from 0 to 1".)
Transitions are implemented with a promise-based API that gives you control over all the relevant timing, including when to insert the new view into the DOM. Read more about Transitions.