2

I’m trying to re-activate the same animation for a DOM element, each time an input gets updated.

The animation is defined as css keyframes that is assigned to a css class and the trigger I’m using now is by removing and then re-assigning that css class, with a slight of delay in order to enable the browser to process and render that change before a new one is received. This seems to me as cumbersome at best, and more so as error prone.

To my understanding, it’s also not exactly what angular 2 animation is about, as I don’t really have different states and transitions between them, but rather just an animation which I wish to re-activate over and over.

I ran into this article, which seem to support what I need, as it exposes ‘onComplete’ etc., but turns out to be obsolete as per the latest Angular RC.

Am I missing something? Is there a way to elegantly do so without writing my own “animation” API, so that it is not so strictly dependent on hard-coded timed values? I'd also like the solution to NOT be too costly, performance-wise, if possible.

I’d greatly appreciate your input on that.

Here’s my current dummy-implementation on Plunkr.

<!-- language: lang-html-->
<div #newBall class="ball ball-in"></div>

<!-- language: typescript -->
import {Component, ViewChild} from 'angular2/core';

@Component({
  // Declare the tag name in index.html to where the component attaches
  selector: 'hello-world',

  // Location of the template for this component
  templateUrl: 'src/hello_world.html'
})
export class HelloWorld {

@ViewChild('newBall') newBall: ElementRef;

constructor(){
//emulate @input changed externally
     setInterval((i) => {
            this.reActivateAnimation(this.newBall, 'ball-in'); 
        }, 1000);
   }

/**
 @fn    private reActivateAnimation(viewChild: ElementRef, className: string, timeout: number = 30): void    
 @brief Force animation to replay, by removing and then adding (after a slight delay) a given CSS class-name.
 @param {ElementRef}    viewChild   The view child to animate.
 @param {string}    className       Name of the animation class.
 @param {number}    timeout         (Optional) the timeout
(to enable the browser to recieve the DOM manipulation and apply it before the next change).
 */
private reActivateAnimation(viewChild: ElementRef, className: string, timeout: number = 30): void {
    viewChild.nativeElement.classList.remove(className);
    setTimeout(x => {
        viewChild.nativeElement.classList.add(className);
    }, timeout);
}
}

<!-- language: css -->
 .ball-in {
    animation: ball-in 0.5s forwards;
}

@keyframes ball-in {
    0% {
        transform: scale(1);
    }

    50% {
        transform: scale(1.5);
    }

    100% {
        transform: scale(1);
    }
}





.ball {
    width: 5.5rem;
    height: 5.5rem;
    margin-top:50vh;
    margin-lefrt:50vw;
    background-size: contain;
    background-color:red;
    background-repeat: no-repeat;
    color: #fff;
    border-radius:50%;

}

2 Answers 2

1

There is a callback function now.

  (@flyInOut.start)="animationStarted($event)"
  (@flyInOut.done)="animationDone($event)"

so I think you can change the state in animationDone to make it repeat

Sign up to request clarification or add additional context in comments.

Comments

0

I'll show you how to do it with Angular2 animation. you can use take a look at official docs here : https://angular.io/docs/ts/latest/guide/animations.html#

Working Demo: https://plnkr.co/edit/7s4cH4pvizqXny1Q49UJ?p=preview

Code:

     //our root app component
import {Component} from '@angular/core';
import {animate} from '@angular/core';
import {Component} from '@angular/core';
import {style, state} from '@angular/core';
import {transition} from '@angular/core';
import {trigger} from '@angular/core';


@Component({
  selector: 'my-app',
  animations: [
    trigger("ballAnimation", [
      transition("void <=> *", [
        style({
          transform: "scale(1.5)",
      }),
        animate( "800ms" )
      ]),

    ]) 
  ],
  template: 
  `
    <div *ngIf="show" @ballAnimation="'b'" class="ball"></div>
  `

})
export class App {
  show=true;
  constructor(){
    setInterval(()=>{
     this.show=!this.show;
      console.log(this.show);
    },800)
  }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.