Анимация с Vue — Конференция Vue Amsterdam 2022 Серия резюме — Седьмой разговор

Добро пожаловать! Рад видеть вас в седьмой части моей серии резюме конференции Vuejs Amsterdam Conference 2022, в которой я делюсь с вами кратким изложением всех докладов.

Вы можете прочитать мою серию статей JSWorld Conference 2022 Summary (в четырех частях) здесь, где я подвел итоги всех докладов первого дня. Вы также можете найти предыдущие доклады конференции Vue Amsterdam 2022 в моем блоге.

(Повторяющееся) введение

Спустя два с половиной года JSWorld и конференция Vue Amsterdam снова прошли в Театре Амстердама с 1 по 3 июня, и у меня был шанс посетить эту конференцию впервые. Я узнал много нового, встретил много замечательных людей, пообщался с отличными разработчиками и прекрасно провел время. В первый день проходила конференция JSWorld, а во второй и третий дни — Vue Amsterdam.

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

Сначала я пытался поделиться несколькими заметками или слайдами, но чувствовал, что это недостаточно хорошо, по крайней мере, не так хорошо, как то, чем делился со мной докладчик. Поэтому я решил пересмотреть каждую речь, погрузиться в них глубже, поискать, сделать заметки и объединить их со слайдами и даже с их точными словами в речи, а затем поделиться этим с вами, чтобы то, чем я делюсь с вами, было, по крайней мере, на том же уровне, что и то, что я узнал от них.

Очень важный момент

Все, что вы прочитаете в этих нескольких статьях, является результатом усилий и времени самого оратора, а я лишь попытался выучить их, чтобы потом превратить в эти статьи. Даже многие предложения, написанные в этих статьях, являются именно тем, что они сказали или что они написали в Слайдах. Это означает, что если вы узнаете что-то новое, то только благодаря их усилиям.

И последнее, но не менее важное: возможно, я не буду вникать в каждую техническую деталь или живой код в некоторых выступлениях. Но если вам интересно и нужно больше информации, дайте мне знать, и я постараюсь написать более подробную статью отдельно. Также не забудьте заглянуть в их Twitter/Linkedin.

Здесь вы можете найти программу конференции:

JSWORLD Conference


Анимация с помощью Vue

Рамона Бисковеану — Frontend Developer в SAP

Иногда нашим приложениям нужно немного «вау», и мы можем сделать это с помощью некоторого «движения», просто идеального количества, чтобы сделать их более живыми.

Мы рассмотрим, как использовать магию Vue для создания потрясающих анимаций, от простых до более сложных, сочетая Vue с библиотеками анимации.

Веб-сайты 90-х годов

На веб-сайтах 90-х годов иногда было много движений и цветов. Но единственным способом создания анимации в те времена были gif-файлы. Только представьте, какую пропускную способность потребляли эти gif-файлы в эпоху Dial-Up интернета! В итоге, чтобы ограничить потребление полосы пропускания, мы сделали несколько крошечных низкокадровых gif-файлов, и вот результат:

Зачем нужна анимация?

Одна из причин, по которой мы используем анимацию в наши дни, да и тогда, — это привлечение внимания и сосредоточение пользователей.

Подумайте, как много у нас отвлекающих факторов: уведомления на телефонах, всплывающие окна на сайтах или прыгающие иконки в доке на macOS.

Мы также можем обмануть пользователей, заставив их думать, что наш сайт работает намного быстрее. Мы даем им понять, что наши API быстрее, размещая загрузчики и прогресс-бары. Исследования показывают, что если у вас есть пользовательский загрузчик, то у вас есть шанс задержать людей на нашем сайте дольше.

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

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

Анимация также является мощным инструментом, когда вы пытаетесь рассказать историю.

Vue <Transition />.

В ванильном JavaScript или jQuery вам нужно вручную рассчитывать тайминги и задержки, а также решать, когда добавлять или удалять классы. Но в Vue мы оборачиваем целевой элемент в компонент <Transition />, и он делает многие из этих сложных вещей автоматически. Вот простая анимация затухания:

<transition name="fade">
  <p v-if="show">hello</p>
</transition>
Вход в полноэкранный режим Выход из полноэкранного режима
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter-from, .fade-leave-to 
  opacity: 0;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Вот как Vue обрабатывает это:

