Статьи

GreenSock для начинающих (часть 2): график GSAP

Анимация DOM с помощью GreenSock (GSAP), часть 2

Цель этой второй части GreenSock для начинающих — познакомить вас с TimelineMax от GreenSock. Вы будете учиться:

  • Зачем вам нужен график
  • Как включить несколько анимаций в хронологию
  • Как упаковать несколько временных шкал в функции и вложить их в основную временную шкалу для большей гибкости.

К концу этого урока вам будет удобно работать с временной шкалой GreenSock, чтобы манипулировать и полностью контролировать нескольких подростков.

Читать современный JavaScript
Будьте в курсе развивающегося мира JavaScript

Для ознакомления с основами GreenSock, в том числе с тем, как работать с TweenMax для упорядочивания и создания простых анимаций, перейдите к части 1 этой статьи, состоящей из нескольких частей.

Статьи GreenSock являются частью серии Beyond CSS: библиотеки динамической анимации DOM . Вот что я освещал в предыдущих статьях:

  • Анимация DOM с помощью Anime.js затрагивает вопрос о том, как наилучшим образом использовать анимацию в Интернете и когда вы можете рассмотреть возможность использования библиотеки анимации JavaScript вместо анимации только с CSS. Затем он фокусируется на Anime.js, бесплатной и легкой библиотеке анимации JavaScript
  • Забавные анимационные эффекты с KUTE.js знакомят вас с KUTE.js, бесплатной и многофункциональной библиотекой анимации JavaScript
  • Сделайте ваш сайт интерактивным и увлекательным с Velocity.js (без jQuery) показывает, как использовать Velocity.js, надежную бесплатную библиотеку анимации с открытым исходным кодом, для создания качественных веб-анимаций
  • GreenSock для начинающих: учебник по веб-анимации (часть 1) представляет собой обзор GreenSock, также известный как GSAP (платформа анимации GreenSock), где я обсуждаю модули библиотеки и модель лицензирования. Я также покажу вам, как кодировать простую анимацию движения, последовательности анимации и потрясающую анимацию с помощью GSAP TweenMax.

Зачем вам нужна временная шкала GreenSock для кодирования веб-анимации?

В части 1 вы узнали, как добавлять различные анимации к элементу или нескольким элементам, создавая несколько независимых анимаций и координируя их время со свойством delay каждой анимации.

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

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

Возьмите этот простой пример с двумя подростками. Вот что происходит:

  • Твин 1: форма круга увеличивается и сжимается при вращении по осям X и Y
  • Твин 2: всплывает какой-то текст.

Фрагмент GSAP, который заставляет его работать, выглядит следующим образом:

 // scale down the text // and hide it before the animation begins TweenMax.set('.example__title', { scale: 0.2, autoAlpha: 0 }); // scale the circle shape down before // the animation begins TweenMax.set('.example__ball', { scale: 0.2 }); // tween 1 TweenMax.to('.example__ball', 0.5, { rotationX: 360, rotationY: 180, scale: 1, ease: Elastic.easeIn.config(2, 1) }); // tween 2 TweenMax.to('.example__title', 0.5, { autoAlpha: 1, scale: 1, ease: Back.easeOut.config(4) }); 

Как видите, обе анимации происходят одновременно, что не является желаемым эффектом:

Если вы хотите, чтобы текст появлялся только тогда, когда фигура перестала вращаться, вам нужно добавить соответствующую задержку для tween2, например так:

 // tween 2 TweenMax.to('.example__title', 0.5, { // rest of the code here delay: 0.6 }); 

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

Именно тогда вы будете очень рады узнать, что GSAP обеспечил вас надежными и гибкими TimelineLite и TimelineMax , которые включены в TweenMax.

Координация нескольких анимаций с временной шкалой GSAP

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

В качестве первого шага на временной шкале GreenSock попробуйте разместить анимацию в фрагментах выше внутри временной шкалы.

Вот как выглядит код:

 // instantiate TimelineMax const tl = new TimelineMax(); // scale down the text // and hide it before the animation begins tl.set('.example__title', { scale: 0.2, autoAlpha: 0 }) // scale the circle shape down before // the animation begins .set('.example__ball', { scale: 0.2 }) // tween 1: rotate shape on X and Y axis // scale it up to its regular dimensions // add a fun ease .to('.example__ball', 0.5, { rotationX: 360, rotationY: 180, scale: 1, ease: Elastic.easeIn.config(2, 1) }) // tween 2: make text appear and // scale it up to its regular size // add a fun ta-da ease .to('.example__title', 0.5, { autoAlpha: 1, scale: 1, ease: Back.easeOut.config(4) }); 

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

