Внести вклад
Подробные руководства
Маршрутизация

Анимации переходов между маршрутами

Анимации переходов между маршрутами улучшают пользовательский опыт, обеспечивая плавные визуальные переходы при навигации между различными представлениями в вашем Angular-приложении. Angular Router включает встроенную поддержку браузерного API View Transitions, что позволяет создавать бесшовные анимации при смене маршрутов в поддерживаемых браузерах.

ПОЛЕЗНО: Нативная интеграция View Transitions в Роутер в настоящее время находится в developer preview. Нативные View Transitions — это относительно новая возможность браузеров с ограниченной поддержкой.

Как работают View Transitions

View Transitions используют нативный браузерный document.startViewTransition API для создания плавных анимаций между различными состояниями вашего приложения. API работает следующим образом:

  1. Захват текущего состояния — Браузер делает снимок текущей страницы.
  2. Выполнение обновления DOM — Запускается ваша функция обратного вызова для обновления DOM.
  3. Захват нового состояния — Браузер захватывает обновленное состояние страницы.
  4. Воспроизведение перехода — Браузер анимирует переход между старым и новым состояниями.

Вот базовая структура API startViewTransition:

document.startViewTransition(async () => {
  await updateTheDOMSomehow();
});

Для получения более подробной информации о браузерном API см. Chrome Explainer.

Как Роутер использует View Transitions

Angular Router интегрирует View Transitions в жизненный цикл навигации для создания бесшовных изменений маршрутов. Во время навигации Роутер:

  1. Завершает подготовку навигации — Выполняются сопоставление маршрутов, ленивая загрузка, Guards и Resolvers.
  2. Инициализирует View Transition — Роутер вызывает startViewTransition, когда маршруты готовы к активации.
  3. Обновляет DOM — Роутер активирует новые маршруты и деактивирует старые внутри колбэка перехода.
  4. Завершает переход — Promise перехода разрешается, когда Angular завершает рендеринг.

Интеграция View Transitions в Роутер действует как прогрессивное улучшение. Если браузеры не поддерживают API View Transitions, Роутер выполняет обычные обновления DOM без анимации, гарантируя работу вашего приложения во всех браузерах.

Включение View Transitions в Роутере

Включите View Transitions, добавив функцию withViewTransitions в вашу конфигурацию роутера. Angular поддерживает как Standalone, так и NgModule подходы к загрузке приложения:

Загрузка Standalone-приложения

import {bootstrapApplication} from '@angular/platform-browser';
import {provideRouter, withViewTransitions} from '@angular/router';
import {routes} from './app.routes';

bootstrapApplication(MyApp, {
  providers: [provideRouter(routes, withViewTransitions())],
});

Загрузка с NgModule

import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';

@NgModule({
  imports: [RouterModule.forRoot(routes, {enableViewTransitions: true})],
})
export class AppRouting {}

Попробуйте пример "count" на StackBlitz

Этот пример демонстрирует, как навигация роутера может заменить прямые вызовы startViewTransition для обновления счетчика.

Настройка переходов с помощью CSS

Вы можете настроить View Transitions с помощью CSS для создания уникальных эффектов анимации. Браузер создает отдельные элементы перехода, к которым можно обращаться с помощью CSS-селекторов.

Чтобы создать пользовательские переходы:

  1. Добавьте view-transition-name — Назначьте уникальные имена элементам, которые вы хотите анимировать.
  2. Определите глобальные анимации — Создайте CSS-анимации в ваших глобальных стилях.
  3. Используйте псевдоэлементы перехода — Используйте селекторы ::view-transition-old() и ::view-transition-new().

Вот пример, добавляющий эффект вращения к элементу счетчика:

/* Define keyframe animations */
@keyframes rotate-out {
  to {
    transform: rotate(90deg);
  }
}

@keyframes rotate-in {
  from {
    transform: rotate(-90deg);
  }
}

/* Target view transition pseudo-elements */
::view-transition-old(count),
::view-transition-new(count) {
  animation-duration: 200ms;
  animation-name: -ua-view-transition-fade-in, rotate-in;
}

::view-transition-old(count) {
  animation-name: -ua-view-transition-fade-out, rotate-out;
}

ВАЖНО: Определяйте анимации View Transitions в файле глобальных стилей, а не в стилях компонента. Инкапсуляция представления в Angular изолирует стили компонента, что не позволяет им корректно воздействовать на псевдоэлементы перехода.

Попробуйте обновленный пример "count" на StackBlitz

Расширенное управление переходами с помощью onViewTransitionCreated

Функция withViewTransitions принимает объект опций с колбэком onViewTransitionCreated для расширенного управления переходами. Этот колбэк:

Используйте этот колбэк для настройки поведения перехода в зависимости от контекста навигации. Например, вы можете пропустить переходы для определенных типов навигации:

import {inject} from '@angular/core';
import {Router, withViewTransitions} from '@angular/router';

withViewTransitions({
  onViewTransitionCreated: ({transition}) => {
    const router = inject(Router);
    const targetUrl = router.getCurrentNavigation()!.finalUrl!;

    // Skip transition if only fragment or query params change
    const config = {
      paths: 'exact',
      matrixParams: 'exact',
      fragment: 'ignored',
      queryParams: 'ignored',
    };

    if (router.isActive(targetUrl, config)) {
      transition.skipTransition();
    }
  },
});

Этот пример пропускает View Transition, когда навигация изменяет только фрагмент URL или параметры запроса (например, якорные ссылки на той же странице). Метод skipTransition() предотвращает анимацию, но позволяет навигации завершиться.

Примеры из Chrome Explainer, адаптированные для Angular

Следующие примеры демонстрируют различные техники View Transitions, адаптированные из документации команды Chrome для использования с Angular Router:

Элементы перехода не обязательно должны быть одним и тем же DOM-элементом

Элементы могут плавно переходить между разными DOM-элементами, если у них одинаковое имя view-transition-name.

Пользовательские анимации входа и выхода

Создавайте уникальные анимации для элементов, входящих и выходящих из области просмотра во время переходов между маршрутами.

Асинхронные обновления DOM и ожидание контента

Angular Router отдает приоритет немедленным переходам, а не ожиданию загрузки дополнительного контента.

ПРИМЕЧАНИЕ: Angular Router не предоставляет способа задержать View Transitions. Это проектное решение предотвращает потерю интерактивности страниц во время ожидания дополнительного контента. Как отмечается в документации Chrome: "В это время страница заморожена, поэтому задержки здесь должны быть сведены к минимуму... в некоторых случаях лучше вообще избегать задержки и использовать тот контент, который у вас уже есть".

Обработка нескольких стилей View Transition с помощью типов переходов

Используйте типы переходов (view transition types) для применения различных стилей анимации в зависимости от контекста навигации.

Обработка нескольких стилей View Transition с помощью имени класса на корне перехода (устарело)

Этот подход использует CSS-классы на корневом элементе перехода для управления стилями анимации.

Переход без заморозки других анимаций

Поддерживайте другие анимации на странице во время View Transitions для создания более динамичного пользовательского опыта.

Анимация с помощью JavaScript

Управляйте View Transitions программно, используя JavaScript API для сложных сценариев анимации.