Angular и anime.js

Для использования anime.js в проекте Angular необходимо установить библиотеку через npm:

npm install animejs --save

После установки подключение происходит через импорт в нужный компонент:

import anime from 'animejs/lib/anime.es.js';

Важно использовать модульную версию (anime.es.js), чтобы избежать конфликтов с Angular CLI и системой модулей ES6.

Основные принципы работы с anime.js

anime.js оперирует объектами анимации, где ключевыми элементами являются:

  • targets – HTML-элементы или CSS-селекторы, к которым применяется анимация.
  • duration – продолжительность анимации в миллисекундах.
  • easing – функция ускорения/замедления анимации.
  • Свойства CSS или SVG, которые будут изменяться (например, translateX, opacity, scale, rotate).

Пример базовой анимации:

anime({
  targets: '.box',
  translateX: 250,
  rotate: '1turn',
  duration: 2000,
  easing: 'easeInOutQuad'
});

Интеграция с компонентами Angular

Angular использует жизненный цикл компонентов, что позволяет запускать анимации в определённые моменты:

  • ngOnInit() – инициализация данных, запуск анимации здесь возможен, но DOM может быть ещё не готов.
  • ngAfterViewInit() – оптимальное место для запуска анимаций, так как элементы DOM уже отрендерены.

Пример анимации после рендера компонента:

import { Component, AfterViewInit } from '@angular/core';
import anime from 'animejs/lib/anime.es.js';

@Component({
  selector: 'app-demo',
  template: '<div class="box"></div>',
  styles: ['.box { width: 100px; height: 100px; background: red; }']
})
export class DemoComponent implements AfterViewInit {

  ngAfterViewInit() {
    anime({
      targets: '.box',
      translateX: 300,
      scale: 1.5,
      duration: 1500,
      easing: 'easeOutExpo'
    });
  }
}

Работа с Angular Material и динамическим DOM

При использовании Angular Material или динамически создаваемых элементов важно убедиться, что селекторы анимации применяются после их добавления в DOM. Для этого применяется:

  • ViewChild или ViewChildren для доступа к элементам.
  • Renderer2 для управления DOM и безопасного применения анимаций.

Пример анимации через ViewChild:

import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
import anime from 'animejs/lib/anime.es.js';

@Component({
  selector: 'app-demo',
  template: '<div #boxEl class="box"></div>',
  styles: ['.box { width: 100px; height: 100px; background: blue; }']
})
export class DemoComponent implements AfterViewInit {
  @ViewChild('boxEl') boxEl!: ElementRef;

  ngAfterViewInit() {
    anime({
      targets: this.boxEl.nativeElement,
      translateY: 200,
      rotate: '45deg',
      duration: 1200,
      easing: 'easeInOutSine'
    });
  }
}

Последовательности и таймлайны

Для комплексных анимаций используется timeline, который позволяет создавать цепочки эффектов с точным управлением временем:

let tl = anime.timeline({
  easing: 'easeOutExpo',
  duration: 1000
});

tl.add({
  targets: '.box',
  translateX: 250
})
.add({
  targets: '.box',
  rotate: '1turn',
  scale: 1.2
}, '-=500'); // начинаем следующую анимацию за 500ms до окончания предыдущей

Использование таймлайнов особенно удобно в Angular для анимаций при переходе между состояниями компонента или при сложных интерактивных интерфейсах.

Работа с событиями анимации

Anime.js предоставляет события для контроля:

  • begin – запускается в начале анимации.
  • update – вызывается на каждом кадре, удобно для синхронизации с Angular.
  • complete – вызывается после окончания анимации.

Пример с обратным вызовом:

anime({
  targets: '.box',
  translateX: 300,
  duration: 1000,
  easing: 'linear',
  complete: () => {
    console.log('Анимация завершена');
  }
});

Анимации SVG и сложных графических элементов

Для интеграции с SVG в Angular anime.js поддерживает:

  • Изменение атрибутов strokeDashoffset, strokeDasharray для эффектов прорисовки.
  • Анимацию трансформаций (translate, scale, rotate) для отдельных элементов <path>, <circle>.

Пример анимации линии SVG:

anime({
  targets: '#line',
  strokeDashoffset: [anime.setDashoffset, 0],
  easing: 'easeInOutSine',
  duration: 1500,
  loop: true
});

Оптимизация производительности в Angular

  • Использовать will-change в CSS для анимируемых свойств.
  • Минимизировать количество одновременно анимируемых элементов.
  • Предпочтение трансформациям (translate, scale, rotate) вместо изменения top/left.
  • Использовать ngZone.runOutsideAngular() для предотвращения лишних проверок Angular при тяжелых анимациях:
import { NgZone } from '@angular/core';

constructor(private ngZone: NgZone) {}

ngAfterViewInit() {
  this.ngZone.runOutsideAngular(() => {
    anime({
      targets: '.box',
      translateX: 500,
      duration: 2000,
      easing: 'easeOutQuad'
    });
  });
}

Реактивные анимации с Angular

Anime.js хорошо интегрируется с RxJS и реактивными формами. Например, анимация может запускаться при изменении состояния BehaviorSubject:

import { BehaviorSubject } from 'rxjs';

const state$ = new BehaviorSubject(false);

state$.subscribe(active => {
  anime({
    targets: '.box',
    scale: active ? 1.5 : 1,
    duration: 800,
    easing: 'easeInOutQuad'
  });
});

state$.next(true); // запускает анимацию

Это позволяет создавать интерактивные анимации, синхронизированные с состоянием приложения и логикой Angular.