LogoLogo
HomeDiscourseBlogDiscord
  • Introduction
  • Introduction
    • Quick start
    • Aurelia for new developers
    • Hello world
      • Creating your first app
      • Your first component - part 1: the view model
      • Your first component - part 2: the view
      • Running our app
      • Next steps
  • Templates
    • Template Syntax
      • Attribute binding
      • Event binding
      • Text interpolation
      • Template promises
      • Template references
      • Template variables
      • Globals
    • Custom attributes
    • Value converters (pipes)
    • Binding behaviors
    • Form Inputs
    • CSS classes and styling
    • Conditional Rendering
    • List Rendering
    • Lambda Expressions
    • Local templates (inline templates)
    • SVG
  • Components
    • Component basics
    • Component lifecycles
    • Bindable properties
    • Styling components
    • Slotted content
    • Scope and context
    • CustomElement API
    • Template compilation
      • processContent
      • Extending templating syntax
      • Modifying template parsing with AttributePattern
      • Extending binding language
      • Using the template compiler
      • Attribute mapping
  • Getting to know Aurelia
    • Routing
      • @aurelia/router
        • Getting Started
        • Creating Routes
        • Routing Lifecycle
        • Viewports
        • Navigating
        • Route hooks
        • Router animation
        • Route Events
        • Router Tutorial
        • Router Recipes
      • @aurelia/router-lite
        • Getting started
        • Router configuration
        • Configuring routes
        • Viewports
        • Navigating
        • Lifecycle hooks
        • Router hooks
        • Router events
        • Navigation model
        • Current route
        • Transition plan
    • App configuration and startup
    • Enhance
    • Template controllers
    • Understanding synchronous binding
    • Dynamic composition
    • Portalling elements
    • Observation
      • Observing property changes with @observable
      • Effect observation
      • HTML observation
      • Using observerLocator
    • Watching data
    • Dependency injection (DI)
    • App Tasks
    • Task Queue
    • Event Aggregator
  • Developer Guides
    • Animation
    • Testing
      • Overview
      • Testing attributes
      • Testing components
      • Testing value converters
      • Working with the fluent API
      • Stubs, mocks & spies
    • Logging
    • Building plugins
    • Web Components
    • UI virtualization
    • Errors
      • Kernel Errors
      • Template Compiler Errors
      • Dialog Errors
      • Runtime HTML Errors
    • Bundlers
    • Recipes
      • Apollo GraphQL integration
      • Auth0 integration
      • Containerizing Aurelia apps with Docker
      • Cordova/Phonegap integration
      • CSS-in-JS with Emotion
      • DOM style injection
      • Firebase integration
      • Markdown integration
      • Multi root
      • Progress Web Apps (PWA's)
      • Securing an app
      • SignalR integration
      • Strongly-typed templates
      • TailwindCSS integration
      • WebSockets Integration
      • Web Workers Integration
    • Playground
      • Binding & Templating
      • Custom Attributes
        • Binding to Element Size
      • Integration
        • Microsoft FAST
        • Ionic
    • Migrating to Aurelia 2
      • For plugin authors
      • Side-by-side comparison
    • Cheat Sheet
  • Aurelia Packages
    • Validation
      • Validation Tutorial
      • Plugin Configuration
      • Defining & Customizing Rules
      • Architecture
      • Tagging Rules
      • Model Based Validation
      • Validation Controller
      • Validate Binding Behavior
      • Displaying Errors
      • I18n Internationalization
      • Migration Guide & Breaking Changes
    • i18n Internationalization
    • Fetch Client
      • Overview
      • Setup and Configuration
      • Response types
      • Working with forms
      • Intercepting responses & requests
      • Advanced
    • Event Aggregator
    • State
    • Store
      • Configuration and Setup
      • Middleware
    • Dialog
  • Tutorials
    • Building a ChatGPT inspired app
    • Building a realtime cryptocurrency price tracker
    • Building a todo application
    • Building a weather application
    • Building a widget-based dashboard
    • React inside Aurelia
    • Svelte inside Aurelia
    • Synthetic view
    • Vue inside Aurelia
  • Community Contribution
    • Joining the community
    • Code of conduct
    • Contributor guide
    • Building and testing aurelia
    • Writing documentation
    • Translating documentation
Powered by GitBook
On this page

Was this helpful?

Export as PDF
  1. Getting to know Aurelia
  2. Routing
  3. @aurelia/router

Router animation

Strategies for stateful router animation

PreviousRoute hooksNextRoute Events

Last updated 2 years ago

Was this helpful?

A common scenario in a single-page application is page transitions. When a page loads or unloads, an animation or transition effect might be used to make it feel more interactive and app-like.

By leveraging , we can perform animations and transition effects in code.

animation-hooks.ts
import { lifecycleHooks } from '@aurelia/runtime-html';
import anime from 'animejs';

const animateIn = (element) =>
  anime({
    targets: element,
    translateX: () => ['110%', '0%'],
    duration: 900,
    easing: 'easeInOutQuart',
  });

const animateOut = (element) =>
  anime({
    targets: element,
    translateX: () => ['0%', '110%'],
    duration: 900,
    easing: 'easeInOutQuart',
  });

@lifecycleHooks()
export class AnimationHooks {
  private element;
  private backwards = false;

  public created(vm, controller): void {
    this.element = controller.host;
  }

  public loading(vm, _params, _instruction, navigation) {
    this.backwards = navigation.navigation.back;
  }
  
  public unloading(vm, _instruction, navigation) {
    this.backwards = navigation.navigation.back;
  }

  public attaching() {
    if (this.backwards) {
      animateOut(this.element);
    } else {
      animateIn(this.element);
    }
  }

  public detaching() {
    if (this.backwards) {
      animateIn(this.element);
    } else {
      animateOut(this.element);
    }
  }
}

At first glance, this might look like a lot of code, but we do the animation inside of the attaching and detaching hooks. Using the Anime.js animation library, we create two animation functions for sliding our views in and out.

We use the created lifecycle callback to access the host element (the outer element of our custom element) which we will animate. Most of the other callbacks determine the direction we are heading in.

import { One } from './one';
import { Two } from './two';
import { AnimationHooks } from './animation-hooks';

export class MyApp {
  static dependencies = [AnimationHooks];

  public static routes = [
    { path: ['', 'one'], component: One },
    { path: 'two', component: Two },
  ];

  public message: string = 'Hello Aurelia 2!';
}pe

We inject out AnimationHooks class into our main component, but we also inject it into the sub-components we want to animate. We avoid setting our hook globally, or it would run for all components (which you might want).

As you can see, besides some router-specific lifecycle methods, animating with the router isn't router-specific and leverages Aurelia lifecycles.

A link to a demo of slide in and out animations based on routing can be seen below:

lifecycle hooks
Aurelia Router Animations - StackBlitzStackBlitz
Logo