Приведенный выше фрагмент кода создает экземпляр TimelineMax с именем tl . Вы можете выбрать любое имя, которое вам нравится, это не повлияет на действительность вашего кода.

Получив свой экземпляр, вы можете использовать большинство методов, с которыми вы уже знакомы из части 1, например to() , from() , fromTo() и т. Д.

Приведенный выше код начинается с настройки нескольких значений для ваших элементов, прежде чем любая анимация начнет использовать set() . Так же, как вы использовали set() с TweenMax , вы можете использовать тот же метод с временной шкалой для достижения тех же целей, т. Е. Устанавливать значения свойств ваших элементов так, чтобы изменение вступало в силу немедленно, без изменения во времени, что является типичным анимации. Вы можете прочитать больше об использовании set() на странице выделенных документов .

Остальная часть кода не отличается от того, что вы ранее писали с использованием TweenMax, с той лишь разницей, что теперь вы объединяете методы TimelineMax. Как вы можете видеть, синтаксис GSAP остается последовательным во всех своих реализациях, что, безусловно, помогает процессу обучения.

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

TimelineMax позиционный параметр GreenSock

Быстро и правильно работать с подростками — это хорошо. Однако что, если вы хотите, чтобы один элемент анимировался всего за полсекунды до или через пару секунд после завершения предыдущей анимации? Все это без необходимости перенастраивать другие значения в общей анимации.

Вот где появляется параметр position . Этот параметр добавляется после объекта vars {} с использованием относительного приращения ( -=0.5 , +=2 ).

Добавление -=1 запускает анимацию движения за 1 секунду до окончания предыдущей анимации на временной шкале, в то время как +=1 запускает анимацию движения через 1 секунду после окончания предыдущей анимации на временной шкале.

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

Вот простой пример:

 .to(box1, 1, { rotation: 45, transformOrigin: 'center bottom', ease: Elastic.easeOut }) .to(box2, 1, { rotation: -45, transformOrigin: 'center bottom', ease: Elastic.easeOut }) 

Фрагмент выше показывает два элемента, вращающихся в противоположных направлениях внутри временной шкалы.

Без параметра position box2 начнет анимацию, как только box1 завершит анимацию.

