Reputation: 1068
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
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
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
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