Greensock: анимация на JavaScript

    Недавно я писал, что Greensock, прекрасная библиотека для скриптовой анимации на Flash, теперь поддерживает и JavaScript. В этой статье я продемонстрирую основы работы с GSAP v12 (beta). Результат будет примерно таким:


    Сразу оговорюсь, что графику и идею для примера я взял из документации $fx(), ведь кто из нас откажется проанимировать НЛО? :)

    Скрипты


    Сначала подключим необходимые скрипты:
    <script type="text/javascript" src="js/jquery.min.js"></script><br><script type="text/javascript" src="js/TweenMax.min.js"></script><br><script type="text/javascript" src="js/TimelineMax.min.js"></script><br><script type="text/javascript" src="js/easing/EasePack.min.js"></script><br><script type="text/javascript" src="js/plugins/CSSPlugin.min.js"></script>


    Зачем столько?
    • JQuery нам нужен для того, чтобы выбирать элементы. Можно, конечно, и без него.
    • TweenMax (60 Kb) — это основная библиотека анимации. Есть ещё TweenLite (21 Kb), включающий только базовые возможности.
    • TimelineMax (16 Kb) — это основаная библиотека таймлайна. TimelineLite весит 9 Kb.
    • EasePack (5 Kb) — это набор эффектов анимации, контролирующих её характер, например, плавное замедление или «эластичное» подрагивание.
    • CSSPlugin (14 Kb) — позволяет анимировать CSS-свойства HTML-объектов, как по одному, так и целыми пачками классами.


    Анимация


    Можем начинать анимировать. Базовый синтаксис такой:
    • TweenMax.from(объект, длительность, значение) — от заданного значения к текущему
    • TweenMax.to(объект, длительность, значение) — от текущего значения к заданному
    • TweenMax.fromTo(объект, длительность, значение1, значение2) — от заданного значения к заданному (чтобы точно не ошибиться :)


    В качестве объекта может выступать любой DOM-элемент. Самый простой способ — получить его через селектор JQuery. Время указывается в секундах. Значение указывается как объект, например {value: 500} или {width: 300}. Удобная фишка: если взять значение в кавычки, изменение будет относительным, а не абсолютным. Наглядно:
    TweenMax.to( $('#sample'), 1, {value: 300} ); // за 1 секунду значение станет равно 300 единицам<br>TweenMax.to( $('#sample'), 1, {value: '300'} ); // за 1 секунду значение увеличится на 300 единиц

    Сравнить оба варианта в демо 1

    Анимация CSS-свойств происходит чуть сложнее (главное — не запутаться в фигурных скобках):
    TweenMax.to( $('#bg1'), 2, {css: {background-position: '-300px'}} );

    Можно указывать свойства по одному, а можно указать целый класс. Тогда GSAP сравнит оба класса (текущий и заданный), найдет отличающиеся свойства и проанимирует их все. Как обычно, цена удобства — скорость выполнения.

    Дополнительно можно указать количество повторений анимации (-1 означает бесконечный повтор):
    TweenMax.to($('#bg1'), 2, {css: {background-position: '-300px'}}, repeat: -1)


    По умолчанию, все анимации происходят с красивым замедлением в конце. Если требуется другой эффект (или никакого), это нужно указать явным образом:
    TweenMax.to($('#ufo'), 2, {width: 300}, ease: Linear.easeNone)


    Воспользуемся полученными знаниями и сделаем бесконечно анимированный фон с блекджеком и параллаксом:
    TweenMax.to($('#bg1'), 9, {css:{backgroundPosition: "-314 0px"}, repeat:-1, ease:Linear.easeNone});<br>TweenMax.to($('#bg2'), 18, {css:{backgroundPosition: "-269 30px"}, repeat:-1, ease:Linear.easeNone});

    Посмотреть демо 2

    Спрайты


    С помощью спрайтовой анимации включим габаритные огни на НЛО. Наш спрайт состоит из 4 кадров:


    Специально для этой цели был придуман SteppedEase, анимирующий не плавно, а наоборот — рывками. Задав количество рывков, равное количеству кадров, мы получим красивую анимацию:
    TweenMax.to($('#ufo'), 0.2, {css:{backgroundPosition :"340 0px"}, ease:SteppedEase.config(4), repeat:-1});

    Посмотреть демо 3

    Таймлайн


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

    * Все примеры кода подсвечены с помощью Source Code Highlighter.
    Поделиться публикацией

    Похожие публикации

    Комментарии 38

      +47
      Я один безрезультатно кликнул на кнопки «Play 1» и «Play 2»? :)
        +18
        Ох… :) Ну вот тогда, восстанавливайте душевное равновесие: goo.gl/sfZcy
          +2
          Вот спасибо :)
          0
          Не один! Я тоже вклубе :)
            –4
            в вк пересидели?
            0
            Нет.
              0
              Меня терзали сомнения )) но на Плай 1 я таки жамкнул )
              +1
              У вас здесь ошибка в участке "width: 300px"

              TweenMax.to($('#ufo'), 2, {width: 300px}, ease: Linear.easeNone)</blockquote>
                +1
                Спасибо, поправил. Должно быть {width: 300}. Работает с теми элементами, у которых есть не-CSS аттрибут width, например с картинками (IMG).
                  +2
                  Молодец. При всей простоте пример получился яркий и доступный.
                –10
                Канвас это конечно хорошо, поболоватся можно и нужно, но в каких-то более менее вменяемых проэктах — кроме как нарисовать график — он, к сожалению мало применим из-за свей медлительности :(
                  +7
                  Во-первых, в топике нету ни слова про канвас.
                  Во-вторых, он медлителен только если бездумно перерисовывать каждый кадр всё, что есть на поле. На данный момент html5-canvas коммерчески-приемлим.
                    +3
                    А где вы тут canvas увидели? На всякий случай, автор обычные dom-элементы анимирует.
                    К слову о canvas, он далеко не для отрисовки графиков предназначен, благо здесь и без него инструментов хватает.
                      +1
                      Вы просто не умеете его готовить ©
                        +3
                        Да, да, не разглядел с самого начала, приношу извинения, а по поводу канваса — значит мне не попадались годные проекты.
                        • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          Прикольный баг: при перемещении объекта background-анимация сбрасывается в начальное значение, в итоге габаритные огни «глючат». Когда тарелка стоит на месте — все ок.
                            0
                            наконец-то)
                              –3
                              только… только это нихрена не подготовлено и куда не сунься — костыли. Куда не сунься нужна полупрозрачность а она в png24 а это… не малый объем…
                                +3
                                Какие костыли? И при чем тут PNG, если речь идёт об анимировании любых DOM-элементов? Хотите — анимируйте GIFы, или JPEGи, или просто элементы HTML, или на канвасе рисуйте статику. Да хоть флэшки по экрану двигайте.
                              +3
                              по большей части нужно только для полной кроссплатформенности, да и то — что-то есть сомнения в полной адекватности и стабильности.

                              Лично мое мнение, что лучше стараться анимировать в CSS3 Animate. Причины:
                              1) CSS в данном случае работает как макроязык анимации.(тем не менее для сложной анимации можно и JS присобачить, как контроллер точек выполнения), что дает определенный порядок при проектировании.
                              2) JavaScript у нас однопоточный, и в современных сайтах у него другой работы полно, а не только анимацию строгать. А так, CSS не мешает JavaScript-у работать
                              3) Зная, как иногда народ увлекается такими анимашками и по нескольку штук их пичкают, грузить это будет неприятно.(если кто будет говорить, про быстрые браузеры и мощные компы — то вспомните, что у нынешнего пользователя, обычно открыто по двадцать вкладок. И в каждом такая дрянь будет работать, если правда не используется requestAnimationFrame)
                              4) По наблюдениям, скажу честно. Когда клиенты видят эти анимации в IE и видят лаги, обвиняют они разработчика сайта в тормозах, а не старый свой браузер. В таком случае лучше уж для IE засунуть простую gif-ку. Пусть некрасиво, зато не тормозит.
                              5) CSS3 Animation (и transform) в chrome и firefox (в opera только с 12-ой), все правила работают с частичным использованием gpu ускорения. А вот с работой DOM модели, только CPU загрузите.
                              6) Можно впринципе заюзать и canvas. Как тут правильно писали — если правильно с ним работать, можно отличные выжать результаты.
                              7) А для графиков — как тут кто-то писал, я бы вообще предлагал посмотреть в сторону SVG.

                              В общем это лично мое мнение, которое построилось из личного опыта.

                              К чему я это написал? Я не уверен в поддержке этих библиотек. Не уверен в стабильной скорости анимации, основанной на данной библиотеке, в перегруженных всякой чепухой страницах И поэтому в коммерческих проектах не рискнул бы использовать эту библиотеку, и выше я описал почему. Хотя позднее, возможно, свою нишу эта библиотека найдет.
                              0
                              я ни слова не сказал про другие JS библиотеки. Я сравнил с CSS. И сравнил не в одиночном контексте, где анимации не будут мешать другие скрипты, а в проектах, где помимо анимации, есть еще куча всяких грузящих элементов.
                                +2
                                1. CSS-анимации выполняются в том же потоке, что и JS. Т.е. если завис JS, то CSS-анимации тоже зависнут
                                2. CSS-анимации не обязательно быстрее, чем изменение свойств через DOM
                                3. Период запуска таймера в неактивной вкладке во всех современных браузерах уменьшается с 4-20мс до 1000 мс, так что они практически не будут грузить при работе в закрытой вкладке.
                                  0
                                  давайте возьмем в пример работу google chrome.
                                  1) В случае если виснет, это понятно — т.к. браузер ждет ответа от скрипта. Это логично.

                                  2) CSS — это по факту тоже изменение DOM модели. Но только во первых, она использует не V8 движок, а webkit, а он по факту работает с отрендеренной моделью(что логично), что уже само по себе быстрее.
                                  Можно заметить что само свойство ноды не меняется до окончания подблока анимации, но при этом визуальная часть изменяется. И кстати значения getComputedStyle тоже. В хроме есть еще и диспетчет задач, где отлично показывается, где, чья память используется. При CSS анимации — JS не задействуется вообще.
                                  Хотя есть и вправду одно исключение. Зависит от простоты вычисления новых координат, и как они вычисляются. Есть разработчики браузера сделали «абы как», то тут уже другой разговор.

                                  3) 3 пункт если вдаться в подробности, режет частично 2. Придется синхронизировать время. Одно дело когда известны промежутки времени, соответственно дельту X и дельту Y можно заранее просчитать. А вот если время исполнения плавающее — это совсем другая ситуация. Синхронизировать можно — но это еще одна, хоть и небольшая, но все-таки нагрузка. Но опять же все зависит от реализации алгоритмов в движках браузеров. Это к теме оптимизации расчета об]ектов в каждом «кадре»

                                  4) Я может неправильно выразился, но я имел ввиду не более быструю анимацию, а более легковесную по ресурсопотреблению, из вариантов, которые мы обсуждаем.

                                  5) Предлагаю трезво спор на эту тему не продолжать. Тема изъезженная. Это долго и тянет на отдельный пост.
                                –2
                                Стоило убивать флэш, чтобы в настоящем затрачивать подобные усилия и достигать таких результатов? Вопрос риторический…
                                  +3
                                  Перед вами — открытые, бесплатные, непроприетарные технологии. В отличие от флэша.
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      0
                                      «Час или три» — обоснуйте. Написать идентичную анимацию на GS во флеше или на JS у меня займет ровно одно и то же время, т.к. синтаксис идентичный.
                                  0
                                  TweenMax.to( $('#sample'), 1, {value: 300} ); // за 2 секунды значение станет равно 300

                                  Почему две секунды? В параметрах одна же. Прикол в том, что по ощущению это длится действительно две секунды.
                                  Не понимать :'(
                                    +1
                                    А вы щёлкайте своим внутренним метрономом не «раз-два», а «ноль-один» («ноль» в момент начала действия). И получится одна секунда как раз :)
                                      +1
                                      Извините. Исправил. Анимация в демо длится ровно 1 секунду, а комментарий остался от старой версии.
                                      0
                                      Ивенты поддерживаются? Можно навесить хандлер на элемент графики?
                                        0
                                        Можно, onStart, onComplete и т.п.
                                        0
                                        Я не силен в JS и CSS, поэтому если надо, то беру какие-нить интересные готовые решения (типа этого) и переделываю под свои нужды.

                                        Поэтому (может быть и тупой) вопрос: сравнительно $fx() (откуда была взята идея примера) Ваш способ чем хорош/плох?
                                        Я особо не всматривался, но визуально что там что тут работает примерно одинаково все.

                                        Спасибо
                                          0
                                          В данном случае — примерно одинаково. В реальной работе пригодится более широкий функционал, высокая производительность, отличная документация и поддержка. Плюс если кто работал с GS на флэше (как я), ничего нового изучать не надо. Можно даже существующий AS-код реюзать.
                                          0
                                          Удалите третий кадр в спрайте, анимация тарелки не будет дергаться.
                                            0
                                            Вот тут вроде ничего не дергается с тем же спрайтом.

                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                          Самое читаемое