Перейти к содержимому

Анимации переходов

Анимации переходов (View Transitions) позволяют создавать анимированные эффекты при перемещении между различными страницами сайта. Это популярное решение для сохранения визуальной преемственности интерфейса.

Поддержка переходов в Astro основана на браузерном View Transitions API и включает в себя:

  • Несколько встроенных анимаций, таких как fade, slide и none.
  • Поддержку анимаций как для перехода вперед, так и для навигации назад.
  • Возможность полной кастомизации анимаций и создания собственных эффектов.
  • Способ сохранения состояния элементов при навигации (например, проигрывание видео без прерывания).
  • Управление поведением для браузеров, которые еще не поддерживают View Transitions API.
  • Автоматическую поддержку настройки prefers-reduced-motion.

В Astro можно использовать нативные переходы между документами, которые просто добавляют анимацию, не меняя логику многостраничного приложения (MPA). Они не требуют дополнительного JavaScript и не влияют на работу существующих скриптов.

Для расширенной функциональности Astro предоставляет встроенный компонент <ClientRouter />. Он включает клиентскую маршрутизацию, превращая ваше MPA в подобие одностраничного приложения (SPA) с очень плавными переходами.

Это дает преимущества (общий стейт, сохранение элементов), но требует внимания к инициализации скриптов после перехода.

Импортируйте и добавьте компонент <ClientRouter /> в общую секцию <head> или компонент макета. Astro создаст стандартные анимации на основе сходства элементов старой и новой страниц.

src/components/CommonHead.astro
---
import { ClientRouter } from "astro:transitions";
---
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>{title}</title>
<ClientRouter />

Этого достаточно, чтобы включить клиентскую навигацию по всему сайту!

Astro автоматически находит похожие элементы на старой и новой страницах и связывает их уникальным именем view-transition-name. Вы можете управлять этим процессом с помощью директив transition:*.

  • transition:name: Позволяет вручную связать пару DOM-элементов, если Astro не сделал этого автоматически.
  • transition:animate: Переопределяет стандартную анимацию для конкретного элемента. Используйте встроенные варианты или свои собственные.
  • transition:persist: Позволяет сохранить состояние элемента (например, позицию воспроизведения видео) при переходе на новую страницу.

Добавлено в: astro@2.10.0

Вы можете запретить замену элемента новым и сохранить его состояние между страницами с помощью transition:persist.

Например, видео будет продолжать играть без прерывания при переходе:

src/components/Video.astro
<video controls muted autoplay transition:persist>
<source src="video.mp4" type="video/mp4" />
</video>

Это также работает для островков Astro (компонентов фреймворков). Состояние счетчика (React/Vue/Svelte) не сбросится:

<Counter client:load transition:persist initialCount={5} />

Astro предоставляет несколько готовых эффектов:

  • fade (по умолчанию): Мягкое перетекание одного контента в другой.
  • slide: Старый контент уезжает влево, новый выезжает справа.
  • none: Отключает стандартную анимацию браузера. Используйте на элементе <html>, чтобы убрать fade для всей страницы.

Пример использования slide для основного контента при отключении общей анимации:

<html transition:animate="none">
<body>
<main transition:animate="slide">
...
</main>
</body>
</html>

Компонент <ClientRouter /> перехватывает клики по ссылкам <a> и события кнопок «Назад»/«Вперед».

Вы можете управлять этим процессом:

Если вы хотите, чтобы конкретная ссылка вела к обычной перезагрузке страницы, добавьте атрибут data-astro-reload:

<a href="/external-page" data-astro-reload>Обычный переход</a>

Вы можете импортировать функцию navigate для вызова перехода из JavaScript (например, при выборе значения в выпадающем списке):

<script>
import { navigate } from "astro:transitions/client";
document.querySelector("select").onchange = (event) => {
navigate(event.target.value);
};
</script>

При использовании View Transitions обычные скрипты-модули (по умолчанию в Astro) выполняются только один раз при первой загрузке сайта. Они не будут запускаться повторно при переходе на новую страницу.

Для кода, который должен работать после каждого перехода (например, инициализация мобильного меню), используйте события жизненного цикла.

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

document.addEventListener("astro:page-load", () => {
// Этот код выполнится при первой загрузке И при каждом переходе
initMyComponents();
});

Для простых инлайновых скриптов можно использовать атрибут data-astro-rerun, чтобы заставить их выполняться при каждом посещении страницы:

<script is:inline data-astro-rerun>
console.log("Я запускаюсь при каждом переходе!");
</script>

Роутер генерирует события в следующем порядке:

  1. astro:before-preparation: Перед началом загрузки новой страницы.
  2. astro:after-preparation: После того как контент загружен и распарсен.
  3. astro:before-swap: Перед заменой текущего документа новым (пользователь все еще видит снимок старой страницы).
  4. astro:after-swap: Сразу после замены DOM, но до отрисовки и выполнения скриптов.
  5. astro:page-load: Завершение перехода.

Astro стремится сделать переходы доступными «из коробки». Компонент <ClientRouter /> включает автоматическое объявление заголовка новой страницы для скринридеров (Route Announcer) и учитывает настройку prefers-reduced-motion, отключая анимации для пользователей, которым это необходимо.