Анимация без jQuery

07 Октября 2014 15442 , , ,

Есть ошибочное мнение среди веб-разработчиков, что CSS анимация — единственный производительный способ анимирования в сети. Этот миф принудил много разработчиков отказаться от основанной на JavaScript анимации в целом. Таким образом:

  1. Вынудили себя управлять сложным взаимодействием UI в таблицах стилей
  2. Блокировали себя в поддержке Internet Explorer 8 и 9
  3. Воздерживаются от возможности построения физики движения, которая возможна только в JavaScript

Проверка в реальных условиях: основанная на JavaScript анимация так же быстра, как и анимация, основанная на CSS — иногда еще быстрее. Анимация CSS имеет преимущество, как правило, только по сравнению с $.animate() jQuery, которая является, по сути, очень медленным. Однако библиотеки для анимации JavaScript, которые обходят jQuery, показывают невероятную производительность, избегая манипулирования DOM насколько это возможно. Эти библиотеки могут быть до 20 раз быстрее, чем jQuery.

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

Почему JavaScript?

CSS анимации удобны, когда вы должны сделать переходы свойств в свои таблицы стилей. Плюс, они показывают фантастическую производительность из коробки — без добавления библиотеки на страницу. Однако, когда вы используете переходы CSS, чтобы привести в действие богатый проект движения (подобное вы увидите в последних версиях IOS и Android), они становятся слишком трудными в управлении, или их функции просто сыпятся ошибками.

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

Примечание: Если вас интересует тема производительности, то можете почитать Джулиана Шапиро “CSS vs. S Animation: что быстрее?” и Джека Дойла: “Разрушение мифа: CSS Animations vs. JavaScript”. Для демо производительности, обратитесь к панели производительности в документации Velocity и  демо GSAP «Библиотека сравнения скорости».

Velocity и GSAP

Две самых популярных библиотеки для JavaScript анимации — Velocity.js и GSAP. Обе работают с и без jQuery. При использовании этих библиотек совместно с jQuery, нет никакого ухудшения производительности, потому что они полностью обходят стек jQuery анимации.

Если jQuery присутствует на вашей странице, вы можете использовать Velocity и GSAP точно так же как и $.animate() jQuery. Например, $element.animate({ opacity: 0.5 }); просто становится $element.velocity({ opacity: 0.5 }).

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

1
2
3
4
5
/* Работа без jQuery */

Velocity(element, { opacity: 0.5 }, 1000); // Velocity

TweenMax.to(element, 1, { opacity: 0.5 }); // GSAP

Как видно Velocity сохраняет тот же синтаксис что и $.animate ()  jQuery, даже когда это используется без jQuery; просто сместите все параметры вправо на одну позицию, чтобы создать место для передачи в предназначенных элементах в первой позиции.

GSAP, напротив, использует объектно-ориентированный API проект, а также удобные статические методы. Так, вы можете получить полный контроль над анимациями.

В обоих случаях вы больше не анимируете объект элемента jQuery ,а скорее необработанный DOM узел. Как напоминание, вы получаете доступ к необработанным DOM узлам при помощи document.getElementByIDdocument.getElementsByTagName, document.getElementsByClassName или document.querySelectorAll (который работает так же к селекторному механизму jQuery). Мы будем работать с этими функциями в следующем разделе.

Работа без jQuery

(Примечание: если вы нуждаетесь в базовом учебнике для начинающих в работе с $.animate()  jQuery, обратитесь к первым нескольким разделам в документации Velocity.)

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

1
2
3
4
5
document.querySelectorAll("body"); // Получите элемент body
document.querySelectorAll(".squares"); // Получите все элементы с класса "square"
document.querySelectorAll("div"); // Получите все отделения
document.querySelectorAll("#main"); // Получите элемент с id "main"
document.querySelectorAll("#main div"); // Получите div содержащие "main"

Как показано вы просто передаете querySelectorAll CSS селектор (те же селекторы, которые Вы использовали бы в своих таблицах стилей), и он возвратит все соответствующие элементы в массив. Следовательно, вы можете сделать это:

1
2
3
4
5
/* Получите все элементы div. */
var divs = document.querySelectorAll("div");
/* Анимируйте все div сразу. */
Velocity(divs, { opacity: 0.5 }, 1000); // Velocity
TweenMax.to(divs, 1, { opacity: 0.5 }); // GSAP

Поскольку мы больше не присоединяем анимации к  объектам элемента jQuery, вы можете задаться вопросом, как мы можем объединить анимации в цепочку:

1
2
3
$element // объект элемента jQuery
 .velocity({ opacity: 0.5 }, 1000)
 .velocity({ opacity: 1 }, 1000);

В Velocity вы просто вызываете анимации одну за другой:

1
2
3
/* Эти анимации автоматически становятся цепочкой. */
Velocity(element, { opacity: 0.5 }, 1000);
Velocity(element, { opacity: 1 }, 1000);

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

(Подсказка: С пакетом Velocity UI вы можете создать свои собственные анимации мультивызова и дать им пользовательские имена, которые сможете использовать в дальнейшем как первый параметр Velocity. См. UI Pack документацию Velocity для получения дополнительной информации.)

Velocity вызов-обработки-за-один-раз, обладает огромным преимуществом: если вы будете использовать promises со своими Velocity анимациями, то каждый Velocity вызов возвратит действенный promise объект. Можно узнать больше о работе с promises в статье Джейка Арчибальда. Они невероятно сильны.

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

