Работа с Vue.js

Для использования библиотеки anime.js во Vue.js необходимо учитывать реактивность данных и жизненный цикл компонентов. Анимации должны запускаться в момент, когда DOM уже отрендерен, поэтому основной инструмент для этого — хук mounted().

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

export default {
  data() {
    return {
      animateState: false
    };
  },
  mounted() {
    this.startAnimation();
  },
  methods: {
    startAnimation() {
      anime({
        targets: '.box',
        translateX: 250,
        duration: 1000,
        easing: 'easeInOutQuad'
      });
    }
  }
};
</script>

<template>
  <div class="box"></div>
</template>

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

Здесь mounted() гарантирует, что .box существует в DOM, прежде чем anime.js попытается анимировать элемент.


Анимация на основе реактивных данных

Vue позволяет управлять состояниями через data, что удобно для динамических анимаций:

data() {
  return {
    position: 0
  };
},
watch: {
  position(newVal) {
    anime({
      targets: '.box',
      translateX: newVal,
      duration: 500,
      easing: 'easeOutExpo'
    });
  }
}

Любое изменение переменной position будет автоматически запускать анимацию, что создаёт тесную интеграцию с реактивной моделью Vue.


Использование директив для анимаций

Для упрощения повторного использования анимаций можно создать кастомную директиву:

Vue.directive('anime', {
  mounted(el, binding) {
    anime({
      targets: el,
      ...binding.value
    });
  }
});

Применение директивы в шаблоне:

<div v-anime="{ translateX: 200, duration: 800, easing: 'easeInOutSine' }"></div>

Директива позволяет декларировать анимацию прямо в шаблоне, сохраняя код компонентов чистым и компактным.


Последовательные и параллельные анимации

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

mounted() {
  const tl = anime.timeline({
    easing: 'easeOutExpo',
    duration: 750
  });

  tl.add({
    targets: '.box1',
    translateX: 250
  })
  .add({
    targets: '.box2',
    translateY: 150
  }, '-=500'); // параллельная анимация с задержкой
}

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


Анимации при изменении компонентов

Для анимации компонентов при их появлении и удалении применяются переходы Vue:

<transition
  enter-active-class="animate__animated animate__fadeIn"
  leave-active-class="animate__animated animate__fadeOut"
>
  <div v-if="show" class="box"></div>
</transition>

Для использования anime.js в transition hooks можно подключить before-enter, enter и leave:

<transition
  v-on:enter="enterAnimation"
  v-on:leave="leaveAnimation"
>
  <div v-if="show" class="box"></div>
</transition>

methods: {
  enterAnimation(el, done) {
    anime({
      targets: el,
      opacity: [0, 1],
      translateY: [-50, 0],
      duration: 600,
      easing: 'easeOutQuad',
      complete: done
    });
  },
  leaveAnimation(el, done) {
    anime({
      targets: el,
      opacity: [1, 0],
      translateY: [0, 50],
      duration: 500,
      easing: 'easeInQuad',
      complete: done
    });
  }
}

Такой подход позволяет плавно интегрировать anime.js в жизненный цикл Vue-компонентов, сохраняя корректную работу реактивности.


Реактивные анимации с computed и methods

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

computed: {
  animationProps() {
    return {
      translateX: this.position,
      backgroundColor: this.active ? '#e74c3c' : '#3498db',
      duration: 700
    };
  }
},
watch: {
  animationProps: {
    handler(props) {
      anime({
        targets: '.box',
        ...props
      });
    },
    deep: true
  }
}

Это позволяет создавать сложные анимации с множеством параметров без дублирования кода и без нарушения реактивной модели Vue.


Оптимизация и производительность

  • Использовать requestAnimationFrame через anime.js для плавной анимации.
  • Минимизировать количество одновременно анимируемых DOM-элементов.
  • Предпочтительно анимировать свойства transform и opacity вместо top/left или width/height.
  • Для повторяющихся анимаций использовать loop или timeline вместо постоянного создания новых анимационных объектов.

Эти подходы позволяют поддерживать высокую производительность интерфейсов даже при сложных анимациях.


События anime.js в Vue

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

anime({
  targets: '.box',
  translateX: 300,
  duration: 1000,
  begin: () => console.log('Анимация началась'),
  update: anim => console.log('Текущее смещение:', anim.progress),
  complete: () => console.log('Анимация завершена')
});

События можно комбинировать с реактивными данными Vue для создания интерактивных и адаптивных интерфейсов.