Анимации и переходы

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


Директивы для анимации

Riot.js поддерживает стандартные HTML-атрибуты и собственные директивы для управления классами и стилями элементов. Основные инструменты для анимаций:

  • class — динамическое добавление и удаление классов;
  • style — управление стилями через реактивные свойства;
  • if / show / hide — условное отображение элементов с возможностью подключения анимации при появлении и исчезновении.

Пример динамического класса:

<button class="{ active: isActive }" oncl ick="{ toggleActive }">
  Кнопка
</button>

<script>
  export default {
    isActive: false,
    toggleActive() {
      this.isActive = !this.isActive;
    }
  }
</script>

<style>
  .active {
    transition: background-color 0.3s ease;
    background-color: #4caf50;
  }
</style>

В данном примере класс active добавляется и удаляется в зависимости от реактивного свойства isActive, а CSS-переход обеспечивает плавное изменение цвета.


Переходы при монтировании и размонтировании

Riot.js позволяет подключать анимации к жизненному циклу компонентов через события onBeforeMount, onMounted, onBeforeUnmount и onUnmounted. Для плавного появления элемента можно использовать комбинацию CSS-переходов и программного управления классами.

Пример появления элемента с анимацией:

<div if="{ showBox }" class="box enter" ref="box"></div>
<button oncl ick="{ toggleBox }">Показать/Скрыть</button>

<script>
  export default {
    showBox: false,
    toggleBox() {
      this.showBox = !this.showBox;
      if (this.showBox) {
        this.update(() => {
          this.refs.box.classList.add('visible');
        });
      }
    }
  }
</script>

<style>
  .box {
    opacity: 0;
    transform: translateY(-20px);
    transition: all 0.5s ease;
  }
  .box.visible {
    opacity: 1;
    transform: translateY(0);
  }
</style>

Использование ref и метод update позволяет гарантировать, что класс visible будет применён только после монтирования элемента, обеспечивая корректную анимацию.


Плавные списки

Riot.js поддерживает анимацию для динамических списков с помощью директивы each. Для добавления и удаления элементов можно использовать CSS-переходы или встроенные методы жизненного цикла компонентов.

Пример анимации элементов списка:

<ul>
  <li each="{ item, index in items }" class="list-item" ref="listItems">{ item }</li>
</ul>
<button oncl ick="{ addItem }">Добавить</button>

<script>
  export default {
    items: ['Первый', 'Второй'],
    addItem() {
      this.items = [...this.items, `Новый ${this.items.length + 1}`];
    }
  }
</script>

<style>
  .list-item {
    opacity: 0;
    transform: translateX(-20px);
    transition: all 0.4s ease;
  }
  .list-item[data-riot-mounted] {
    opacity: 1;
    transform: translateX(0);
  }
</style>

Атрибут data-riot-mounted автоматически добавляется Riot.js после монтирования элемента, что позволяет реализовать эффект плавного появления новых элементов.


Анимации через JavaScript

Для более сложных эффектов можно использовать программные анимации через метод requestAnimationFrame или сторонние библиотеки, интегрированные с жизненным циклом Riot.js. Компоненты можно анимировать через изменения стилей, классов или трансформаций напрямую.

Пример анимации движения:

<div class="moving-box" ref="box"></div>
<button oncl ick="{ animateBox }">Анимировать</button>

<script>
  export default {
    animateBox() {
      let position = 0;
      const animate = () => {
        if (position < 200) {
          position += 2;
          this.refs.box.style.transform = `translateX(${position}px)`;
          requestAnimationFrame(animate);
        }
      };
      requestAnimationFrame(animate);
    }
  }
</script>

<style>
  .moving-box {
    width: 50px;
    height: 50px;
    background-color: #2196f3;
    transition: transform 0.1s linear;
  }
</style>

Такой подход обеспечивает точный контроль над анимацией и её временными интервалами.


Рекомендации по оптимизации анимаций

  1. Использовать CSS-переходы и трансформации вместо прямого изменения top/left для GPU-ускорения.
  2. Минимизировать количество перерисовок элементов при изменении состояния.
  3. Для списков и динамически создаваемых элементов применять data-riot-mounted или программно добавлять классы после монтирования.
  4. Разделять визуальные эффекты и логику компонентов для улучшения поддержки кода.

Анимации и переходы в Riot.js комбинируют реактивность фреймворка с возможностями CSS и JavaScript, позволяя создавать плавные, интерактивные интерфейсы без лишней сложности и зависимостей.