1
2
3
4
5
var tl = new TimelineMax();
/* GSAP вставляет промежуточные кадры в цепочку по умолчанию, но вы можете указать точные точки вставки в сроки, в том числе относительное смещение. */
tl
 .to(element, 1, { opacity: 0.5 })
 .to(element, 1, { opacity: 1 });

Удивительность JavaScript: Workflow

Анимация является по сути экспериментальным процессом, в котором необходимо играть с timing и easing для получения правильного ощущения, в котором нуждается приложение. Конечно, даже если вы будете считать дизайн прекрасным, клиент будет часто запрашивать нетривиальные изменения. В этих ситуациях управляемый workflow становится важным.

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

Однако базовый недостаток API ключевых кадров — в том, что вы должны определить разделы в процентах, который не интуитивен. Например:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@keyframes myAnimation {
 0% {
 opacity: 0;
 transform: scale(0, 0);
 }
 25% {
 opacity: 1;
 transform: scale(1, 1);
 }
 50% {
 transform: translate(100px, 0);
 }
 100% {
 transform: translate(100px, 100px);
 }
}

#box {
 animation: myAnimation 2.75s;
}

Что происходит, если клиент просит, чтобы вы сделали translateX анимацию на секунду длиннее?  Это требует восстановления математики и изменения всех (или большинства) процентов.

У Velocity есть свой UI пакет, чтобы иметь дело со сложностью мультианимации, и GSAP предлагает nestable временные шкалы. Эти функции допускают полностью новые возможности потока операций.

Но давайте прекратим проповедь о потоке операций и погрузимся в забавные примеры анимации.

Удивительность JavaScript: физика

Много мощных эффектов достижимы исключительно через JavaScript. Давайте исследуем некоторые анимации запускающиеся с физической основой.

Утилита физики в проекте движения наталкивается на базовый принцип того, что делает для UX: интерфейсы, которые естественно плывут от ввода пользователя — другими словами, интерфейсы, которые придерживаются движения подобного реальному миру.

GSAP предлагает физики плагины, которые адаптируются к ограничениям пользовательского интерфейса. Например, ThrowPropsPlugin отслеживает динамическую скорость пальца пользователя или мыши, и когда пользователь отпускает, ThrowPropsPlugin выбирает соответствующую скорости и заставляет элемент естественно остановиться. Получающаяся анимация — стандартный промежуточный кадр, который может управляться временем (приостановленный, инвертированный, и т.д.):

Velocity предлагает тип упрощения на основе физики упругости. Обычно с упрощением опций вы передаете в именованном типе упрощения; например, ease, ease-in-out или easeInOutSine. С физикой упругости вы передаете массив с двумя элементами, состоящий из силы и значений трения (в скобках ниже):

1
Velocity(element, { left: 500 }, [ 500, 20 ]); // 500 натяжение, 20 трение

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

Удивительность JavaScript: скроллинг

В Velocity вы можете позволить пользователю прокрутить браузер к краю любого элемента, передавши scroll как первый параметр Velocity (вместо карты свойств). Команда scroll ведет себя тождественно стандартному Velocity вызову;  можно выбрать варианты и можно поставить в очередь.

1
Velocity(element, "scroll", { duration: 1000 };

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

У GSAP есть ScrollToPlugin, который предлагает подобную функциональность и может автоматически оставить управление, когда пользователь взаимодействует с полосой прокрутки.

Удивительность JavaScript: реверс

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

В Velocity, передайте reverse как первый параметр Velocity:

1
2
// Reverse значения по умолчанию к опциям последнего вызова, которые вы можете расширить
Velocity(element, "reverse", { duration: 500 });

Щелкните по вкладке “JS”, чтобы увидеть код, который приводит в действие этот пример:

В GSAP Вы можете сохранить ссылку на объект анимации, затем вызвать его reverse() метод в любое время:

1
2
var tween = TweenMax.to(element, 1, {opacity:0.5});
tween.reverse();

Удивительность JavaScript: преобразование управления

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

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

И Velocity и GSAP позволяют индивидуально анимировать преобразовываете компоненты:

1
2
3
4
5
6
7
8
9
10
11
// Velocity
/* First animation */
Velocity(element, { translateX: 500 }, 1000);
/* Trigger a second (concurrent) animation after 500 ms */
Velocity(element, { rotateZ: 45 }, { delay: 500, duration: 2000, queue: false });

// GSAP
/* First animation */
TweenMax.to(element, 1, { x: 500 });
/* Trigger a second (concurrent) animation after 500 ms */
TweenMax.to(element, 2, { rotation: 45, delay: 0.5 });

Подведение итогов

  • По сравнению с CSS анимацией у JavaScript  анимации есть лучшая поддержка браузера и больше функций, и это обеспечивает более управляемый поток операций для последовательностей анимации.
  • Анимация в JavaScript не влечет за собой принесение скорости в жертву (или аппаратное ускорение). И Velocity и GSAP поставляют скорость и аппаратное ускорение. Никакого смешения с null-transform хаками.
  • Вы не должны использовать jQuery, чтобы использовать в своих интересах преданные библиотеки анимации JavaScript. Однако, если вы это сделаете, то вы не будете жертвовать производительностью.

ЗАКЛЮЧИТЕЛЬНОЕ ПРИМЕЧАНИЕ

Обратитесь к Velocity и GSAP документации, чтобы освоить JavaScript анимацию.

По материалам: www.smashingmagazine.com

Подписывайтесь на обновления

Читайте RSS ленту

Комментарии

Добавить комментарий