Vue <TransitionGroup />

<TransitionGroup> — это встроенный компонент, предназначенный для анимации вставки, удаления и изменения порядка элементов или компонентов, отображаемых в списке.

Это простой пример скольжения некоторых плиток по экрану:

<transition-group tag="div" class="tile-section" name="list" appear>
  <TileComp
    v-for="(tile, i) in tiles"
    :key="i + 'tile'"
    :header="tile.title"
    :content="tile.content"
    :footer="tile.footer"
  ></TileComp>
</transition-group>
Вход в полноэкранный режим Выход из полноэкранного режима
.list-enter-active,
.list-leave-active {
  transition: all 1s ease;
}
.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateY(70px);
}
Вход в полноэкранный режим Выход из полноэкранного режима

JavaScript Hooks

CSS — это замечательно, и мы можем многое с его помощью сделать, но иногда этого недостаточно.

Vue предоставляет некоторые хуки для компонента <Transition />.

<Transition
  @before-enter="onBeforeEnter"
  @enter="onEnter"
  @after-enter="onAfterEnter"
  @enter-cancelled="onEnterCancelled"
  @before-leave="onBeforeLeave"
  @leave="onLeave"
  @after-leave="onAfterLeave"
  @leave-cancelled="onLeaveCancelled"
>
  <!-- ... -->
</Transition>
Вход в полноэкранный режим Выход из полноэкранного режима

GreenSock GSAP

GreenSock Animation Platform (сокращенно GSAP) — это мощная библиотека JavaScript, которая позволяет разработчикам и дизайнерам создавать надежные анимации на основе временной шкалы.

Одна из самых важных вещей, которую вы будете часто слышать в GSAP, — это Tween.

Tween — это то, что делает всю работу по созданию анимации — считайте, что это высокопроизводительный задатчик свойств. Вы вводите цели (объекты, которые вы хотите анимировать), длительность и любые свойства, которые вы хотите анимировать, и когда его головка воспроизведения перемещается в новую позицию, он определяет, какие значения свойств должны быть в этот момент, и применяет их соответствующим образом.

Общие методы для создания Tween (все эти методы возвращают экземпляр Tween):

  • gsap.to()
  • gsap.from()
  • gsap.fromTo()

Для простой анимации (без причудливой последовательности), вышеуказанные методы — это все, что вам нужно!

gsap.to(".selector", {toVars});
gsap.from(".selector", {fromVars});
gsap.fromTo(".selector", {fromVars}, {toVars});
// special properties (duration, ease, etc.) go in toVar
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь давайте добавим GSAP в наш пример с плитками:

<div class="tile-section">
  <TileComp
    v-for="(tile, i) in tiles"
    :key="i + 'tile'"
    :header="tile.title"
    :content="tile.content"
    :footer="tile.footer"
  ></TileComp>
</div>
Вход в полноэкранный режим Выход из полноэкранного режима
import gsap from "gsap";
...
mounted() {
  gsap.from(".tile", {
    duration: 0.5,
    opacity: 0,
    scale: 0,
    y: 200,
    ease: "power2",
    stagger: 0.1,
  });
},
Войти в полноэкранный режим Выход из полноэкранного режима

Счетчик анимации Vue

Еще одним простым примером использования GSAP для создания красивой анимации может быть анимация счетчика праздников. Здесь вы можете увидеть, как это будет выглядеть:

Все, что у нас есть в шаблоне, это элемент h1, которому мы передаем форматированное значение и кнопку сброса.

<div>
  <h1 ref="celebrate" class="counter" :class="{ celebrate: isCelebrate }">
    {{ this.numberWithCommas(value) }}
  </h1>
  <button class="restart" @click="restart">Restart</button>
</div>
Вход в полноэкранный режим Выход из полноэкранного режима

Нам нужно использовать функцию timeline в GSAP. Считайте ее инструментом для создания последовательности анимации.

import gsap from "gsap";
import confetti from "canvas-confetti";
const tl = gsap.timeline();
const start = 100000;
const end = 3240074;

