[Перевод] Овладейте всем потенциалом анимирования с Vue

qg8gixddhfc3syhabrxtxgw6-hq.png


Vue позволяет разработчикам писать более гибкий и переиспользуемый код за счёт наличия дополнительных возможностей для организации компонентов. И одной из областей применения этих возможностей являются анимации. В текущей статье мы разберём использование Composition API для создания анимаций в Vue с помощью CSS и JS библиотеки GSAP (GreenSock Animation Platform).

Примечание пер.: статья содержит крупные GIF-анимации.


Для начала мы рассмотрим принцип построения анимаций с помощью CSS. Для этого мы посредством директивы v-bind привяжем CSS класс к элементу, а затем, используя функцию анимации по ключевым кадрам, создадим саму анимацию. Вот как всё это может выглядеть в компоненте Vue 3:

_8veiy0jilycov3kqwjmzk3gwf0.png

uvoopwe9coxvnvnyijwcisc2stc.gif
Итоговая анимация в формате GIF

В этом примере у нас есть элемент div с классом fade. Мы привязываем класс in или out, переключая значение animationStarted событием клика. Затем начинается анимация по ключевым кадрам, которая демонстрирует появляющийся и затухающий текст с динамическим эффектом (ease).

Вот ещё один пример анимирования элементов с использованием перехода (transition) и класса v-bind.

d1hljeg8u6dmbvdgpqhyxgv32fi.png

fdochfoiculegvxcycumna3yheu.gif
Результат в формате GIF

В этом примере у нас есть элемент img с классом fadeIn. Мы привязываем класс active, переключая значение animated с помощью события клика. Затем мы связываем значение animated в элементе style со свойством opacity. При этом animated является логическим значением, то есть может быть равно 1 или 0.

Теперь немного углубимся и используем дополнительные события.

zrnvdflklbhepx7_t5ofwuoocqe.png

lgbjx5oosftu17lmbmt2oqqnlm4.gif

В этом примере у нас есть шаблон Vue с элементом img, содержащим слушателей событий mousemove и mouseleave. При наведении мыши на изображение вызывается функция getMousePos, которая вычисляет положение курсора относительно центра изображения и обновляет несколько реактивных переменных. Затем эти переменные используются для трансформации изображения, например, его поворота относительно осей X и Y, и применения отбрасываемой тени с цветом, определяемым положением курсора. Когда же курсор изображение покидает, вызывается функция resetPos, сбрасывающая реактивные переменные на начальные значения.

А вот ещё один пример с использованием события mousemove:

elzmtrjmk8qddv5pgwmwjvrjpzk.png

svhhognvk8j8xg8ma1glnlfeeow.gif

Для просмотра непожатой версии из оригинала — кликните по анимации

Тут мы создаём на изображении эффект прожектора, используя радиальный градиент. При этом положение светового пятна управляется движением мыши. Этот эффект можно включать и отключать кнопкой. В Vue эта возможность реализуется с помощью компонента Teleport, который позволяет перемещать прожектор в другую часть DOM без необходимости использовать сложное позиционирование. Положение прожектора сохраняется в реактивных переменных с помощью ref(), а движение мыши отслеживается с помощью события @mousemove. Для стилизации используется код CSS, в котором параметры opacity и position регулируются посредством переходов.

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

Для использования этой библиотеки с Vue нужно её установить через npm install gsap. Для этого примера мы анимируем заголовки hero-раздела и изображение.

xywuscursj1pbsgnrk5nfuaovq4.png

vhtz_9-7jvm1jn7j-iqmewc607s.gif

Здесь мы использовали GSAP для создания анимаций в приложении Vue.js. Мы импортировали функции gsap и ref, которые позволили нам создать реактивные данные и обращаться к элементам в DOM. Затем мы создали реф revealUp, ссылающуюся на изображение, которое мы хотим анимировать. Функция animateImage использует метод gsap.fromTo для анимирования изображения путём изменения его свойств opacity, clipPath, autoAlpha, scale, delay, duration и ease.

Аналогичным образом функция animateInfo анимирует текстовые элементы, используя метод gsap.timeline для создания временной линии отображения каждого из них с помощью класса revealUp. При этом здесь также используется метод fromTo со свойством stagger для поочерёдного вывода анимируемых элементов.

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


Наконец, мы используем хук onMounted для вызова функций animateInfo и animateImage в момент монтирования компонента, чтобы анимации выполнялись сразу после отрисовки этого компонента.

Далее мы создадим в Vue.js кастомную директиву для использования GSAP.

5aerh4r44efiqkwufxsc9fqrgdy.png

tlk1tq9xaz1epqfjq5p9y80zlws.gif

В этом примере мы создали собственную директиву vGsap, которая позволит привязывать анимации к HTML-элементам на основе определённых событий, таких как mouseenter, click и так далее.

Сначала мы импортировали библиотеку GSAP, после чего определили три разных функции анимации для тестирования — animateRevealDown, animateRevealLeft и animatePulseRingEffect — каждую со своей временной линией, определяющей порядок анимирования элементов.

