It's actually fairly simple - all you need to do is:
- get your initial (server side generated) page url
- store it in the TransferState
- when client page is reloaded, check if the url is the same
- if so, fast forward animation immediately right to the end
- ensure it's only done for the initial navigation (as the server- to client-rendered transition only occurs once)
I've created a simple directive for this purpose. Just put it on any element that has a css animation e.g.
<div class="slideInAnimation" ssrPreventAnimationReplay></div>
Here it is:
@Directive({
selector: '[ssrPreventAnimationReplay]'
})
export class ServerSidePreventAnimationReplayDirective {
static key = makeStateKey('ssrPreventAnimationReplay');
static subscription: Subscription;
constructor(
private el: ElementRef,
private transferState: TransferState,
private router: Router,
private renderer: Renderer2,
@Inject(PLATFORM_ID) private platformId) {
}
ngOnInit() {
if (isPlatformServer(this.platformId))
this.transferState.set(ServerSidePreventAnimationReplayDirective.key, { url: this.router.url });
else {
let value = this.transferState.get(ServerSidePreventAnimationReplayDirective.key, null);
if (value && value.url == this.router.url) {
this.preventAnimation();
this.cancelOnNavigation();
}
}
}
ngOnDestroy() {
if (ServerSidePreventAnimationReplayDirective.subscription)
ServerSidePreventAnimationReplayDirective.subscription.unsubscribe();
}
private preventAnimation() {
this.renderer.setStyle(this.el.nativeElement, 'animation-duration', '0ms');
this.renderer.setStyle(this.el.nativeElement, 'animation-delay', '0ms');
}
private cancelOnNavigation() {
ServerSidePreventAnimationReplayDirective.subscription = this.router.events.subscribe(async event => {
if (event instanceof NavigationStart)
this.transferState.remove(ServerSidePreventAnimationReplayDirective.key);
});
}
}
You can disable angular animations in a similar fashion.
Hope it's of help to someone.