How to animate views?

How do I animate views? i.e page transitions. If I want to slide up a page while clicking a url

Hey @rehat, can you link to something that shows the animation you’re looking for? Often you can use 3rd party animation libraries and integrate them with CanJS to get this sort of effect.

Do you want it working with routing? Are you using pushstate or hashchange routing?

@justinbmeyer - I’m looking for basic animations when the user clicks on a route; slide up, slide down, etc. I was thinking to use animate.css library and add in classes that can animate the views. Yes, I want it work with routing. I’m using pushstate.

I’m working on an example right now.

Here’s an example: JS Bin

I didn’t hook it up to routing, but that shouldn’t be a huge issue if you understand how this example works. (Let me know if I’m wrong about this).

The important things to notice:

The elements are absolutely positioned

Th login / signup pages are absolutely positioned, this helps prevent collisions during the animations. You can likely work around this, but it’s tricky. Let me know if this is a problem.

It keeps both elements in the page until all animations are complete

I use page, oldPage, and shouldDisplay to make sure both pages are rendered until the animations have completed.

It works by using on:EVENT:by:SCOPE

When .login() is called, it updates the properties in a batch:

    can.batch.start();
    this.oldPage = this.page;
    this.page = "login"
    can.batch.stop();

This makes it so computes will not re-evaluate until both oldPage and page have been set.

Once this batch is done, the page will be updated, we need to make sure the <div class='login'> element is in the page before we dispatch the animateLoginPage event:

this.dispatch("animateLoginPage");

The <div> is listening to these events with:

on:animateLoginPage:by:this="slideInDown(scope.element)"

This calls the animation helper:

can.stache.registerHelper("slideInDown", function(el){
  el.classList.add("animated","slideInDown")
});

We do something similar if the signup page is being shown:

on:animateSignupPage:by:this="slideOutDown(scope.element)"

Probably the trickiest part is to remove the <div> from the page once the leaving animation has completed. To do this we can listen to animation end:

on:animationend="removeOldPage('login')"

Unfortunately, this animationend fires for both the slideIn and the slideOut. This is why we only actually removeOldPage if we are the old page.

Here’s probably a better way of doing it: JS Bin

I used inserted events to fire the slide down:

on:inserted="slideInDown(scope.element)"

And I just used the page event to figure out if the slideOutDown should actually animate:

on:page:by:this="slideOutDown(scope.element, 'login', scope.root.page)"