Затем мы создали директиву vGsap, получающую два аргумента: анимируемый элемент и применяемую анимацию. Эта директива настраивает слушателя на прослушивание конкретного события и активирует анимацию при его возникновении. Если событием оказывается mouseenter, мы также устанавливаем слушателя для mouseleave и используем метод gasp.to для анимирования элемента обратно в исходное состояние, когда курсор мыши его покидает.

Наконец, мы использовали директиву v-gasp в шаблоне для анимирования элементов. Мы передали ей объект, устанавливающий событие для прослушивания, и анимацию для применения к каждому нужному элементу.

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

Теперь мы сделаем шаг ещё дальше и познакомимся с использованием в приложениях Vue.js 3D-моделирования. В этом случае основанная на компонентах архитектура Vue предоставляет прекрасную основу для реализации трёхмерной графики, способствующей более погружающему и интригующему пользовательскому опыту. Здесь мы будем использовать библиотеку Trois.js, которая упростит интеграцию популярной библиотеки 3D-графики Three.js. Мы разберём создание и управление 3D-сценами, моделями и анимациями, а также научимся кастомизировать их под необходимые критерии.

С помощью Trois.js можно создавать сложные реактивные и интерактивные 3D-приложения, используя знакомые принципы Vue.js, такие как свойства, события и хуки жизненного цикла. Эта библиотека включает широкий спектр готовых компонентов, в том числе освещение, камеры, модели и эффекты пост-обработки, которые можно легко добавлять в приложение и настраивать желаемым образом.

Мы научимся создавать динамические и интерактивные эффекты для изображения. Проработав приведённый пример, вы хорошо уясните, как создавать эти эффекты с помощью Vue.js и Three.js. Вы также научитесь использовать библиотеку Trois.js для работы с Three.js в приложениях Vue.

k2oiuyvlrlc1zwrpxwxqekmhvcc.png

bwwxitjiur-q45hp5hguok9ezua.gif

Для просмотра непожатой версии из оригинала — кликните по анимации

Результат применения готового компонента Noisy Image Shader в формате GIF
В этом примере шаблон начинается с компонента , создающего отрисовщик WebGL, который будет отрисовывать 3D-сцену. У этого отрисовщика есть ряд свойств, включая ширину и высоту, а также настройки для альфа-канала, контроля вращения камеры и теней. Внутри отрисовщика присутствует компонент , настраивающий начальное положение камеры. За ним следует компонент , представляющий 3D-сцену.

Основной акцент в этом примере делается на готовый компонент , который будет создавать шумную анимированную версию изображения. Здесь мы использовали для управления анимацией различные свойства, а именно time-coef, noise-coef и z-coef.

  • :disp-coef управляет эффектом смещения изображения;
  • :noise-coef управляет степенью применяемого к изображению шума;
  • :time-coef — коэффициент, определяющий фактор времени применяемой текстуры шума;
  • :z-coef — коэффициент, влияющий на смещение текстуры шума по оси z;


Мы также использовали события @pointerOver и @pointerLeave для активации различных состояний анимации при взаимодействии пользователя с изображением.

В процессе создания анимации с помощью библиотеки GSAP мы подстраивали значения определённых свойств. Это позволяет нам осуществлять плавный переход между различными состояниями анимации на основе пользовательского ввода.

Теперь мы научимся использовать troisjs для создания 3D-сцены с моделью, загружаемой из внешнего файла.

-8e4ggw5y-rbbgj7ioka32nlkww.png

y70yzs-0mgr7xaaxk9kojgyti98.gif

Для просмотра непожатой версии из оригинала — кликните по анимации

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

Наконец, сцена содержит компонент , который загружает 3D-модель из указанного файла. После загрузки вызывается функция onReady. Она устанавливает AnimationMixer, который будет анимировать модель и запускать анимацию, воспроизводя первый клип. При этом также устанавливаются часы для отслеживания времени анимации.

В завершении для отрисовки каждого кадра вызывается функция updateMixer, которая обновляет AnimationMixer, вызывая его метод update с указанием количества времени, прошедшего с момента отрисовки последнего кадра.

При отрисовке каждого кадра вызывается mixer.value.update, которая получает количество времени, прошедшего после рендеринга предыдущего кадра. Вычисляется это время функцией clock.value.getDelta(). Вызов этого метода обновляет состояние mixer на основе прошедшего времени и требуется для плавного воспроизведения анимаций на сцене.

Вуаля! Мы успешно встроили 3D-модель на наш сайт.

Благодарю вас за уделённое время. Надеюсь, что статья оказалась для вас полезной и вдохновила на применение некоторых из описанных в ней техник и инструментов в собственных проектах. Постепенно раскрывая весь потенциал анимаций Vue, вы начнёте создавать более привлекательные и динамические интерфейсы, улучшающие пользовательский опыт и заметно выделяющие ваши приложения. Высокая гибкость Composition API и обширный функционал GSAP делают ваши возможности практически безграничными.

Удачного анимирования!

Telegram-канал с розыгрышами призов, новостями IT и постами о ретроиграх

© Habrahabr.ru