[Перевод] Овладейте всем потенциалом анимирования с Vue
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
В этом примере шаблон начинается с компонента
Основной акцент в этом примере делается на готовый компонент time-coef
, noise-coef
и z-coef
.
:disp-coef
управляет эффектом смещения изображения;:noise-coef
управляет степенью применяемого к изображению шума;:time-coef
— коэффициент, определяющий фактор времени применяемой текстуры шума;:z-coef
— коэффициент, влияющий на смещение текстуры шума по оси z;
Мы также использовали события @pointerOver
и @pointerLeave
для активации различных состояний анимации при взаимодействии пользователя с изображением.
В процессе создания анимации с помощью библиотеки GSAP мы подстраивали значения определённых свойств. Это позволяет нам осуществлять плавный переход между различными состояниями анимации на основе пользовательского ввода.
Теперь мы научимся использовать troisjs
для создания 3D-сцены с моделью, загружаемой из внешнего файла.
Для просмотра непожатой версии из оригинала — кликните по анимации
Этот пример отличается лишь тем, что сцена включает компонент
Наконец, сцена содержит компонент onReady
. Она устанавливает AnimationMixer
, который будет анимировать модель и запускать анимацию, воспроизводя первый клип. При этом также устанавливаются часы для отслеживания времени анимации.
В завершении для отрисовки каждого кадра вызывается функция updateMixer
, которая обновляет AnimationMixer
, вызывая его метод update
с указанием количества времени, прошедшего с момента отрисовки последнего кадра.
При отрисовке каждого кадра вызывается mixer.value.update
, которая получает количество времени, прошедшего после рендеринга предыдущего кадра. Вычисляется это время функцией clock.value.getDelta()
. Вызов этого метода обновляет состояние mixer
на основе прошедшего времени и требуется для плавного воспроизведения анимаций на сцене.
Вуаля! Мы успешно встроили 3D-модель на наш сайт.
Благодарю вас за уделённое время. Надеюсь, что статья оказалась для вас полезной и вдохновила на применение некоторых из описанных в ней техник и инструментов в собственных проектах. Постепенно раскрывая весь потенциал анимаций Vue, вы начнёте создавать более привлекательные и динамические интерфейсы, улучшающие пользовательский опыт и заметно выделяющие ваши приложения. Высокая гибкость Composition API и обширный функционал GSAP делают ваши возможности практически безграничными.
Удачного анимирования!
Telegram-канал с розыгрышами призов, новостями IT и постами о ретроиграх