Note: dear readers from the future! at the time of writing the released meteor version is 0.3.7; as Meteor is a rapidly changing framework, it is likely this post is out of date!

UPDATE: David Greenspan posted some detailed info about the heuristics that meteor uses to update DOM nodes. The important takeaway: you can achieve animations the ‘meteor way’ if you set an id on your DOM nodes (or a name on form elements). More details below.

A common question that people have as they begin to use Meteor for developing a javascript application is how to implement animations. This isn’t surprising as the example applications don’t really use them and the docs make no mention of it. Yet for a client-side responsive JS app, animating JS changes makes a lot of sense.

In this post I’d like to discuss the animation of a simple expanding div, as seen below.

Click me!

Using CSS transitions

The HTML5 way to achieve this is using the CSS3 transition property. CSS transitions work when the class changes on an element. The browser will animate the transition of a CSS property between the old value (as specified by the first class) and the new.

1. Reactively: the Meteor way

It fits with Meteor’s reactive setup to force the class on an element to change via a variable change. For instance, with the correct CSS setup, we could do something like:

<div class="{{open}}" id="clickme">Click me!</div>
Template.foo.open = function() { if (Session.get(open)) { returnopen; }};
Template.foo.events = {‘click #clickme’: function() { 
  Session.set(open, true); 
}};

The only challenge in this technique is naming the session variable to use to store the state of the <div> [1]. However, it’s usually sensible to call it something like this._id + '-open', depending on exactly what you are doing. In the future, meteor will have ways to attach reactive variables to the “template invocation” that’s currently rendering—this will avoid using the session in ways that it’s not really intended for.

Please note that this technique only works if you set an id on your <div>. This is because it isn’t easy for meteor to tell when you’ve simply changed the class on an element—from meteor’s perspective you may have deleted the original <div> and created a totally new <div> which is identical except for the classname change. Setting an id tells meteor that, no, in fact that is the same element after all. (Similarly, you can just set the name attribute on a form element).

2. Directly: the jQuery way

The more direct, jQuery way to do it is to simply go
Template.foo.events = {‘click .somewhere: function(e) { 
  $(e.target).addClass(open); 
}};

This technique will work, however, be very careful. If for some reason the template needs to be reactively re-drawn (for instance the underlying data is updated), the class-name will be lost as the element will be re-rendered. There are techniques to try and isolate meteor’s re-rendering (for instance using Meteor.ui.chunk in a helper, the {{#each}} helper, or a using separate template). However, you are basically swimming upstream with this approach; for this reason I think doing things this way is likely to be a maintenance nightmare. Use at your own risk.

What other techniques are people using for animation?

  1. the nice thing about using a session var is that the <div> will remain open if there is a hot-code change. If this isn’t what you want, you might consider adding a reactive variable to your data object []
Tom Coleman

Co-creator of bindle.me, searching for simplicity, quality and elegance in technology, products and code.

See all Tom Coleman's posts

2 Responses to “Animations in Meteor: state of the game”

  1. Seth Hall says:

    I am new to Meteor, so I am wrapping my head around all of the ins and outs. I am using jquery to animate my initial sign-up/login page and I am thinking that is ok because no underlying data will be update, such as the case within the app itself. Am I thinking about this correctly?

    I ask because I want to have best practices with Meteor and I am just starting with web app development and programming.

    Thanks.

    • Tom Coleman says:

      Hi Seth,

      Certainly you can use jQuery to animate stuff, but since writing this post, I’m more convinced that doing so is going against the grain of doing client-side Meteor stuff.

      The issue is that if you rely on data not changing (and thus Meteor not re-rendering), you end up with a very brittle solution. You have to be very careful to make sure that it stays that way, and given the fact that it can sometimes be confusing to know when a given data change is going to make some part of your page re-render, this can be tough.

      Anyway, I know people do use jQuery animations successfully in their Meteor projects, so it’s not impossible! But personally, I always try and do it with CSS if I can.

Leave a Reply

  • Search: