Розуміння переходів і анімації в Svelte

Якісно реалізована анімація здатна значно покращити досвід взаємодії користувача з вебсайтом, а також є ефективним способом надання зворотного зв’язку. Svelte пропонує спрощений підхід до інтеграції анімаційних ефектів та переходів у ваш застосунок, не вимагаючи застосування додаткових JavaScript бібліотек.

Розпочинаємо роботу з проєктом Svelte

Для того, щоб почати використовувати Svelte, переконайтесь, що Node.js та NPM (менеджер пакетів Node) встановлено на вашому комп’ютері. Відкрийте термінал та введіть команду:

 npm create vite

Ця команда ініціює новий проєкт Vite.js. Задайте назву проєкту, оберіть Svelte як фреймворк і вкажіть JavaScript як мову розробки. Далі, перейдіть у каталог створеного проєкту та виконайте команду для встановлення потрібних залежностей:

 npm install

Видаліть шаблонний код, прибравши папки assets та lib, а також очистіть вміст файлів App.svelte і App.css.

Застосування твінінгу в Svelte

Твінінг – це метод у анімації та комп’ютерній графіці, що створює проміжні кадри між ключовими для відтворення плавного та реалістичного руху або переходів. Svelte надає інструмент `tweened`, що дозволяє анімувати елементи, змінюючи їх числові значення, забезпечуючи створення витончених переходів та анімацій у ваших вебдодатках.

Утиліта `tweened` є складовою модуля `svelte/motion`. Для застосування `tweened` у вашому компоненті, необхідно його імпортувати:

 import { tweened } from 'svelte/motion'

В основі `tweened` лежить сховище Svelte, яке по суті є об’єктом JavaScript для керування станом. Сховище `tweened` включає в себе два методи: `set` та `update`. Базовий синтаксис `tweened` сховища має наступний вигляд:

 const y = tweened(defaultValue, {
    duration: [час_у_мілісекундах],
    easing: [функція_згладжування],
})

У фрагменті коду вище оголошується змінна `y`, пов’язана зі сховищем `tweened`. Це сховище має два параметри: перший – значення за замовчуванням для прив’язки `y`, а другий – об’єкт з двома властивостями: `duration` (тривалість анімації в мілісекундах) та `easing` (функція згладжування).

Функції згладжування в Svelte визначають динаміку анімаційних ефектів. Ці функції є частиною модуля `svelte/easing`, що означає, що для використання певної функції згладжування потрібно її імпортувати. Svelte надає інструмент для візуалізації згладжування, який дозволяє досліджувати вплив різних функцій згладжування на анімацію.

Для повної демонстрації застосування `tweened`, розглянемо приклад анімації збільшення розміру елемента у Svelte.

 <script>
  import { tweened } from "svelte/motion";
  import { bounceOut } from "svelte/easing";

  const size = tweened(0, {
    easing:bounceOut
  })
</script>

<div class="container">
  <div style={`height: ${$size * 30}px;`}>
  </div>
</div>
<button on:click={()=>(size.update(()=>$size+3))}>Збільшити розмір</button>

<style>
  .container{
    display: flex;
    align-items: flex-end;
    margin-top: 400px;
  }
  div{
    height:0;
    width:100px;
    background-color: red;
  }
</style>

У наведеному вище коді імпортуються дві функції: `tweened` та `bounceOut` з модулів `svelte/motion` та `svelte/easing`, відповідно. Далі оголошується змінна `size`, пов’язана зі сховищем анімації зі значенням за замовчуванням 0. Це значення можна отримати за допомогою символу `$` . Другим параметром функції `tweened` є об’єкт, що містить властивість `easing`, яка вказує на функцію згладжування `bounceOut`.

У секції розмітки елемент кнопки містить директиву `on:click`, що викликає метод `update` для прив’язки `size`. Цей метод збільшує значення сховища `$size` на 3 при кожному натисканні кнопки. Елемент `div` має вбудований стиль, залежний від значення сховища `$size`. При запуску цього коду в браузері, результат буде наступним:

Переходи в Svelte

Для анімації додавання та видалення елементів з DOM в Svelte передбачена директива `transition` та модуль `svelte/transition`, що пропонує корисні функції, які можуть застосовуватись із цією директивою. Наприклад, для створення ефекту розмиття елемента при його появі та зникненні з DOM, спочатку імпортуйте функцію `blur` з `svelte/transition`:

 <script>
import { blur } from 'svelte/transition';
</script>

Далі додайте функціонал, що відповідає за появу та зникнення елемента з DOM. У тезі `script` створіть змінну `visible` зі значенням `false` за замовчуванням:

 <script>
import { blur } from 'svelte/transition';
let visible = false;
</script>

Потім використовуйте блок `if` для умовного відображення елемента `div`. Переконайтеся, що додали директиву `transition` до `div` та налаштували її на розмиття:

 {#if visible}
<div transition:blur>Here I am...</div>
{/if}

Далі додайте кнопку для відображення або приховування `div`:

 <button on:click={()=>visible=!visible}>
{visible ? "Приховати" : "Показати"}
</button>

При запуску коду в браузері, результат буде наступним:

Модуль `svelte/transition` експортує сім функцій: `fade`, `blur`, `fly`, `slide`, `scale`, `draw` та `crossfade`. Переходи у Svelte можуть мати параметри. Наприклад, функція `blur` з попереднього прикладу може приймати такі параметри: `delay`, `duration`, `easing` (функція згладжування), `opacity` та `amount` (розмір розмиття).

Окрім параметрів переходів, Svelte також пропонує вхідні та вихідні переходи, що забезпечують точніший контроль над анімацією елемента. Розглянемо приклад: як зробити так, щоб при появі елемент розмивався, а при зникненні ковзав? Ось як це реалізувати:

 <script>
  import { blur, slide } from 'svelte/transition';
  let visible = false;
  </script>

{#if visible}
<div in:blur out:slide>Here I am...</div>
{/if}

<button on:click={()=>visible=!visible}>
  {visible ? "Приховати" : "Показати"}
  </button>

Зверніть увагу, що у фрагменті коду вище немає директиви `transition` в елементі `div`. Натомість використовуються директиви `in` та `out`, що вказують на `blur` та `slide`, відповідно.

Анімація елементів у Svelte

Для анімації елементів у Svelte, зручно використовувати функцію `flip` з модуля `svelte/animate`. `flip` означає “First, Last, Invert, Play”. Вона приймає три параметри: `delay`, `duration` та `easing`. Розглянемо приклад:

 <script>
  import { flip } from "svelte/animate";
  let originalList = ["Помідори", "Хліб", "Риба", "Молоко", "Корм для котів"];
  let shoppingList = [...originalList];
</script>

<div class="container">
  {#each shoppingList as item (item)}
    {@const number = shoppingList.indexOf(item)}
    <div animate:flip>
      {number + 1}. {item}
    </div>
  {/each}
</div>

<button on:click={() => shoppingList = shoppingList.sort()}>Сортувати</button>
<button on:click={() => shoppingList = [...originalList]}>Скинути</button>

У цьому прикладі показано, як використовувати директиву `animate` у Svelte. У тегу `script` імпортується функція `flip`. Оголошено два масиви: `originalList` та `shoppingList`. У `div` з класом “container” блок `each` відповідає за рендеринг кожного елемента з масиву `shoppingList`.

Дочірній `div` має директиву `animate`, що вказує на функцію `flip`. При натисканні на першу кнопку, список буде відсортовано в алфавітному порядку, а при натисканні на другу кнопку, список повернеться до початкового стану. При запуску цього коду в браузері, результат буде наступним:

Чому анімація важлива для вебдодатків?

Значення анімації виходить за рамки простої візуальної привабливості. Вона відіграє ключову роль у покращенні взаємодії з користувачем та ефективній комунікації. Поєднуючи естетику та функціональність, анімація оживляє вебзастосунки, роблячи їх не лише привабливими, а й інтуїтивно зрозумілими.