Статьи

Сделайте ваш сайт интерактивным и увлекательным с Velocity.js (без jQuery)

Начните работать с Velocity.js на Warp Speed ​​(без jQuery)


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

В этой статье я представляю Velocity.js, быстрый и мощный движок JavaScript-анимации Джулиана Шапиро. К тому времени, как вы пройдете все демонстрации, вы сможете использовать Velocity.js для создания своих собственных анимаций и сделать свой веб-сайт более интерактивным и удобным для пользователя. Все это без использования jQuery, просто ванильный JavaScript.

Это третья статья в серии Beyond CSS: библиотеки динамической анимации DOM .

Вот что я уже рассмотрел:

  • Анимация DOM с помощью Anime.js затрагивает вопрос о том, как лучше всего использовать анимацию в Интернете и когда вы можете рассмотреть возможность использования библиотеки анимации JavaScript вместо анимации только с CSS. Затем он фокусируется на Anime.js, бесплатной и легкой библиотеке анимации JavaScript
  • Забавные анимационные эффекты с KUTE.js знакомят вас с KUTE.js, бесплатной и многофункциональной библиотекой анимации JavaScript.

Что вы можете оживить с Velocity.js

Velocity.js — мощная библиотека, которая ставит DOM у вас под рукой! Это позволяет вам анимировать:

  • Числовые значения свойств анимации CSS, включая цвета
  • Трансформации
  • SVG свойства
  • События прокрутки, относящиеся как к странице, так и к элементу контейнера внутри страницы
  • Исчезать и скользить анимации.

В общем, Velocity анимирует одно числовое значение свойства за раз. Например, если вы хотите перевести элемент по координатам X и Y, вы не можете использовать что-то вроде translate['10px', '15px'] . Скорее, вы должны сопровождать свойство translate соответствующей осью, например: translateX: '10px', translateY: '15px' . Существует одна функция, называемая принудительным кормлением , которую Velocity делает доступной, чтобы вы могли указать два значения одновременно. Я собираюсь представить принудительное кормление позже в этой статье.

Параметры

Объект опций Velocity дает вам немного гибкости в создании анимации.

Вот список параметров, которые вы увидите в демонстрационных материалах для этой статьи:

  • Продолжительность : как долго длится каждая анимация. Единица измерения длительности — миллисекунды.
  • Ослабление : Velocity поддерживает большинство типов jQuery UI, CSS3, то есть «легкость», «легкость входа», «легкость выхода» и «легкость выхода», кривые Безье, пошаговое ослабление и даже крутая пружина. физика. Вы можете поиграть с этим демо, чтобы увидеть опцию весенней физики в действии
  • Цикл : сколько раз анимация должна повторяться. Если вы установите для этой опции значение true , она будет работать бесконечно
  • Задержка : как долго ждать до начала анимации.

Полный список опций доступен на странице документации Velocity .

Синтаксис

Если вы являетесь пользователем jQuery, Velocity.js облегчит вам задачу. На самом деле Velocity имеет тот же API, что и jQuery. Для начала:

Загрузите Velocity, $.animate() его на свою страницу и замените все экземпляры $.animate() в jQuery на $.velocity() .

Velocity.js Документы

Однако вам не нужен jQuery для работы с Velocity, и вы не собираетесь использовать jQuery для демонстраций в этой статье. Синтаксис будет немного отличаться от того, который вы использовали бы, если бы jQuery был включен. Вот как это выглядит:

 Velocity(element, {property: value}, {option: optionValue}); 

Чтобы связать другую анимацию с тем же элементом, просто добавьте еще один вызов Velocity после предыдущего:

 Velocity(element1, {property: value}, {option: optionValue}); Velocity(element1, {property: value}, {option: optionValue}); 

Чтобы применить анимацию к нескольким элементам одновременно, просто кэшируйте все элементы в переменную и вызовите Velocity для этой переменной, не нужно писать собственный цикл. Например:

 const elements = document.querySelectorAll('<div>'); Velocity(elements, {property: value}, {option: optionValue}); 

Вы можете использовать px , % , rem , em , vw/vh и deg . Если вы не добавляете единицу, Velocity предполагает подходящую для вас единицу, обычно px .

