Cannot get an individual headline from the list of headlines returned by *ngFor to be animated with Angular Animation Player.
I'm making a headline news scroller that takes 20 news headlines from a live rss feed using rxjs and observable operators. I need to use the Angular AnimationPlayer because I need to include a mouseover pause() and mouseout play().
Here is my component template
<div #el>
<ng-container *ngIf="newsItems$ | async as newsItems$FromContainer">
<div id="news" class='mat-elevation-z10'>
<div class="news-title" *ngFor="let v of newsItems$FromContainer">
<div class="news-headline" [innerHTML]="v[4]"
(mouseover)="this.streamPlayer.pause()"
(mouseout)="this.streamPlayer.play()"></div>
</div>
</div>
</ng-container>
</div>
Here is my component:
@Component({
selector: 'app-news-card-list',
templateUrl: './news-card-list.component.html',
styleUrls: ['./news-card-list.component.scss']
})
export class NewsCardListComponent implements AfterViewInit {
constructor(private api: ApiService, private _builder: AnimationBuilder) { }
streamPlayer: AnimationPlayer;
@ViewChild('el', {static: false}) el: ElementRef;
title = 'news-stream';
newsItems$: Observable<Item[]>;
http$: Observable<Item[]>;
private factory = this._builder.build([
useAnimation(streamAnimation, {})
]);
ngAfterViewInit() {
this.http$ = this.api.rssSource$();
this.newsItems$ = this.http$.pipe(
map(res => Object.values(res['items'])
.map(item => {
const v = item['content'].toString()
// tslint:disable-next-line:align
.match(/(?:https.*?)(?=\"|')|(?:)(<\s*[p]*>(.*?)<\/p>)/g);
return v;
}
)));
this.streamPlayer = this.factory.create(this.el.nativeElement, {});
this.streamPlayer.play();
}
}
I ended up using a reusable Animation because when I used the normal @startEnd trigger() notation it gave me an error asking for me to install the BrowserAnimationModule, which is properly installed in the ngModule. useAnimation() effectively now acts as the trigger and is identified as so in the AnimationBuilder factory.
Here is the Animation in a separate ts file:
import {animation, animateChild, transition, animate, style, query, stagger, sequence
} from '@angular/animations';
export const streamAnimation = animation([
transition(':enter', [
query('.news-headline', [
stagger(5000,
sequence([
animate(1000, style({top: '0', opacity: '0', transform: 'translateX(0px)'})),
animate('3s', style({opacity: '1', transform: 'translateX(1200px)'})),
])
), animateChild()
], { optional: true })
])
]);
All imports and dependencies appear to be correct as I've checked them many times.
My expectation is that when this.streamPlayer.play() is run in the ngAfterViewInit() it will fire the player and the items from v[4] will scroll across the screen.
Currently I get what I expect as the starting point minus the scroll across the screen. Its 20 headlines piled on top of each other waiting for their turn to have their opacity: 0; changed to opacity: 1; and their transitionX(0) changed to transitionX(1200px). They are still waiting. Something to note - In Augury it says the player's state as "started"
At this point I have ZERO error messages. Please help if you can. Thank you