Vue позволяет разработчикам писать более гибкий и переиспользуемый код за счёт наличия дополнительных возможностей для организации компонентов. И одной из областей применения этих возможностей являются анимации. В текущей статье мы разберём использование Composition API для создания анимаций в Vue с помощью CSS и JS библиотеки GSAP (GreenSock Animation Platform).
Примечание пер.: статья содержит крупные GIF-анимации.
Для начала мы рассмотрим принцип построения анимаций с помощью CSS. Для этого мы посредством директивы
v-bind
привяжем CSS класс к элементу, а затем, используя функцию анимации по ключевым кадрам, создадим саму анимацию. Вот как всё это может выглядеть в компоненте Vue 3:Итоговая анимация в формате GIF
В этом примере у нас есть элемент
div
с классом fade
. Мы привязываем класс in
или out
, переключая значение animationStarted
событием клика. Затем начинается анимация по ключевым кадрам, которая демонстрирует появляющийся и затухающий текст с динамическим эффектом (ease).Вот ещё один пример анимирования элементов с использованием перехода (transition) и класса
v-bind
.Результат в формате GIF
В этом примере у нас есть элемент
img
с классом fadeIn
. Мы привязываем класс active
, переключая значение animated
с помощью события клика. Затем мы связываем значение animated
в элементе style
со свойством opacity
. При этом animated
является логическим значением, то есть может быть равно 1 или 0.Теперь немного углубимся и используем дополнительные события.
В этом примере у нас есть шаблон Vue с элементом
img
, содержащим слушателей событий mousemove
и mouseleave
. При наведении мыши на изображение вызывается функция getMousePos
, которая вычисляет положение курсора относительно центра изображения и обновляет несколько реактивных переменных. Затем эти переменные используются для трансформации изображения, например, его поворота относительно осей X и Y, и применения отбрасываемой тени с цветом, определяемым положением курсора. Когда же курсор изображение покидает, вызывается функция resetPos
, сбрасывающая реактивные переменные на начальные значения.А вот ещё один пример с использованием события
mousemove
:Для просмотра непожатой версии из оригинала — кликните по анимации
Тут мы создаём на изображении эффект прожектора, используя радиальный градиент. При этом положение светового пятна управляется движением мыши. Этот эффект можно включать и отключать кнопкой. В Vue эта возможность реализуется с помощью компонента
Teleport
, который позволяет перемещать прожектор в другую часть DOM без необходимости использовать сложное позиционирование. Положение прожектора сохраняется в реактивных переменных с помощью ref()
, а движение мыши отслеживается с помощью события @mousemove
. Для стилизации используется код CSS, в котором параметры opacity
и position
регулируются посредством переходов.Теперь мы создадим более продвинутую анимацию, используя библиотеку GSAP, которая позволяет реализовывать роскошные и привлекательные пользовательские интерфейсы с динамическими анимациями. GSAP предоставляет широкий спектр возможностей для анимирования HTML-элементов, а также отличается высоким быстродействием и может анимировать элементы плавно даже на слабых устройствах.
Для использования этой библиотеки с Vue нужно её установить через
npm install gsap
. Для этого примера мы анимируем заголовки hero-раздела и изображение.Здесь мы использовали 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.
В этом примере мы создали собственную директиву
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.
Для просмотра непожатой версии из оригинала — кликните по анимации
Результат применения готового компонента
Noisy Image Shader
в формате GIFВ этом примере шаблон начинается с компонента <Renderer>, создающего отрисовщик WebGL, который будет отрисовывать 3D-сцену. У этого отрисовщика есть ряд свойств, включая ширину и высоту, а также настройки для альфа-канала, контроля вращения камеры и теней. Внутри отрисовщика присутствует компонент <Camera>, настраивающий начальное положение камеры. За ним следует компонент <Scene>, представляющий 3D-сцену.
Основной акцент в этом примере делается на готовый компонент <NoisyImage>, который будет создавать шумную анимированную версию изображения. Здесь мы использовали для управления анимацией различные свойства, а именно
time-coef
, noise-coef
и z-coef
.-
:disp-coef
управляет эффектом смещения изображения; -
:noise-coef
управляет степенью применяемого к изображению шума; -
:time-coef
– коэффициент, определяющий фактор времени применяемой текстуры шума; -
:z-coef
– коэффициент, влияющий на смещение текстуры шума по оси z;
Мы также использовали события
@pointerOver
и @pointerLeave
для активации различных состояний анимации при взаимодействии пользователя с изображением.В процессе создания анимации с помощью библиотеки GSAP мы подстраивали значения определённых свойств. Это позволяет нам осуществлять плавный переход между различными состояниями анимации на основе пользовательского ввода.
Теперь мы научимся использовать
troisjs
для создания 3D-сцены с моделью, загружаемой из внешнего файла.Для просмотра непожатой версии из оригинала — кликните по анимации
Этот пример отличается лишь тем, что сцена включает компонент <AmbientLight>, который обеспечивает фоновое освещение и компонент <PointLight>, создающий точечный свет. Для обоих видов освещения установлено отбрасывание теней.
Наконец, сцена содержит компонент <GltfModel>, который загружает 3D-модель из указанного файла. После загрузки вызывается функция
onReady
. Она устанавливает AnimationMixer
, который будет анимировать модель и запускать анимацию, воспроизводя первый клип. При этом также устанавливаются часы для отслеживания времени анимации.В завершении для отрисовки каждого кадра вызывается функция
updateMixer
, которая обновляет AnimationMixer
, вызывая его метод update
с указанием количества времени, прошедшего с момента отрисовки последнего кадра.При отрисовке каждого кадра вызывается
mixer.value.update
, которая получает количество времени, прошедшего после рендеринга предыдущего кадра. Вычисляется это время функцией clock.value.getDelta()
. Вызов этого метода обновляет состояние mixer
на основе прошедшего времени и требуется для плавного воспроизведения анимаций на сцене.Вуаля! Мы успешно встроили 3D-модель на наш сайт.
Благодарю вас за уделённое время. Надеюсь, что статья оказалась для вас полезной и вдохновила на применение некоторых из описанных в ней техник и инструментов в собственных проектах. Постепенно раскрывая весь потенциал анимаций Vue, вы начнёте создавать более привлекательные и динамические интерфейсы, улучшающие пользовательский опыт и заметно выделяющие ваши приложения. Высокая гибкость Composition API и обширный функционал GSAP делают ваши возможности практически безграничными.
Удачного анимирования!
Telegram-канал с розыгрышами призов, новостями IT и постами о ретроиграх ????️
3263927
вау! супер спасибо! не знал что в Vue так круто можно с 3D работать! с three.js работал а тут как их вместе использовать! спасибо огромное!