Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
Ben Nadel at the jQuery Conference 2010 (Boston, MA) with: Rachel Makrucki
Ben Nadel at the jQuery Conference 2010 (Boston, MA) with: Rachel Makrucki ( @m_rookie )

Styling The Void State Using Animations In Angular 2 RC 6

By Ben Nadel on

As I've starting to dig into the Animations support in Angular 2, one thing that seemed non-obvious to me was whether or not the "void" state could be styled. I have seen and demonstrated that you can certainly provide void-oriented styles when transition to and from the "void" state; but, I wasn't sure if the "void" state itself could be styled as stand-alone state() meta-data. Turns out, it can.


 
 
 

 
 
 
 
 

Run this demo in my JavaScript Demos project on GitHub.

To be clear, what I wanted to test here was whether or not this kind of meta-data even made sense in the Animations configuration:

state( "void", style({ ... }) )

Here, I'm telling Angular 2 that when the associated element doesn't exist, it should have the given style. From a state-rendering standpoint, this clearly makes no sense - a non-existing element has no style. But, from a state-transition standpoint, it might be helpful.

To test this, I put together a small demo in which I'm adding and removing a Box to the rendered view. In the animation configuration for the @boxAnimation trigger, I'm providing explicit "void" state and non-void state style:

  • // Import the core angular services.
  • import { animate } from "@angular/core";
  • import { Component } from "@angular/core";
  • import { state } from "@angular/core";
  • import { style } from "@angular/core";
  • import { transition } from "@angular/core";
  • import { trigger } from "@angular/core";
  •  
  • @Component({
  • selector: "my-app",
  • animations: [
  • trigger(
  • "boxAnimation",
  • [
  • // Even though the "void" state is not rendered, per-say, we can style
  • // it. This way, when we transition to and from the "void" state,
  • // Angular will know what CSS properties to animate.
  • state(
  • "void",
  • style({
  • borderRadius: 50,
  • opacity: 0.0,
  • transform: "rotate( 900deg )"
  • })
  • ),
  •  
  • // CAUTION: The non-void state needs to be styled for the Web Animations
  • // API ** polyfill **. When running in Chrome, which has native support
  • // for the Web Animations API, you do NOT need this state() block. If you
  • // attempt to omit this in Firefox, however, you get the following error:
  • // --
  • // Animation to or from an underlying value is not yet supported.
  • // --
  • state(
  • "*",
  • style({
  • borderRadius: 4,
  • opacity: 1.0,
  • transform: "rotate( 0deg )"
  • })
  • ),
  •  
  • // Now, when we transition to and from the "void" state, we don't have
  • // to provide additional styles - we only need to provide the relevant
  • // animation duration and timing functions.
  • transition(
  • "void => * , * => void",
  • [
  • animate( "1000ms ease-in-out" )
  • ]
  • )
  • ] // End: boxAnimation.
  • )
  • ],
  • template:
  • `
  • <p>
  • <a (click)="removeBox()">Remove Box</a>
  • </p>
  •  
  • <div class="container">
  • <template [ngIf]="isShowingBox">
  •  
  • <div @boxAnimation class="box">
  • Box
  • </div>
  •  
  • </template>
  • </div>
  • `
  • })
  • export class AppComponent {
  •  
  • public isShowingBox: boolean;
  •  
  •  
  • // I initialize the component.
  • constructor() {
  •  
  • this.isShowingBox = true;
  •  
  • }
  •  
  •  
  • // ---
  • // PUBLIC METHODS.
  • // ---
  •  
  •  
  • // I remove the box from the view-rendering; then, several seconds later, add it
  • // back so that it can be removed again.
  • public removeBox() : void {
  •  
  • this.isShowingBox = false;
  •  
  • // In a few seconds, reset the view.
  • setTimeout(
  • () : void => {
  •  
  • this.isShowingBox = true;
  •  
  • },
  • 2000
  • );
  •  
  • }
  •  
  • }

Notice that my transition() meta-data doesn't define any styling. That's because it is using the styles provided by the individual state() configurations. The only configuration that we need to provide in the actual transition is the duration and any other optional timing information. And, when we run this in the browser, we can get the following output:


 
 
 

 
 Styling the void state in the animations meta-data in Angular 2 RC 6. 
 
 
 

As you can see, the box element is clearly transitioning to and from the "void" state styling.

As a quick side-note, I should mention that the "*" state only needs to be defined in browsers that don't have native support for the Web Animations API. In Chrome, for example - which does have native support - the browser can determine the underlying values for the animating styles and therefore doesn't need the "*" state. In Firefox, on the other hand - which relies on the polyfill - we need to explicitly provide the browser with the underlying target values of the animating properties.

Long-story-short, you can style the "void" state in Angular 2 animation meta-data. This is a helpful feature because it means that you don't have to redefine the void styles in both the "enter" and the "leave" animations for a given element.




Reader Comments

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.