Velocity также поддерживает операции с + , , * и / , а также относительные математические операции, добавляя знак равенства ( = ) после каждого оператора, например, '+=3em'

Velocity.js Forcefeeding: передача начальных значений

Вместо того, чтобы позволить Velocity.js запрашивать DOM, чтобы получить начальное значение элемента, вы можете установить его самостоятельно, используя этот синтаксис:

 Velocity(element, { translateX: [endValue, startValue], backgroundColor: [endValue, easing, startValue] }, { //options here }); 

В этом случае вы передаете массив из двух, необязательно трех, элементов:

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

Вы можете прочитать больше о принудительном кормлении на документах Velocity .

Взять под контроль анимацию Velocity.js

Вы можете остановить, приостановить, обратить и возобновить все вызовы Velocity для элемента, используя этот синтаксис:

  • Для остановки: Velocity(elem, 'stop');
  • Пауза: Velocity(elem, 'pause');
  • Для реверса: Velocity(elem, 'reverse');
  • Для возобновления: Velocity(elem, 'resume');

Вооружившись этими основными инструкциями, вы можете начать с практических примеров.

Демо: Падающий мяч

Начните с простого шара, падающего с верхней части страницы.

 const ball = document.querySelector('.ball'); Velocity(ball, { translateY: '130px' }, { easing: [1000, 20], duration: 2000 }); 

Приведенный выше код выбирает элемент HTML с классом .ball , переводит его на 130px вдоль оси Y в течение 2 секунд (только для демонстрационных целей, в противном случае я рекомендую гораздо более короткую продолжительность) с движением, которое ускоряется при падении и становится бодрым в конец.

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

Ради забавы, заставьте фоновый цвет шара анимировать от начального значения синеватого до темного цвета. Чтобы установить начальное значение для цвета фона, вам нужно использовать принудительную подачу Velocity.js :

 Velocity(ball, { translateY: '130px', //array items: endValue, startValue backgroundColor : ['#222', '#043d99'] }, { //options here }); 

И это все для этой базовой реализации Velocity.js. Поиграйте с кодом ниже:

Демо: Прыгающий мяч, управляемый кнопкой

Для следующей демонстрации цель состоит в том, чтобы создать эту последовательность анимации:

  • Мяч падает сверху
  • Это выглядит немного раздавленным, как он падает на землю
  • Это приобретает свою естественную форму, поскольку он отскакивает назад
  • Эта анимация продолжается в цикле
  • Вы можете остановить и возобновить циклическую анимацию одним нажатием кнопки.

Достижение этого вида анимации требует объединения нескольких анимаций и управления их анимацией в целом с помощью кнопок.

Идеальным инструментом для этого была бы временная шкала, охватывающая всех подростков и позволяющая контролировать начало и конец всех анимаций. Velocity.js не имеет собственной временной шкалы, но у вас есть несколько вариантов:

  • Использование Tweene — это прокси анимации , то есть оболочка, которую вы можете использовать с рядом библиотек анимации JavaScript, включая Velocity.js. Я пробовал этот путь, но, к сожалению, Tweene ожидает, что Velocity будет работать с jQuery, что здесь не так. Возможно, вы можете настроить код Твина, но это не идеально
  • Обращаясь к JavaScript requestAnimationFrame() , который на момент написания статьи поддерживается во всех основных браузерах, кроме Opera Mini. Это нативный API для запуска любой плавной, производительной анимации в среде браузера, например, CSS, canvas и т. Д., И этот подход вы будете использовать здесь каждый раз, когда вам нужна такая функциональность.

Разделение подростков на разные функции

Чтобы сохранить код в чистоте, вы можете создать функцию для нужных вам анимационных сцен. Затем вы просто вызываете эти функции внутри того, что я называю главной функцией , которая содержит метод requestAnimationFrame() .

Вот код:

 const changeBallPosition = (elem, propVal, easingVal, durationVal) => { Velocity(elem, { translateY: propVal }, { easing: easingVal, duration: durationVal }); }; const changeBallWidth = (elem, propVal, easingVal, durationVal) => { Velocity(elem, { scaleX: propVal }, { easing: easingVal, duration: durationVal }); }; 

Приведенный выше фрагмент кода содержит примеры написания функций стрелок ES6 . Вам нужно избавиться от ключевого слова и использовать вместо него круглые скобки ( => ).

Функция хранится в константе с использованием ключевого слова const . Не углубляясь слишком глубоко, скажем, что вы не можете обновить значение констант. Если вам нужно сохранить значение, которое необходимо обновить в вашей программе, используйте вместо этого let . Чтобы узнать больше, ES6 позволил VS const переменным от Wes Bos отлично читать.

Как видите, каждая функция содержит вызов Velocity, который заставляет шар выполнять определенное движение. Обратите внимание, что для перемещения шара и изменения его ширины код не изменяет значения свойств top и width CSS соответственно. Скорее, он изменяет значения свойств translate и scale , что приводит к гораздо более производительной анимации.

Вот основная функция с таймером. Именно здесь вы размещаете вызов вышеупомянутых функций:

 let animationFrameID; const launchBall = (elem) => { changeBallPosition(elem, '130px', 'easeInQuart', 300); changeBallWidth(elem, 1.2, 'linear', 50); changeBallWidth(elem, 1, 'linear', 50); changeBallPosition(elem, '-10px', 'easeOutQuart', 300); changeBallWidth(elem, 1, 'linear', 50); animationFrameID = requestAnimationFrame( () => { launchBall(elem); }); }; 

Обратите внимание на глобальную переменную animationFrameID . Эта переменная понадобится вам для остановки анимации с помощью cancelAnimationFrame() позже в коде, так что держитесь за нее!

Чтобы привести мяч в движение, обработайте событие нажатия кнопки Play , вызвав launchBall() и передав ей аргумент ball :

 btnPlay.addEventListener('click', function() { launchBall(ball); this.disabled = true; btnStop.disabled = false; }); 

Обратите внимание, как в этот раз вы используете ключевое слово function чтобы написать обратный вызов, который обрабатывает событие click. Это так, потому что вы используете ключевое слово this для ссылки на кнопку, на которую нажимаете, т.е. this.disabled = true; , Если вы используете функцию стрелки, ключевое слово this будет ссылаться на объект глобального window , что приведет к ошибке и не позволит вам достичь желаемого результата. Короче говоря, не используйте функции стрелок в функциях обратного вызова с динамическим контекстом .

После запуска анимации пользователям не нужно нажимать кнопку « Воспроизвести» , поэтому следующая строка кода отключает ее, а также кнопку « Стоп» , поэтому пользователи могут остановить анимацию в любое время.

Чтобы остановить мяч, вам нужна новая функция:

 const removeAnimFrame = () => { if (animationFrameID) { cancelAnimationFrame(animationFrameID); } } 

Здесь вы размещаете вызов cancelAnimationFrame() , передавая animationFrameID , который, как вы помните, содержит ссылку на циклическую анимацию шара.

Наконец, вот как вы бы обработали событие нажатия кнопки « Стоп »:

 btnStop.addEventListener('click', function() { removeAnimFrame(); Velocity(ball, 'stop', true); this.disabled = true; btnPlay.disabled = false; }); 

Этот код:

  • Удаляет цикличную анимацию
  • Calls Velocity(ball, 'stop', true); остановить анимацию
  • Отключает кнопку воспроизведения
  • И восстанавливает функциональность кнопки Стоп .

Интересным фрагментом кода является вызов метода Velocity.js stop() с дополнительным логическим (true или false) аргументом. Это необходимо для очистки очереди анимации. Если вы пропустите этот аргумент и нажмете кнопку « Стоп» , шар не прекратит анимацию. Он прекратит анимацию только после того, как все вызовы Velocity, поставленные в очередь, завершат выполнение (см. Очистка очереди анимации в разделе Stop в документации Velocity.js).

Взгляните на демо, чтобы просмотреть весь код:

Прокрутка анимации

С Velocity.js вы можете быстро реализовать как вертикальную, так и горизонтальную анимацию прокрутки. Прокрутка может касаться всей страницы или содержащего ее элемента. В любом случае, вы всегда вызываете Velocity для элемента, который вы прокручиваете в поле зрения .

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

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

 const scrolling = (element, container, direction) => { let offsetDistance = 0; direction === 'up' ? offsetDistance = -200 : 200; //velocity call Velocity(element, 'scroll', { container: container, duration: 500, offset: offsetDistance, easing: 'ease-out' }); }; 
  • Параметр element обозначает элемент, который вы хотите прокрутить в представление, в данном случае либо первый, либо последний раздел, в зависимости от направления прокрутки.
  • Направление сохраняется в параметре direction и его функциональность определяется тем, как работает троичный оператор . В частности: если значение direction ‘up’ ( direction === 'up' ? ), Тогда значение offsetDistance равно -200px, что перемещает страницу на 200px выше прокручиваемого элемента в представление ( offsetDistance = -200 ) в противном случае значение offsetDistance будет равно 200px ( : 200 ), что смещает страницу на 200px ниже прокручиваемого элемента. Параметр offsetDistance будет хранить значение для свойства параметра offset Velocity, которое позволяет offsetDistance целевую позицию прокрутки на указанную величину в пикселях.
  • Поскольку прокрутка в демонстрационной версии относится не к окну браузера, а к содержащему его элементу, вызову Velocity требуется та информация, которая в приведенном выше коде хранится в параметре контейнера . Также из-за этого установите свойство CSS position содержащего элемента на relative , absolute или fixed ; static не работает.

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

 Link.addEventListener('click', (e) => { e.preventDefault(); scrolling(lastSection, scrollerContainer, 'down'); }); 

Вот полный код:

SVG Animation

Velocity может анимировать любое свойство с одним числовым значением, включая свойства CSS, применяемые к SVG, и специфичные для SVG свойства, например, fill , stroke , stroke-width stroke-color , rx , ry и т. Д.

Полный список свойств SVG, которые может анимировать Velocity.js, можно найти в документах Velocity по анимации SVG .

Демонстрация ниже показывает изображение улыбающейся рыбы в формате SVG. Пузыри исчезают и исчезают из виду, и их глаз мигает каждые несколько секунд. Если вы нажмете кнопку « Воспроизвести» , рыба переместится влево от своего контейнера, исчезнет, ​​вернется и обернется.

Предупреждение об ошибке: к сожалению, браузеры IE / Edge не поддерживают CSS-преобразования, и Velocity не предоставляет исправления совместимости для этой ошибки. Таким образом, демонстрация не работает так, как ожидалось в этих браузерах.

Подготовьте SVG-изображение к анимации

Прежде чем писать какой-либо код, убедитесь, что ваше SVG-изображение готово для анимации с помощью Velocity.js.

  • Добавьте атрибуты класса или ID к частям SVG, которые вы планируете анимировать. Это облегчит вам нацеливание этих частей в JavaScript
  • Если вы хотите анимировать некоторые элементы целиком, оберните эти элементы внутри тегов <g></g> и добавьте атрибут класса или атрибут ID для легкой манипуляции в вашем коде JavaScript
  • Упростите и оптимизируйте свою графику.

Код JavaScript с Velocity.js

Еще раз упакуйте большую часть вашего кода в функции для большей гибкости и меньшего количества повторений.

Например, вот функция, которая перемещает рыбу:

 const moveFish = (elem, moveBy, initialPos, btn, bool = false) => { Velocity(elem, { translateX: [moveBy, initialPos] }, { duration: 5000, easing: 'linear', complete: () => { if(bool) { btn.disabled = false; } } }); }; 

Синтаксис SVG-анимации не отличается от анимации HTML-элементов. Вот что код выше делает более подробно:

  • Код выполняет вызов Velocity для элемента и использует принудительную подачу для установки значения свойства translateX , которое определяет как конечную, так и начальную позиции для элемента. Когда вы позже вызовете эту функцию, аргумент, который вы предоставите для параметра элемента, будет ссылкой на рыбу SVG.
  • Он использует встроенный метод complete () Velocity.js, чтобы активировать кнопку Play только после окончания всей анимации. Это предотвращает повторное нажатие кнопки во время анимации, которая создаст очередь анимации.
  • После завершения анимации и повторного нажатия кнопки « Воспроизведение» пользователи могут выбрать воспроизведение анимации, если они того пожелают. Эта функциональность работает через параметр bool . Если значение bool равно true, когда moveFish() функция moveFish() , собственный метод Velocity.js complete () внутри moveFish() запускается в конце анимации и повторно активирует кнопку
  • Наконец, обратите внимание на другую особенность ES6 — параметры по умолчанию . Вы устанавливаете значение по умолчанию, в этом случае это bool = false , и когда вы вызываете moveFish() вы можете пропустить соответствующий аргумент, потому что то, что вы установили в качестве значения по умолчанию, будет применено автоматически . Кроме того, вы можете изменить значение по умолчанию, явно введя аргумент. Чтобы увидеть это в действии, обратите внимание на следующий бит кода, который содержит вызов функции выше.

Чтобы добиться разных движущихся анимаций, вызывайте moveFish() несколько раз, используя разные аргументы внутри главной функции, например:

 const play = () => { moveFish(fish, '-1000', 0, btnPlay); moveFish(fish, 0, '-1000', btnPlay, true); //more functions here }; 

Обратите внимание на различные способы вызова moveFish() : первый раз без пятого аргумента и второй раз с пятым аргументом со значением true . В первом случае значение для пятого аргумента является параметром по умолчанию, который вы moveFish() при написании функции moveFish() .

Наконец, просто вызовите функцию play() для события нажатия кнопки Play :

 btnPlay.addEventListener('click', function() { this.disabled = true; play(); }); 

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

Velocity UI Pack

Вы можете дополнить Velocity.js пакетом Velocity UI Pack, плагином, который значительно улучшает рабочий процесс анимации.

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

Этот плагин предоставляет доступ к крутым предварительно зарегистрированным эффектам, таким как bounceIn / Out , swirlIn / Out , fadeIn / Out и т. Д. Вы можете увидеть список всех эффектов, которые вы можете получить из коробки, в документации по UI Pack . Кроме того, вы также можете зарегистрировать свои собственные пользовательские эффекты.

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

Вот как выглядит Velocity для скрытия формы (внутри функции hideForm() ):

 Velocity(formEl,'transition.bounceUpOut', 500); 
  • Первый аргумент — это элемент, который вы анимируете , т.е. форма в этом случае
  • Второй аргумент — это один из предварительно зарегистрированных эффектов пакета пользовательского интерфейса , т. Е. BounceUpOut (эффекты разделены на переходы и выноски, и вы добавляете эффект к соответствующей категории)
  • Последний — это продолжительность анимации.

Посмотрите демо ниже для всех деталей:

Больше ресурсов

Вот некоторые ссылки на ресурсы в Интернете, где вы можете узнать больше о Velocity.js:

Вывод

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

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

Ниже приведено лишь несколько соображений, касающихся использования Velocity.js без jQuery и SVG-анимации:

  1. Пакет пользовательского интерфейса Velocity.js предоставляет функцию с именем $.Velocity.RunSequence() , которая объединяет несколько вызовов Velocity в единый эффект, который затем можно ссылаться по имени. Эта функция была бы очень полезна при работе с более сложными анимационными последовательностями. К сожалению, мне не удалось заставить его работать без jQuery
  2. Такая мощная библиотека выиграла бы от предоставления временной шкалы. Использование Tweene могло бы быть решением, но, опять же, интеграция между Tweene и Velocity без jQuery не проста
  3. Отсутствие исправления в браузерах IE / Edge отсутствие поддержки CSS-преобразований является для меня ограничивающим фактором при использовании Velocity с SVG.

Весьма вероятно, что вышеперечисленные пункты будут рассмотрены в будущем разработчиками проекта. В то же время, помните, что Velocity.js с открытым исходным кодом. Следовательно, если вы можете подумать о каких-либо улучшениях или найти ошибку, у вас есть возможность отправить запрос на удаление или оставить комментарий в разделе вопросов репозитория Velocity.js на GitHub.

Вы использовали Velocity.js для своих анимационных проектов? Каким был ваш опыт? У вас есть анимация, которой вы хотели бы поделиться? Используйте поле для комментариев ниже, чтобы сообщить нам.

Кредиты: для демоверсии SVG графика представляет собой адаптированную версию Goldfish от Pixabay , показанное изображение любезно предоставлено Unsplash , а изображение женщины-фотографа в последней демоверсии любезно предоставлено Gratisography