Svelte-интеграция

Для использования anime.js в проекте на Svelte необходимо установить библиотеку через npm:

npm install animejs

Импорт выполняется в компоненте Svelte стандартным образом:

<script>
  import anime from 'animejs/lib/anime.es.js';
</script>

Важно использовать модуль anime.es.js, так как он оптимизирован для современных сборщиков модулей и корректно работает с Svelte.

Основы работы с анимацией

Anime.js использует объект конфигурации, в котором задаются свойства анимации, длительность, задержка и кривые перехода. В Svelte можно привязывать анимацию к DOM-элементам через bind:this:

<script>
  import anime from 'animejs/lib/anime.es.js';
  let box;

  function animateBox() {
    anime({
      targets: box,
      translateX: 250,
      rotate: '1turn',
      duration: 2000,
      easing: 'easeInOutQuad'
    });
  }
</script>

<div bind:this={box} class="box"></div>
<button on:click={animateBox}>Запустить анимацию</button>

<style>
  .box {
    width: 100px;
    height: 100px;
    background-color: #3498db;
  }
</style>

Ключевой момент: bind:this позволяет получить прямой доступ к DOM-узлу, что необходимо для корректного взаимодействия с anime.js.

Использование реактивных переменных

Svelte обладает системой реактивности, что позволяет динамически менять параметры анимации:

<script>
  import anime from 'animejs/lib/anime.es.js';
  let box;
  let offset = 0;

  $: anime({
    targets: box,
    translateX: offset,
    duration: 1000,
    easing: 'easeOutElastic(1, .5)'
  });
</script>

<div bind:this={box} class="box"></div>
<input type="range" min="0" max="500" bind:value={offset}>

Изменение offset автоматически перезапускает анимацию с новым значением благодаря реактивному блоку $:.

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

Anime.js позволяет анимировать группы элементов, что удобно для списков или сеток:

<script>
  import anime from 'animejs/lib/anime.es.js';
  let items = [];

  function animateItems() {
    anime({
      targets: items,
      translateY: 50,
      delay: anime.stagger(100),
      duration: 800,
      easing: 'easeOutBounce'
    });
  }
</script>

{#each Array(5) as _, i}
  <div bind:this={el => items[i] = el} class="item"></div>
{/each}

<button on:click={animateItems}>Анимировать элементы</button>

<style>
  .item {
    width: 80px;
    height: 80px;
    margin: 5px;
    background-color: #e74c3c;
    display: inline-block;
  }
</style>

Особенности: anime.stagger() позволяет создавать последовательные задержки для каждого элемента, что облегчает построение сложных последовательностей анимаций.

Использование ключевых кадров (keyframes)

Ключевые кадры дают возможность анимировать элемент через несколько этапов:

<script>
  import anime from 'animejs/lib/anime.es.js';
  let box;

  function animateWithKeyframes() {
    anime({
      targets: box,
      keyframes: [
        { translateX: 100 },
        { translateY: 100 },
        { rotate: 180 },
        { scale: 1.5 }
      ],
      duration: 3000,
      easing: 'easeInOutSine'
    });
  }
</script>

<div bind:this={box} class="box"></div>
<button on:click={animateWithKeyframes}>Ключевые кадры</button>

Преимущество: ключевые кадры позволяют объединить несколько эффектов в одной анимации без необходимости писать несколько отдельных вызовов anime().

Управление анимацией через методы

Anime.js предоставляет методы управления: play(), pause(), restart(), seek(). Их можно интегрировать в Svelte для интерактивного управления:

<script>
  import anime from 'animejs/lib/anime.es.js';
  let box;
  let animation;

  function startAnimation() {
    animation = anime({
      targets: box,
      translateX: 300,
      rotate: '1turn',
      duration: 4000,
      easing: 'easeInOutCubic',
      autoplay: false
    });
    animation.play();
  }

  function pauseAnimation() {
    animation.pause();
  }

  function restartAnimation() {
    animation.restart();
  }
</script>

<div bind:this={box} class="box"></div>
<button on:click={startAnimation}>Старт</button>
<button on:click={pauseAnimation}>Пауза</button>
<button on:click={restartAnimation}>Рестарт</button>

Замечание: хранение анимации в переменной позволяет манипулировать состоянием без необходимости пересоздавать объект каждый раз.

Анимация свойств CSS и SVG

Anime.js поддерживает анимацию любых CSS-свойств, а также атрибутов SVG. В Svelte это реализуется стандартным образом через bind:this:

<script>
  import anime from 'animejs/lib/anime.es.js';
  let circle;

  function animateSVG() {
    anime({
      targets: circle,
      r: 50,
      stroke: '#f39c12',
      duration: 1500,
      easing: 'easeOutQuad'
    });
  }
</script>

<svg width="200" height="200">
  <circle bind:this={circle} cx="100" cy="100" r="20" fill="none" stroke="#3498db" stroke-width="4"/>
</svg>
<button on:click={animateSVG}>Анимировать SVG</button>

Особенность: anime.js может плавно интерполировать числовые значения и цветовые свойства, что упрощает создание визуально богатых эффектов.

Интеграция с переходами Svelte

Для синергии с нативными переходами Svelte anime.js может использоваться внутри функций on:intro и on:outro:

<script>
  import anime from 'animejs/lib/anime.es.js';
  let visible = false;

  function fadeIn(node) {
    anime({
      targets: node,
      opacity: [0, 1],
      translateY: [-20, 0],
      duration: 800,
      easing: 'easeOutQuad'
    });
  }
</script>

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

{#if visible}
  <div transition:fadeIn class="box"></div>
{/if}

Это позволяет использовать anime.js для кастомных эффектов появления и исчезновения элементов, расширяя возможности стандартных переходов Svelte.

Настройка сложных временных линий

Для управления несколькими анимациями одновременно используется anime.timeline:

<script>
  import anime from 'animejs/lib/anime.es.js';
  let box1, box2;

  const timeline = anime.timeline({
    easing: 'easeOutExpo',
    duration: 1000,
    autoplay: false
  });

  timeline
    .add({
      targets: box1,
      translateX: 200
    })
    .add({
      targets: box2,
      translateY: 150
    }, '-=500'); // отступ по времени для наложения анимаций

  function playTimeline() {
    timeline.play();
  }
</script>

<div bind:this={box1} class="box red"></div>
<div bind:this={box2} class="box blue"></div>
<button on:click={playTimeline}>Запустить таймлайн</button>

<style>
  .box {
    width: 80px;
    height: 80px;
    margin: 10px;
    display: inline-block;
  }
  .red { background-color: #e74c3c; }
  .blue { background-color: #3498db; }
</style>

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