I have html component:
<section
class="flex flex-col w-full h-[100vh] overflow-hidden animate__animated animate__fadeIn"
>
<!-- Top navbar remains fixed at the top and does not shrink -->
<app-top-navbar class="flex-shrink-0"></app-top-navbar>
<!-- Main content area with side navbar and dynamic content -->
<div class="h-full flex overflow-hidden">
<!-- Side navbar remains fixed in width and does not grow or shrink -->
<app-side-navbar class="w-[10%] flex-shrink-0"></app-side-navbar>
<!-- Content area that can expand and scroll independently -->
<div class="w-full flex flex-col relative h-full overflow-y-auto">
<p class="p-3 drop-shadow-md text-gray-800 font-semibold">
{{ sectionTitle }}
</p>
<!-- Centered router-outlet container that can grow vertically -->
<div class="flex items-center justify-center h-full">
<router-outlet></router-outlet>
</div>
<!-- Bottom navigation positioned at the bottom of the content area -->
<app-overview-nav
[back_router_link]="back_router_link"
[next_router_link]="next_router_link"
></app-overview-nav>
</div>
</div>
</section>
when it is loaded, the whole page is animated using fadeIn animation. But i want to animate also
<div class="flex items-center justify-center h-full">
<router-outlet></router-outlet>
</div>
so every time the router outlet changes, it also has animate__animated animate__fadeIn
animation.
I tried using animate__animated animate__fadeIn on router-outlet, but it doesnt work.
You can check out this amazing tutorial, that explains the concept clearly.
We need to import animations using provideAnimations()
.
We define the animation to be used, here it's fade animation.
export const fadeAnimation = trigger('fadeAnimation', [
transition('* => *', [
query(':enter', [style({ opacity: 0, position: 'absolute' })], {
optional: true,
}),
query(
':leave',
[
style({ opacity: 1 }),
animate('0.3s', style({ opacity: 0, position: 'absolute' })),
],
{ optional: true }
),
query(
':enter',
[
style({ opacity: 0 }),
animate('0.3s', style({ opacity: 1, position: 'relative' })),
],
{ optional: true }
),
]),
]);
Then, we can add the animation decorator [@fadeAnimation]
, this takes an input of when to trigger the animation, for this, we are using a reference to the router-outlet
, using template reference variables. Then if it is present then the animation will fire.
<main role="main" [@fadeAnimation]="outlet.isActivated ? outlet.activatedRoute : ''">
<router-outlet #outlet="outlet"></router-outlet>
</main>
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { provideAnimations } from '@angular/platform-browser/animations';
import { RouterModule, provideRouter } from '@angular/router';
import {
trigger,
animate,
transition,
style,
query,
} from '@angular/animations';
export const fadeAnimation = trigger('fadeAnimation', [
transition('* => *', [
query(':enter', [style({ opacity: 0, position: 'absolute' })], {
optional: true,
}),
query(
':leave',
[
style({ opacity: 1 }),
animate('0.3s', style({ opacity: 0, position: 'absolute' })),
],
{ optional: true }
),
query(
':enter',
[
style({ opacity: 0 }),
animate('0.3s', style({ opacity: 1, position: 'relative' })),
],
{ optional: true }
),
]),
]);
@Component({
selector: 'app-a',
standalone: true,
template: `
<h1>Hello from {{ name }}!</h1>
<a target="_blank" href="https://angular.dev/overview">
Learn more about Angular
</a>
`,
})
export class A {
name = 'Angular';
}
@Component({
selector: 'app-b',
standalone: true,
template: `
<h1>Hello from {{ name }}!</h1>
<a target="_blank" href="https://angular.dev/overview">
Learn more about Angular
</a>
`,
})
export class B {
name = 'Angular';
}
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterModule, A, B],
animations: [fadeAnimation],
template: `
<div class="container">
<header class="my-3">
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" [routerLink]="['/a']" routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: true }">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" [routerLink]="['/b']" routerLinkActive="active">About</a>
</li>
</ul>
</header>
<main role="main" [@fadeAnimation]="outlet.isActivated ? outlet.activatedRoute : ''">
<router-outlet #outlet="outlet"></router-outlet>
</main>
</div>
`,
})
export class App {
name = 'Angular';
}
bootstrapApplication(App, {
providers: [
provideAnimations(),
provideRouter([
{ path: 'a', component: A },
{ path: 'b', component: B },
]),
],
});