SvelteKit предоставляет мощный механизм для реализации
переходов между страницами, позволяя создавать плавные
и отзывчивые интерфейсы. В отличие от классических SPA-фреймворков,
здесь переходы интегрированы с маршрутизацией на уровне файловой
структуры src/routes, что упрощает их управление и
кастомизацию.
Основной инструмент для реализации переходов — это Svelte
transitions (transition, animate и
motion), которые применяются к компонентам страниц при их
монтировании и размонтировании.
<script>
import { fade } from 'svelte/transition';
</script>
<div transition:fade>
Содержимое страницы
</div>
При таком подходе элемент плавно появляется и исчезает при навигации. Для переходов между страницами можно использовать аналогичные механизмы, но с учётом маршрутизации SvelteKit.
SvelteKit строится на основе файловой маршрутизации.
Каждая страница — это отдельный .svelte файл в
src/routes. Чтобы добавить переходы, можно обернуть
содержимое страницы в компонент с переходом:
<script>
import { fly } from 'svelte/transition';
</script>
<main transition:fly="{{ x: 300, duration: 400 }}">
<slot />
</main>
fly позволяет задать смещение (x и
y) и длительность анимации (duration). Переход
срабатывает при монтировании страницы, а при уходе со
страницы — происходит обратная анимация.
Для глобального контроля переходов можно использовать layout
файлы, например src/routes/+layout.svelte, чтобы
единообразно применять анимации ко всем страницам:
<script>
import { fade } from 'svelte/transition';
</script>
<slot transition:fade={{ duration: 300 }} />
Это гарантирует, что каждая страница будет плавно появляться и исчезать при навигации.
SvelteKit предоставляет события жизненного цикла маршрутов:
beforeNavigate — вызывается перед сменой страницы.afterNavigate — вызывается после смены страницы.Использование этих событий позволяет точно синхронизировать переходы и, при необходимости, запускать дополнительные эффекты:
<script>
import { beforeNavigate, afterNavigate } from '$app/navigation';
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
let progress = tweened(0, { duration: 400, easing: cubicOut });
beforeNavigate(() => {
progress.set(0);
progress.set(100);
});
afterNavigate(() => {
progress.set(0);
});
</script>
<div class="progress-bar" style="width: {progress}%"></div>
Такой подход полезен для индикаторов загрузки и более сложных визуальных эффектов при смене маршрутов.
Для комплексных интерфейсов важно учитывать состояние страницы. Если на странице присутствует динамическое содержимое (например, данные из API), переходы должны корректно обрабатывать появление контента.
<script>
import { fade, slide } from 'svelte/transition';
import { onMount } from 'svelte';
let items = [];
onMount(async () => {
const res = await fetch('/api/items');
items = await res.json();
});
</script>
{#each items as item (item.id)}
<div transition:slide>
{item.name}
</div>
{/each}
{#each} с ключами (item.id) гарантирует,
что каждый элемент будет анимирован индивидуально при рендеринге и
обновлении списка.
Для более сложных эффектов можно использовать двухфазные переходы: выход со старой страницы и вход новой. Это требует управления двойной отрисовкой в layout:
<script>
import { fade } from 'svelte/transition';
import { tick } from 'svelte';
let currentPage;
let nextPage;
export let segment;
$: if (segment) {
nextPage = segment;
handleTransition();
}
async function handleTransition() {
await tick(); // ожидание отрисовки
currentPage = nextPage;
}
</script>
{#if currentPage}
<svelte:component this={currentPage} transition:fade={{ duration: 400 }} />
{/if}
Такой подход позволяет реализовать плавный эффект смены страниц, аналогичный анимациям в мобильных приложениях.
Помимо встроенных transition и animate,
доступны сторонние UI-библиотеки для SvelteKit,
предоставляющие готовые анимации и компоненты переходов:
Пример с Motion One:
<script>
import { animate } from 'motion';
let container;
$: if (container) {
animate(container, { opacity: [0, 1], transform: ['translateY(20px)', 'translateY(0)'] }, { duration: 0.5 });
}
</script>
<div bind:this={container}>
Контент с Motion One
</div>
Комбинирование этих библиотек с маршрутизацией SvelteKit позволяет создавать сложные, отзывчивые анимации страниц, при этом сохраняя производительность.
{#each} для корректной анимации
списков.beforeNavigate и
afterNavigate.Такой подход обеспечивает гибкость и масштабируемость при разработке интерфейсов с плавной сменой страниц в SvelteKit.