Angular 4 Animations not working in Ionic 3?

here is my ionic info:

global packages:
    @ionic/cli-utils : 1.0.0
    Cordova CLI      : 7.0.1 
    Ionic CLI        : 3.0.0

local packages:
    @ionic/app-scripts              : 1.3.7
    @ionic/cli-plugin-cordova       : 1.0.0
    @ionic/cli-plugin-ionic-angular : 1.0.0
    Ionic Framework                 : ionic-angular 3.2.1

System:
    Node       : v7.9.0
    OS         : macOS Sierra
    Xcode      : Xcode 8.3 Build version 8W120l 
    ios-deploy : 1.9.1 
    ios-sim    : 5.0.13

here is the relevant part of my package.json file:

"dependencies": {
    "@angular/animations": "^4.1.2",
    "@angular/common": "^4.1.2",
    "@angular/compiler": "^4.1.2",
    "@angular/compiler-cli": "^4.1.2",
    "@angular/core": "^4.1.2",
    "@angular/forms": "^4.1.2",
    "@angular/http": "^4.1.2",
    "@angular/platform-browser": "^4.1.2",
    "@angular/platform-browser-dynamic": "^4.1.2",
    "@ionic-native/core": "^3.8.0",

in my app.module.ts file:

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

and in imports:

imports: [
    BrowserModule,
    BrowserAnimationsModule,

My pages are all using the new @page decorator. Could this be the problem?
In one of my pages i have a component imported via my page’s page.module like this:

import { ProgressbarComponentModule } from  '../../components/progressbar/progressbar.module';
...
imports: [
    ProgressbarComponentModule,
...
export class MyPageModule {}

In my Progressbar component, i attempt to use animation as noted below.

in the progress bar’s template, i add the appropriate trigger:

<div class="progress-inner" [@animateProgress]>

the relevant part of the progress bar component.ts file looks like this:

import { trigger, state, style, transition, animate, AUTO_STYLE } from '@angular/animations';
...
@Component({
  selector: 'progressbar',
  templateUrl: 'progressbar.html',
  animations: [
  trigger('animateProgress', [
    state('in', style({
      width: '0px'
    })),
    transition('void => *', [
      style({
        width: '300px'
      }),
      animate(10000)
    ])
  ])
  ]

This should animate the width of my div with the class ‘.progress-inner’ from a width of 300px to 0px over 10 seconds when the component is added to the DOM, but it does nothing. Even the initial size of 300px is not set.

There are NO errors output during my build or when running the application either.

Any ideas?

1 Like

What input are you feeding to [@animateProgress] ? I’ve always seen that connected to a variable or a Boolean expression. Maybe it should work the way you have it, but you might try [@animateProgress]="true" and see what happens.

The animation i demonstrated is supposed to fire when the component is added to the DOM. Hence it does not or well SHOULD not need a state specified in the template as you noted …
(See angular’s use of the “void” state)

Nevertheless - i tried adding =true as you suggested … still does not work.

I also tried specifying a specific state as a test, like [@animateProgress]=“in” even though this is NOT how to do it according to angular… that does not work either …

Here is Angular’s documentation on this type of use case, its pretty straightforward:

nameOfState: string;

this.nameOfState = 'in';

[@animatonProgress]="nameOfState"

OK …
INTERESTING …
see my test below … it almost works … but regardless it is NOT the correct approach according to Angular’s docs.

First, I don’t think you need to import AUTO_STYLE. I’ve never needed to use it. Though I usually import and use keyframes, so maybe my situation is different from yours.

Let’s say you want some action to happen. Roughly, make that action occur in transition from any state to state action (so the transition rule is * => action) and your desired action occurs as a result of that transition. Then when you feed “action” to your variable, your component transitions from void state to action state and performs the animation.

1 Like

Hey thank you for your help on all this … its greatly appreciated man seriously…

I too did not think i needed the AUTO_STYLE import … i saw that recommended elsewhere in another ionic forum post … indeed i am not using it … ill remove it …

OK …

So here is my result …

ALMOST working … even though this is not what Angular recommends …

In the template:

<div class="progress-inner" [@animateProgress]="nameOfState">

Here is my animation logic:

animations: [
  trigger('animateProgress', [
    state('in', style({
      width: '100%'
    })),
    state('done', style({
      width: '0%'
    })),
    transition('in => done', animate('10000ms linear'))
  ])
  ]

in the component.ts …

export class ProgressbarComponent implements OnInit {
  nameOfState:string = "in";

and in OnInit…


ngOnInit() {
    setTimeout(()=>{
      this.nameOfState = "done";
    },2000);

The progress bar gets added to the DOM via *ngIf … but in attempting what i just outlined …

When the component is added to the page …

It initially displays as expected at 100% width. And then after that 2 second timeout in OnInit … the width changes to 0% as it should BUT the TRANSITION is NOT working.

It changes state instantly - without the transition.

I should add here … i only tried it with the 2sec timout as a test … because when attempting to change it with a timeout of 0 or no timeout at all … the state that is set when the component is added to the DOM is just the “done” state … it required some delay before switching to the “done” state … hence angular’s instruction to use the “void” state … ugh.

Regardless of this test …

When adding an element to the DOM, we should NOT be specifying an “in” state …
According to Angular we are just supposed to set the trigger: [@mytrigger]

And then in the animations logic use the “void => *” for the transition.

That does not work in an ionic 3 app.

I think the takeaway here from my tests are:

1. Using the “void” state does NOT work in Ionic 3
2. Transitions do NOT work in Ionic 3

2 Likes

Does this still hold true? I have been struggling to get the transition to work for two days…so I guess I answered my own question…

Transitions work if you add them on the css…still adheres to the angular trigger properties just not the duration/styles…maybe I am just animating via css transitions now but for my simple problem this will work for now…

I’ve got Angular animations working fine. In general, they are preferable to css animations - better control, lighter weight, easier to debug. Maybe irrelevant for your specific case though.

1 Like

can you post up how you have it working…ionic info and package.xml…

??? There’s been no change for months, regardless of Framework version.

The last post before I jumped in…

I think the takeaway here from my tests are:

  1. Using the “void” state does NOT work in Ionic 3
  2. Transitions do NOT work in Ionic 3

Transitions dont work…I figured you claim yours do yet the rest of the internets don’t work with latest ionic 3 …

The OP was wrong. I didn’t respond because the thread felt too dramatic. I just tested my animations 15 minutes ago and yep, still working. Ionic 3.4.

1 Like

I can confirm animations work just fine on latest ionic.

1 Like

OP, Create a blank starter app, add @angular/animations to npm then drop this over the homepage.html file:

import { Component } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  animations: [
    trigger('colorChange', [
      state('black', style({ background: 'black' })),
      transition('* => black', animate('20ms')),
      state('red', style({ background: 'red' })),
      transition('* => red', animate('20ms')),
      state('green', style({ background: 'green' })),
      transition('* => green', animate('20ms')),
      state('blue', style({ background: 'blue' })),
      transition('* => blue', animate('20ms')),
      state('yellow', style({ background: 'yellow' })),
      transition('* => yellow', animate('20ms')),
      state('orange', style({ background: 'orange' })),
      transition('* => orange', animate('20ms')),
      state('aqua', style({ background: 'aqua' })),
      transition('* => aqua', animate('20ms')),
      state('white', style({ background: 'white' })),
      transition('* => white', animate('20ms')),
      state('pink', style({ background: 'pink' })),
      transition('* => pink', animate('20ms'))
    ])
  ],
  //templateUrl: 'home.html'
  template: `
  <ion-header>
    <ion-navbar>
      <button ion-button menuToggle>
        <ion-icon name="menu"></ion-icon>
      </button>
      <ion-title>Home</ion-title>
    </ion-navbar>
  </ion-header>

  <ion-content padding [@colorChange]="currentColor">
    <button ion-button (click)="changeColor()">Color Change</button>
  </ion-content>
`
})
export class HomePage {
  private colorCount: number = 0;
  private currentColor: string;
  private intervalID: any;
  private downBeat:boolean = true ;
  colorArr: string[] = ['red', 'green', 'blue', 'yellow', 'orange', 'aqua', 'pink', 'white'];

  constructor(public navCtrl: NavController, public events: Events) {}

 
 changeColor() {
    this.colorCount++;
    if (this.colorCount < this.colorArr.length) {
      this.currentColor = this.colorArr[this.colorCount];
    } else {
      this.colorCount = 0;
      this.currentColor = this.colorArr[0];
  }
}
}

Then in app.module.ts, add this:

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

and

imports: [
    BrowserModule,
    BrowserAnimationsModule, <<< add this
    IonicModule.forRoot(MyApp),
  ],

And click the button on the home page, and if your [roject is configured properly, you should see animations

1 Like

On ionic 3.3, angular animations are working for me on the browser. We put our apps on both the browser and iPad though, and the animations are not working on the browser. I would suspect that this is probably more of an angular/cordova problem, rather than an ionic problem.

Anyone else seen the same? Animations not working on the iPad?

My issues relate to mostly using ‘%’ as the animations don’t work with relative values. using the ‘*’ has solved my problems on android but not for iOS so I think something with iOS isn’t happy…

Turns out, web animations are not implemented in Safari, whether desktop or iOS, so you need a polyfill https://github.com/web-animations/web-animations-js

1 Like