Svelte

Переходы и анимации

Уведомление, которое возникает рывком и так же резко пропадает, выглядит дёшево. Тост должен плавно выехать и мягко угаснуть. Вручную это значит навесить классы, дождаться окончания CSS-перехода, потом удалить узел - и так в каждом месте. Директива transition: в Svelte делает это сама: элемент анимируется при появлении в DOM и при удалении, причём Svelte ждёт окончания анимации выхода, прежде чем убрать узел. Встроенные fade, fly и slide покрывают большинство случаев одной строкой.

  • Тост-уведомление выезжает через fly и плавно исчезает при закрытии
  • Модальное окно появляется через fade, фон затемняется тем же приёмом
  • Раскрывающийся блок FAQ открывается через slide по высоте
  • Список задач: при удалении элемента остальные плавно сдвигаются через animate
  • Карточки в галерее перетасовываются с пружинной анимацией из пакета motion

Предварительные знания

  • Блоки if и each, по которым элементы появляются и исчезают из DOM
  • Базовое понимание CSS-переходов и единиц времени в миллисекундах
  • Идея ключа в keyed each для отслеживания конкретных элементов

Директива transition: и встроенные эффекты

Директива transition: навешивается на элемент внутри блока if или each и анимирует его и при появлении, и при исчезновении. Когда условие становится истинным, элемент анимированно входит; когда ложным, Svelte проигрывает анимацию выхода и только потом удаляет узел. Эффекты импортируются из svelte/transition: fade меняет прозрачность, fly сдвигает и затемняет, slide раскрывает по высоте, scale масштабирует.

Первый блок использует fade без параметров - элемент плавно проявляется и так же угасает. Второй передаёт параметры fly в фигурных скобках: смещение по оси y и длительность в миллисекундах. Одна директива описывает обе фазы, и Svelte сам дожидается окончания выхода перед удалением узла.

ЭффектЧто меняетЧастые параметры
fadeПрозрачностьduration, delay
flyСмещение и прозрачностьx, y, duration
slideВысотуduration, axis
scaleМасштаб и прозрачностьstart, duration

Длительность задаётся в миллисекундах через параметр duration. Параметр delay откладывает старт анимации - удобно, когда несколько элементов должны входить по очереди с нарастающей задержкой.

Что делает директива transition: на элементе внутри блока if?

Раздельные in: и out:

Иногда вход и выход должны выглядеть по-разному: элемент выезжает снизу, а исчезает растворяясь. Для этого вместо transition: используют две отдельные директивы: in: для появления и out: для исчезновения. Каждая принимает свой эффект и свои параметры. transition: - это сокращение для случая, когда вход и выход одинаковы; in: и out: разделяют их.

Здесь in:fly задаёт въезд снизу со смещением по y, а out:fade - растворение при удалении. Эффекты независимы, поэтому появление и исчезновение читаются по-разному. Это даёт более выразительную анимацию там, где симметрия входа и выхода нежелательна.

  • transition: один эффект — Вход и выход анимируются одинаково. Сокращённая запись для симметричной анимации
  • in: и out: раздельно — Вход и выход задаются отдельными эффектами и параметрами. Для случаев, когда фазы должны различаться

Переходы Svelte по умолчанию проигрываются только при изменении состояния, но не при первой отрисовке страницы. Чтобы элемент анимировался и при начальной загрузке, переходу передают параметр, включающий анимацию на старте.

Когда вместо transition: используют отдельные in: и out:?

animate: и плавные величины из motion

transition анимирует появление и исчезновение, но не перестановку оставшихся элементов. Когда в keyed each меняется порядок - элемент удалили, список отсортировали - соседи должны плавно переехать на новые места. За это отвечает директива animate:, обычно с эффектом flip из svelte/animate. Она работает только в блоке each с ключом, потому что Svelte отслеживает позиции по ключам элементов.

Каждый элемент each имеет ключ item, поэтому Svelte знает, какой узел куда переехал. При перемешивании animate:flip плавно перемещает узлы на новые позиции вместо мгновенного скачка. Без ключа в each такая анимация невозможна - Svelte не смог бы сопоставить старые и новые позиции.

Отдельно стоит пакет motion из экосистемы Svelte. Он даёт пружинные и твин-значения: величина не меняется скачком, а плавно стремится к новой через spring или tween. Это применяют к числам вроде позиции, прогресса или счётчика, когда нужна физически плавная интерполяция, а не дискретная смена значения.

Директива animate: требует ключ в блоке each. Без ключа Svelte не отслеживает конкретные элементы и не может анимировать их перестановку - анимация просто не сработает или будет вести себя непредсказуемо. Ключ должен быть стабильным и уникальным.

Какое условие обязательно для работы директивы animate:?

Связь с другими темами

Анимации работают там, где элементы входят и выходят из DOM:

  • Компоненты — Переход навешивается на элемент внутри компонента
  • Синтаксис шаблонов — Переходы срабатывают на блоках if и each при появлении и удалении
  • Actions — Обе директивы на элементах привязаны к жизни узла в DOM

Итог

  • Директива transition: анимирует элемент при появлении и исчезновении из DOM одной директивой
  • in: анимирует только вход, out: только выход - когда вход и выход должны отличаться
  • Встроенные fade, fly, slide и scale импортируются из svelte/transition и принимают параметры
  • animate: анимирует перестановку элементов в keyed each, когда меняется их порядок
  • Пакет motion даёт пружинные (Spring) и твин (Tween) значения через классы для плавных переходов величин вроде позиции или прогресса

Связанные уроки

  • sv-03-components — Переходы навешиваются на элементы внутри компонента, появляющиеся и исчезающие по условию
  • sv-04-template-syntax — Анимации работают с блоками if и keyed each, где элементы входят и выходят из DOM
  • sv-15-actions — И переходы, и actions - директивы на элементах, привязанные к появлению узла в DOM
Переходы и анимации

0

1

Войти