export default {
  props: {
    msg: String,
  },
  data() {
    return {
      isCelebrate: false,
      value: start,
    };
  },
  mounted() {
    tl.fromTo(
      ".counter",
      {
        innerText: start,
        scale: 0.8,
      },
      {
        innerText: end,
        snap: { innerText: 1 },
        duration: 4,
        ease: "linear",
        onUpdate: () => {
          this.$refs.celebrate.innerText = this.numberWithCommas(
            this.$refs.celebrate.innerText
          );
        },
        onComplete: () => {
          this.celebrate();
        },
      }
    );
  },
  methods: {
    celebrate() {
      this.isCelebrate = true;
      confetti({
        particleCount: 150,
        spread: 100,
        origin: { y: 0.6 },
        colors: ["#647eff", "#42d392"],
        disableForReducedMotion: true,
      });
    },
    numberWithCommas(x) {
      return x.toString().replace(/B(?=(d{3})+(?!d))/g, ",");
    },
    restart() {
      tl.restart();
      this.isCelebrate = false;
    },
  },
};
Вход в полноэкранный режим Выход из полноэкранного режима

Переход страницы

В Vue Router 4 синтаксис перехода между страницами немного изменился. Мы больше не оборачиваем маршрутизатор в компонент перехода. Вместо этого мы используем v-slot:

<router-view v-slot="{ Component }">
  <transition name="fade">
    <component :is="Component" />
  </transition>
</router-view>
Войти в полноэкранный режим Выход из полноэкранного режима

Вот пример перехода страницы:

Для построения этого перехода страницы нам нужен хук enter:

<router-view v-slot="{ Component }">
  <transition
    :key="$route.path"
    @enter="onEnter"
    :css="false"
  >
    <component :is="Component" />
  </transition>
</router-view>
Войти в полноэкранный режим Выход из полноэкранного режима

Затем нам нужно зарегистрировать плагин SplitText из GSAP:

import gsap from "gsap";
import SplitText from "gsap/SplitText";

gsap.registerPlugin(SplitText);

gsap.defaults({
  duration: 1,
  ease: "power3.inOut",
});
Войти в полноэкранный режим Выход из полноэкранного режима

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

mySplitText(el) {
  return new SplitText(el, { type: "words,chars,lines" });
},
Войти в полноэкранный режим Выход из полноэкранного режима

Давайте посмотрим на хук onEnter:

onEnter(el, done) {
  const masterTL = gsap.timeline({
    onComplete: () => {
      done;
    },
  });

  masterTL.add(
    this.enterContentTextAnimation(
      mySplitText(".content-text-header").chars
    )
  );
  masterTL.add(
    this.enterContentTextAnimation(".content-text-body"),
    "-=0.9" //overlap with previous by 0.9s
  );
  masterTL.add(this.imgScaleOut(".content img"), "<");
    //The start of previous animation
},
Вход в полноэкранный режим Выход из полноэкранного режима

А здесь вы можете увидеть, как можно вложить временные шкалы GSAP и что делают функции enterContentTextAnimation и imgScaleOut:

enterContentTextAnimation(id) {
  const tl = gsap.timeline();

  tl.fromTo(
    id,
    {
      yPercent: "100",
      opacity: 0,
    },
    {
      yPercent: "0",
      opacity: 1,
      stagger: 0.03,
    }
  );
},

imgScaleOut(id) {
  const tl = gsap.timeline();

  tl.from(id, {
    scale: 1.5,
  });

  return tl;
},
Вход в полноэкранный режим Выход из полноэкранного режима

SVG

Анимированные графики могут быть хорошим примером SVG-анимации:

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

watch: {
  data(newValue, oldValue) {
    newValue.map((data, index) => {
      var id = "#arc" + index;
      var d = this.calculateArc(data, index);
      var oldValueD = this.calculateArc(oldValue[index]);
      const tl = gsap.timeline();

      tl.fromTo(
        id,
        {
          attr: { d: oldValueD },
        },
        {
          duration: 0.5,
          attr: { d: d },
          yoyo: true,
        }
      );
    });
  },
},
Войти в полноэкранный режим Выход из полноэкранного режима

Важно не злоупотреблять анимацией на вашем сайте. Иногда они полезны, но иногда они могут убить вашу аудиторию.


Конец седьмого разговора

Надеюсь, вам понравилась эта часть, и она может оказаться для вас такой же ценной, как и для меня.

Здесь вы можете найти следующую беседу о Nuxt 3.

Оцените статью
devanswers.ru
Добавить комментарий