Библиотека svelte-motion

svelte-motion — это библиотека для SvelteKit, предназначенная для создания анимаций и плавных переходов с минимальными усилиями и высокой производительностью. В основе лежит декларативный подход: состояние компонента связывается с анимацией, и изменения этого состояния автоматически трансформируются в визуальные эффекты.

Главный принцип работы — motion values. Это реактивные переменные, которые могут управлять CSS-свойствами, такими как opacity, transform, scale, rotate, x, y. Изменение значения motion автоматически запускает анимацию к новому состоянию.

Пример создания базового анимированного блока:

<script>
  import { motion } from 'svelte-motion';
  let isVisible = false;
</script>

<motion.div
  animate={{ opacity: isVisible ? 1 : 0, y: isVisible ? 0 : -50 }}
  transition={{ duration: 0.5 }}
>
  Анимированный блок
</motion.div>

<button on:click={() => isVisible = !isVisible}>Переключить видимость</button>

В этом примере animate задает конечные значения анимируемых свойств, а transition управляет длительностью и кривой анимации.


Motion Values и их реактивность

Motion values можно использовать отдельно от компонента motion. Это полезно для сложных взаимодействий или анимаций, зависящих от пользовательских событий.

<script>
  import { spring } from 'svelte-motion';
  let x = spring(0, { stiffness: 0.1, damping: 0.25 });
  
  function moveRight() {
    x.set(200);
  }
</script>

<div style="width:50px;height:50px;background:red;transform:translateX({$x}px)"></div>
<button on:click={moveRight}>Двигаться вправо</button>

Здесь используется spring — один из видов motion values, который моделирует физику пружины. Это создает реалистичную, динамическую анимацию с инерцией и затуханием. Помимо spring доступны tween (линейная интерполяция с кривыми Bezier), inertia (имитация движения с замедлением), и keyframes для последовательных анимаций.


Переходы между состояниями

svelte-motion упрощает анимацию изменений состояния через animate. Можно задать несколько ключевых состояний и плавно переключаться между ними:

<script>
  import { motion } from 'svelte-motion';
  let state = 'start';
</script>

<motion.div
  animate={{
    start: { x: 0, opacity: 0 },
    end: { x: 300, opacity: 1 }
  }[state]}
  transition={{ duration: 1 }}
>
  Переходящий блок
</motion.div>

<button on:click={() => state = state === 'start' ? 'end' : 'start'}>Сменить состояние</button>

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


Комбинирование анимаций

svelte-motion поддерживает композицию анимаций, позволяя объединять spring, tween и другие motion values. Это особенно полезно для интерфейсов с несколькими движущимися элементами, которые должны оставаться синхронизированными.

<script>
  import { motion, spring, tween } from 'svelte-motion';
  let scale = spring(1);
  let rotate = tween(0, { duration: 0.5 });

  function animate() {
    scale.set(1.5);
    rotate.set(360);
  }
</script>

<motion.div
  style="width:100px;height:100px;background:blue;"
  animate={{ transform: `scale(${$scale}) rotate(${$rotate}deg)` }}
></motion.div>

<button on:click={animate}>Запустить комбинированную анимацию</button>

Комбинирование motion values дает полный контроль над сложными эффектами без необходимости писать низкоуровневый код анимации.


Анимация списков и элементов

Для динамических списков svelte-motion предоставляет возможности layout transitions. Это позволяет анимировать появление, исчезновение и изменение позиции элементов без ручного отслеживания координат:

<script>
  import { motion } from 'svelte-motion';
  let items = ['A', 'B', 'C'];

  function addItem() {
    items = [...items, String.fromCharCode(65 + items.length)];
  }
</script>

<motion.ul>
  {#each items as item (item)}
    <motion.li layout={{ duration: 0.4 }}>{item}</motion.li>
  {/each}
</motion.ul>

<button on:click={addItem}>Добавить элемент</button>

Использование layout автоматически отслеживает изменение DOM и плавно перемещает элементы, обеспечивая естественные анимации при добавлении, удалении и перестановке.


Настройка переходов

Библиотека поддерживает детальную настройку анимаций через объект transition. Можно задать:

  • duration — длительность в секундах
  • ease — кривая ускорения (например, ease-in, ease-out, ease-in-out)
  • stiffness, damping — параметры для spring-анимаций
  • delay — задержка перед стартом анимации
<motion.div
  animate={{ x: 300 }}
  transition={{ duration: 0.6, ease: 'ease-out', delay: 0.2 }}
>
  Настраиваемый блок
</motion.div>

Эти параметры позволяют добиться точного визуального эффекта, приближенного к дизайну в Figma или Sketch.


Интеграция с событиями

svelte-motion легко интегрируется с событиями: hover, drag, scroll. Например, для hover-анимации можно использовать whileHover:

<motion.div
  whileHover={{ scale: 1.2, rotate: 5 }}
  transition={{ duration: 0.3 }}
  style="width:100px;height:100px;background:green"
></motion.div>

Для перетаскивания элементов доступен drag и dragConstraints, что позволяет создавать интерактивные компоненты, такие как карусели, слайдеры и панели.


Производительность

svelte-motion оптимизирован под SvelteKit. Он минимально нагружает DOM, использует requestAnimationFrame и реактивные подписки, что обеспечивает плавные анимации даже на слабых устройствах. Motion values обновляются только при необходимости, избегая лишних перерисовок.


svelte-motion предоставляет полный набор инструментов для создания современных анимаций: от простых fade-in эффектов до сложных физических движений и интерактивных интерфейсов. Его декларативная модель и реактивные motion values делают разработку UI в SvelteKit быстрой, прозрачной и мощной.