menaka
menaka

Reputation: 1068

Using Angular animations for animation words

I am fairly new to using animations in angular, what i wanted to do is to create a shifting worlds in a sentence.

For example: I have a list of fruits like {apple, orange, banana, etc..}

I want to display :

I Like "apple"

after 5s change apple to orange and agin after 5s orange to banana... go through the list and again to apple. How do I get this using angular animations ?

Upvotes: 1

Views: 1321

Answers (3)

bob
bob

Reputation: 2734

Assuming that the question is about how to animate changing word, here is a simple demo:

trigger('wordUpdated', [
  transition("* => *", group([
    query(':enter', [
      style({ opacity: 0, transform: 'translateY(40%)' }),
      animate('.5s ease-out', style({ opacity: 1, transform: 'translateY(0%)' }))
    ], { optional: true }),
    query(':leave', [
      style({ opacity: 1, transform: 'translateY(0%)' }),
      animate('.5s ease-out', style({ opacity: 0, transform: 'translateY(-40%)' }))
    ], { optional: true })
  ]))
])

Template:

  I like <span class="block" [@wordUpdated]="word">
    <span class="span" *ngFor="let word of [ word ]">
      {{ word }}
    </span>
  </span>

It also needs some CSS to place old / new words in the same position:

span.block {
  position: relative;
}
span.span {
  position: absolute;
  left: 0.3em;
}

Upvotes: 1

menaka
menaka

Reputation: 1068

This was a different approach =>

In the Component :

public wordList = ['Design', 'Apple', 'orange', 'banana' ];

and Create a method

    spanStyle(index, delay, length) {

      if (index == 0){

        return {'animation': 'rotateWordsSecond '+ delay*length+'s linear infinite 0s' }
      }

      return {'animation': 'rotateWordsSecond '+ delay*length+'s linear infinite 0s','animation-delay.s': index*delay }

    }

In the respective html :

<div class="rw-words">

   <span *ngFor="let word of wordList;index as i; let l = count [ngStyle]="spanStyle(i, 3, l)">{{word}} </span>

</div>

For the Styles

.rw-words
  display: inline
  text-indent: 10px

.rw-words span
  position: absolute
  opacity: 0
  overflow: hidden
  width: 100%



@keyframes rotateWordsSecond
  0%
    opacity: 1
    animation-timing-function: ease-in
    width: 0px
  10%
    opacity: 0.3
    width: 0px
  20%
    opacity: 1
    width: 100%
  27%
    opacity: 0
    width: 100%
  100%
    opacity: 0

Upvotes: 0

bodorgergely
bodorgergely

Reputation: 578

What you want can be achieved without animations, you only need good old-fashioned two-way data binding and an interval from rxjs. I went ahead and created a simple angular-cli project in stackblitz, go ahead and check out the working example.

https://stackblitz.com/edit/stackoverflow-51222243

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject, interval } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {

  fruit: string;
  fruitList: Array<string> = ['apple', 'orange', 'banana'];
  ngUnsubscribe: Subject<any> = new Subject();

  constructor() { }

  ngOnInit() {
  // init the first fruit
    this.fruit = this.fruitList[0];
    // create an interval that is going to fire every 5s
    interval(5000)
      // unsubscribe from interval when the component is destroyed, averting any memory leak
      .pipe(takeUntil(this.ngUnsubscribe))
      // subscribe to interval
      .subscribe(() => {
        // find the current fruit index in the list
        const fruitIndex = this.fruitList.findIndex((fruit: string) => fruit === this.fruit);
        // get the next fruit from the list
        const nextFruit = this.fruitList[fruitIndex + 1];
        // if next fruit is defined set displayed fruit with it
        // else if next fruit is undefined that means you reached the end of the list 
        // so set the displayed fruit with the first list item
        this.fruit = nextFruit ? nextFruit : this.fruitList[0];
      });
  }

  ngOnDestroy() {
    this.ngUnsubscribe.next();
    this.ngUnsubscribe.complete();
  }

}

Upvotes: 3

Related Questions