Quick start - Angular

Framework-agnostic - call initAnimations() once the view is ready and re-call it after SPA navigation. The engine is SSR-safe (checks window) but you should still guard with isPlatformBrowser and run only on the client.

Usage - Standalone root component

js
import { Component, AfterViewInit, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { Router, NavigationEnd, RouterOutlet } from '@angular/router';
import { filter } from 'rxjs';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
})
export class AppComponent implements AfterViewInit {
  constructor(
    @Inject(PLATFORM_ID) private platformId: Object,
    private router: Router
  ) {}

  async ngAfterViewInit() {
    if (!isPlatformBrowser(this.platformId)) return;
    const { initAnimations } = await import('gclass-anims');
    initAnimations();

    // Re-init on SPA navigation (same as Vue router.afterEach)
    this.router.events
      .pipe(filter((e) => e instanceof NavigationEnd))
      .subscribe(async () => {
        await new Promise((r) => setTimeout(r, 0));
        initAnimations();
      });
  }
}

Alternate - afterNextRender (Angular 16+)

js
import { afterNextRender, Component, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs';

@Component({ selector: 'app-root', template: '<router-outlet />' })
export class AppComponent {
  constructor(@Inject(PLATFORM_ID) pid: Object, router: Router) {
    if (!isPlatformBrowser(pid)) return;
    afterNextRender(() => {
      import('gclass-anims').then(({ initAnimations }) => {
        initAnimations();
        router.events.pipe(filter(e => e instanceof NavigationEnd))
          .subscribe(() => initAnimations());
      });
    });
  }
}

What's next

Add utility classes to your templates (class="appear scroll spawn-up", class="float magnet"). No directives or wrappers needed. Mark persistent layout shells with .preserve so they skip re-animation on route change.