Чтобы обе анимации работали одновременно, добавьте запятую после закрывающей фигурной скобки во второй анимации и параметр позиции '-=1' , например, так:

 .to(box1, 1, { // code here }) .to(box2, 1, { // code here }, '-=1') //position parameter 

Поскольку первый анимационный ролик длится 1 секунду, параметр позиции '-=1' будет ожидать анимацию на 1 секунду, что приведет к одновременному срабатыванию обеих анимаций.

Вот код выше в контексте более длинной анимации с использованием параметра position.

Использование меток в качестве значения для параметра положения

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

Использование меток делает ваш код более читабельным, за что вы будете благодарны за более сложные анимации.

Всякий раз, когда вам нужна контрольная точка для синхронизации ваших подростков на временной шкале, просто добавьте метку с некоторым значимым текстом, используя метод .add() как TimelineLite, так и TimelineMax:

 tl.add('nameoflabel'); 

Затем используйте метку в качестве параметра позиции:

 // move element horizontally 100px tl.to(element, 0.5, { x: 100 }) .add('go') // add a label // move element vertically 100px // with reference to the 'go' label .to(element, 1, { y: 100 }, 'go'); // rotate otherElement // with reference to the 'go' label .to(otherElement, 0.5, { rotation: 360 }, 'go'); 

В приведенном выше фрагменте элемент перемещается на 100 пикселей вправо. Как только эта анимация заканчивается, анимация element и anotherElement происходит одновременно, поскольку они оба запускаются со ссылкой на метку go (просто присвойте меткам имя, которое имеет смысл в контексте вашей анимации).

Вы также можете использовать метки с относительными значениями. Например, если вы хотите, чтобы otherElement запускался через 2 секунды после элемента , используйте это вместо параметра позиции: 'go+=2' .

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

Вы можете узнать больше о параметре позиции на этой специальной странице на сайте GSAP .

Мастер-сроки с GreenSock и сохраняя ваш код организованным

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

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

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

Вот как выглядит вложенная временная шкала:

 // timeline-based animation inside a function function partOne() { // timeline instance const tl = new TimelineMax(); // add your tweens to the timeline as usual tl.to(myElement, 0.5, { rotation: 90, ease: Back.easeOut }) .to(otherElement, 1, { // more code here }); // return the timeline instance return tl; } // create a new timeline instance const master = new TimelineMax(); // add your function and a label to it master.add(partOne(), 'part1'); 

Приведенный выше фрагмент демонстрирует анимацию на временной шкале, спрятанную в своей собственной функции. Вы можете назвать функцию так, чтобы она описывала этот фрагмент анимации или просто partOne , sceneOne и т. Д., Что бы ни имело для вас больше смысла. Затем вы создаете экземпляр GSAP TimelineLite или TimelineMax, добавляете свою анимацию, как вы уже сделали, и возвращаете экземпляр временной шкалы : return tl .

Наконец, вы создаете свой основной экземпляр временной шкалы и используете .add() для включения вашей функции, чтобы убедиться, что функция .add() (обратите внимание на квадратные скобки в имени функции) .

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

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

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

Хитроумные анимационные трюки GreenSock

У GreenSock есть несколько хитрых хитростей, которые облегчат вам жизнь веб-аниматора.

Вот как.

Как приостановить все ваши анимации GSAP при загрузке страницы

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

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

 const tl = new TimelineMax({ paused: true }); 

Точно так же вы можете приостановить вложенные временные шкалы одним ударом, приостановив основную временную шкалу:

 const master = new TimelineMax({ paused: true }); 

Как играть, приостанавливать, перезапускать и реверсировать несколько роликов GSAP в целом

В части 1 вы узнали, как управлять отдельными подростками с помощью play() , pause() , reverse() , restart() и resume() .

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

Например, чтобы воспроизвести всю последовательность анимации внутри временной шкалы, напишите:

 tl.play(); 

Вы можете увидеть, как restart() работает с временной шкалой для реализации функциональности кнопки «Воспроизведение» в некоторых демонстрационных версиях CodePen выше.

Как замедлить / ускорить несколько анимаций GSAP одновременно

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

 tl.timeScale(0.3); 

или, если у вас есть вложенные сроки:

 master.timeScale(0.3); 

Метод .timeScale() масштабирует время анимации. Значение 1 устанавливает время для нормальной скорости (по умолчанию), от 0,5 до половины нормальной скорости, 2 для удвоения нормальной скорости и т. Д.

Почему это полезно? Потому что будут моменты, когда вам нужно будет проверять, как выглядит ваша анимация, когда вы играете немного быстрее, или вы просто хотите тщательно проверить определенные анимации в супер медленном движении. С .timeScale .timeScale() вы сможете сделать это, не тратя время на каждую временную шкалу.

Как воспроизвести анимацию из указанного места на временной шкале с помощью GSAP

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

Входит .seek() , ваш лучший друг. С .seek() метода .seek() и использования меток вы сможете запускать анимацию с любой точки временной шкалы. То же самое касается вложенных временных шкал внутри основной временной шкалы, поэтому я добавил метку с именем part1 к основной временной шкале в предыдущем разделе выше.

В частности, вот основная временная шкала с 3-мя вложенными временными шкалами:

 const master = new TimelineMax(); master.add(partOne(), 'part1') .add(partTwo(), 'part2') .add(partThree(), 'part3'); 

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

 master.seek('part2'); 

Если, с другой стороны, вы хотите запустить анимацию через 3 секунды после ‘part2’, используйте метку с параметром относительной позиции:

 master.seek('part2+=3'); 

Круто, ваша анимация начинается именно в тот момент, когда вы хотите внести свои коррективы, и вы можете выполнить любое количество тестов, не выпуская свои волосы.

Вывод

В этой статье показано, как работать с TimelineMax () GreenSock и с вложенными временными шкалами. Должно быть понятно, какой огромный контроль эта гибкая и надежная библиотека временной шкалы может дать вам при создании веб-анимации, и насколько быстро можно собрать сложную последовательность анимаций с ее помощью.

Оставайтесь с нами для части 3 этой мини-серии, посвященной GreenSock, где вы будете экспериментировать с некоторыми замечательными плагинами GSAP Premium на CodePen.

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

Тогда почему бы не создать свои собственные анимации и не поделиться ими со всеми нами в комментариях?