Создание анимации джава скрипт лекция. Создание анимации в JavaScript. Сложные варианты step

Здравствуйте! В этом уроке рассмотрим анимации в JavaScript. JavaScript-анимация применяется где не подходит .

Например, анимация по сложной траектории, с специальной временной функцией, выходящей за рамки кривых Безье, на canvas. Еще её используют для анимации в старых IE. Хотя надо сказать, что для экономии ресурсов, особенно мобильных устройств предпочтительно использовать CSS анимации.

Функция setInterval

Сначала давайте дадим определение анимации. Итак с точки зрения HTML/CSS, анимация – это постепенное изменение стиля DOM-элемента. Например, увеличение координаты style.left от 0px до 100px сдвигает элемент влево.

Если увеличивать свойство left от 0 до 100 при помощи метода , делая по 50 изменений в секунду, то это будет выглядеть как плавное перемещение. Тот же принцип, что и в киноиндустрии: для анимации достаточно 24 или больше вызовов setInterval в секунду.

Код для анимации выглядит так:

Var fps = 50; // 50 кадров в секунду var timer = setInterval(function() { if (время вышло) clearInterval(timer); else немного увеличить left } , 1000 / fps)

Вот более полный пример кода анимации:

Var start = Date.now(); // сохранить время начала var timer = setInterval(function() { // вычислить сколько времени прошло с начала анимации var timePass = Date.now() - start; if (timePassed >= 2000) { clearInterval(timer); // конец через 2 секунды return; } // рисует состояние анимации, соответствующее времени timePass draw(timePassed); }, 20); // в то время как timePassed идёт от 0 до 2000 // left принимает значения от 0 до 400px function draw(timePass) { train.style.left = timePass / 5 + "px"; }

requestAnimationFrame

Если у вас не один такой setInterval, а несколько в разных местах кода, то браузеру нужно в те же 20 мс работать со страницей уже не один раз. А ведь кроме setInterval есть ещё другие действия, к примеру, прокрутка страницы, которую тоже надо нарисовать.

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

Гораздо лучше с точки зрения производительности – сгруппировать все перерисовки в одну и запускать их централизованно, все вместе.

Для этого в JavaScript-фреймворках, которые поддерживают анимацию, есть единый таймер:

SetInterval(function() { /* отрисовать все анимации */ }, 20);

Все анимации, которые запускает такой фреймворк, добавляются в глобальный общий список, и раз в 20 мс единый таймер проверяет его, запускает текущие, удаляет завершившиеся
Современные браузеры, кроме IE9-, поддерживают стандарт Animation timing, который представляет собой дальнейший шаг в этом направлении. Он позволяет синхронизировать все анимации со встроенными механизмами обновления страницы. То есть, сгруппированы будут не только наши, но и CSS-анимации и другие браузерные перерисовки.

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

Для этого используется функция requestAnimationFrame.

Синтаксис функции:

Var requestId = requestAnimationFrame(callback)

Такой вызов планирует запуск функции callback в ближайшее время, когда браузер сочтёт возможным осуществить анимацию.
Если запланировать в callback какое-то рисование, то оно будет сгруппировано с другими requestAnimationFrame и с внутренними перерисовками браузера.
Возвращаемое значение в requestId нужно для отмены запуска:

// отменить запланированное выше выполнение callback cancelAnimationFrame(requestId);

Функция callback получает один аргумент – время, прошедшее с начала загрузки страницы, результат вызова performance.now().

Как правило, запуск callback происходит очень скоро. Если у процессора большая загрузка или батарея у ноутбука почти разряжена – то пореже.

Если вы запустите этот код, то увидите промежутки между первыми 20 запусками requestAnimationFrame. Как правило, это 10-20 мс, но бывает и больше и меньше. Это оптимальная частота анимации с точки зрения браузера.

var prev = performance.now(); var times = 0; requestAnimationFrame(function measure(time) { document.body.insertAdjacentHTML("beforeEnd", Math.floor(time - prev) + " "); prev = time; if (times++ < 10) requestAnimationFrame(measure); })

Функция анимации на основе requestAnimationFrame:

// Рисует функция draw // Продолжительность анимации duration function animate(draw, duration) { var start = performance.now(); requestAnimationFrame(function animate(time) { // определить, сколько прошло времени с начала анимации var timePassed = time - start; // возможно небольшое превышение времени, в этом случае зафиксировать конец if (timePassed > duration) timePassed = duration; // нарисовать состояние анимации в момент timePassed draw(timePassed); // если время анимации не закончилось - запланировать ещё кадр if (timePassed < duration) { requestAnimationFrame(animate); } }); }

Структура анимации

На основе requestAnimationFrame можно соорудить и гораздо более мощную, но в то же время простую функцию анимации.

У анимации есть три основных параметра:

Duration Общее время, которое длиться анимация, в мс. Например, 1000. timing(timeFraction) Временная функция, которая, по аналогии с , будет по текущему времени вычислять состояние анимации.

Она получает на вход непрерывно возрастающее число timeFraction – от 0 до 1, где 0 означает самое начало анимации, а 1 – её конец.

Её результатом должно быть значение завершённости анимации, которому в CSS transitions на кривых Безье соответствует координата y.

Также по аналогии с transition-timing-function должны соблюдаться условия:

  • timing(0) = 0
  • timing(1) = 1…То есть, анимация начинается в точке (0,0) – нулевое время и нулевой прогресс и заканчивается в (1, 1) – прошло полное время, и процесс завершён.Например, функция-прямая означает равномерное развитие процесса: function linear(timeFraction) { return timeFraction; }
  • Её график:

  • Как видно, её график полностью совпадает с transition-timing-function: linear, и эффект абсолютно такой же.Есть и другие, более интересные варианты, мы рассмотрим их далее.
draw(progress) Функция, которая получает состояние завершённости анимации и рисует его. Значению progress=0 соответствует начальная точка анимации, progress=1 – конечная.

Именно эта функция и осуществляет, собственно, анимацию.

Например, может двигать элемент:

Function draw(progress) { train.style.left = progress + "px"; } Возможны в принципе любые варианты, анимировать можно что угодно и как угодно.

Временные функции

Выше мы видели самую простую, линейную временную функцию.

Рассмотрим примеры анимации движения с использованием различных timing.

В степени n

Вот еще один простой случай – progress в степени n. Частные случаи – квадратичная, кубическая функции и т.д.

Для квадратичной функции:

Function quad(progress) { return Math.pow(progress, 2) }

График квадратичной функции:

Увеличение степени влияет на ускорение. Например, график для 5-й степени:

Функция:

Function circ(timeFraction) { return 1 - Math.sin(Math.acos(timeFraction)) }

График:

Back: стреляем из лука

Эта функция работает по принципу лука: сначала мы «натягиваем тетиву», а затем «стреляем».

В отличие от предыдущих функций, эта зависит от дополнительного параметра x, который является «коэффициентом упругости». Он определяет расстояние, на которое «оттягивается тетива».

Function back(x, timeFraction) { return Math.pow(timeFraction, 2) * ((x + 1) * timeFraction - x) }

График для x = 1.5:

Отскок bounce

Представьте, что вы отпускаете мяч, он падает на пол, несколько раз отскакивает и останавливается.

Функция bounce делает то же самое, только наоборот: «подпрыгивание» начинается сразу.

Эта функция немного сложнее предыдущих и использует коэффициенты:

Function bounce(timeFraction) { for (var a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2) } } }

Упругая анимация

Эта функция зависит от дополнительного параметра x, который определяет начальный диапазон.

Function elastic(x, timeFraction) { return Math.pow(2, 10 * (timeFraction - 1)) * Math.cos(20 * Math.PI * x / 3 * timeFraction) }

График для x=1.5:

Реверсивные функции ease*

Итак, у нас есть коллекция временных функций.

Их использование называется «easeIn».

Иногда нужно показать анимацию в обратном режиме. Преобразование функции, которое даёт такой эффект, называется «easeOut».

easeOut

В режиме «easeOut», значение timing вычисляется по формуле: timingEaseOut(timeFraction) = 1 — timing(1 — timeFraction)

Например, функция bounce в режиме «easeOut»:

// обычный вариант function bounce(timeFraction) { for (var a = 0, b = 1, result; 1; a += b, b /= 2) { if (timeFraction >= (7 - 4 * a) / 11) { return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2); } } } // преобразователь в easeOut function makeEaseOut(timing) { return function(timeFraction) { return 1 - timing(1 - timeFraction); } } var bounceEaseOut = makeEaseOut(bounce);

Полный пример – отскок в bounceEaseOut теперь не в начале, а в конце (и это куда красивее):
На этом графике видно преобразование easeOut изменяет поведение функции:

Если есть анимационный эффект, такой как подпрыгивание – он будет показан в конце, а не в начале (или наоборот, в начале, а не в конце).

Красным цветом обозначен обычный вариант, а синим – easeOut.

  • Обычно анимируемый объект сначала медленно скачет внизу, а затем, в конце, резко достигает верха…
  • А после easeOut – он сначала прыгает наверх, а затем медленно скачет внизу.
easeInOut

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

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

If (timeFraction 1) timeFraction = 1; // текущее состояние анимации var progress = options.timing(timeFraction) options.draw(progress); if (timeFraction < 1) { requestAnimationFrame(animate); } }); }

Основные параметры:

  • duration – длительность анимации в мс.
  • timing – функция, которая определяет состояние анимации каждый кадр. Получает часть времени от 0 до 1, возвращает завершенность анимации от 0 до 1.
  • draw – функция, которая отрисовывает состояние анимации от 0 до 1.

Эту функцию можно улучшить, например добавить коллбэк complete для вызова в конце анимации.

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

Это же относится и к функции draw.

Такая реализация анимации имеет три основных области применения:

  • Нестандартные задачи и требования, не укладывающиеся в рамки CSS.
  • Поддержка IE9-.
  • Графика, рисование на canvas.
Задания

Can’t make the #ChromeDevSummit this year? Catch all the content (and more!) on the livestream, or join your peers for a CDS Extended event at a hosted location nearby. To learn more, check out the Chrome Dev Summit 2019 website .

CSS Versus JavaScript Animations

Paul is a Design and Perf Advocate

Evangelises Chrome and the mobile web in the Developer Relations team at Google.

There are two primary ways to create animations on the web: with CSS and with JavaScript. Which one you choose really depends on the other dependencies of your project, and what kinds of effects you"re trying to achieve.

TL;DR
  • Use CSS animations for simpler "one-shot" transitions, like toggling UI element states.
  • Use JavaScript animations when you want to have advanced effects like bouncing, stop, pause, rewind, or slow down.
  • If you choose to animate with JavaScript, use the Web Animations API or a modern framework that you"re comfortable with.

Most basic animations can be created with either CSS or JavaScript, but the amount of effort and time differs (see also CSS vs JavaScript Performance). Each has its pros and cons, but these are good guidelines:

  • Use CSS when you have smaller, self-contained states for UI elements. CSS transitions and animations are ideal for bringing a navigation menu in from the side, or showing a tooltip. You may end up using JavaScript to control the states, but the animations themselves will be in your CSS.
  • Use JavaScript when you need significant control over your animations. The Web Animations API is the standards-based approach, available today in most modern browsers. This provides real objects, ideal for complex object-oriented applications. JavaScript is also useful when you need to stop, pause, slow down, or reverse your animations.
  • Use requestAnimationFrame directly when you want to orchestrate an entire scene by hand. This is an advanced JavaScript approach, but can be useful if you"re building a game or drawing to an HTML canvas.

Alternatively, if you"re already using a JavaScript framework that includes animation functionality, such as via jQuery"s .animate() method or GreenSock"s TweenMax , then you may find it more convenient overall to stick with that for your animations.

Animate with CSS

Animating with CSS is the simplest way to get something moving on screen. This approach is described as declarative , because you specify what you"d like to happen.

Below is some CSS that moves an element 100px in both the X and Y axes. It"s done by using a CSS transition that"s set to take 500ms . When the move class is added, the transform value is changed and the transition begins.

Box { transform: translate(0, 0); transition: transform 500ms; } .box.move { transform: translate(100px, 100px); }

Besides the transition"s duration, there are options for the easing , which is essentially how the animation feels. For more information about easing, see The Basics of Easing guide.

If, as in the above snippet, you create separate CSS classes to manage your animations, you can then use JavaScript to toggle each animation on and off:

Box.classList.add("move");

Doing this provides a nice balance to your apps. You can focus on managing state with JavaScript, and simply set the appropriate classes on the target elements, leaving the browser to handle the animations. If you go down this route, you can listen to transitionend events on the element, but only if you’re able to forego support for older versions of Internet Explorer; version 10 was the first version to support these events. All other browsers have supported the event for some time.

The JavaScript required to listen for the end of a transition looks like this:

Var box = document.querySelector(".box"); box.addEventListener("transitionend", onTransitionEnd, false); function onTransitionEnd() { // Handle the transition finishing. }

In addition to using CSS transitions, you can also use CSS animations, which allow you to have much more control over individual animation keyframes, durations, and iterations.

Note: If you’re new to animations, keyframes are an old term from hand-drawn animations. Animators would create specific frames for a piece of action, called key frames, which would capture things like the most extreme part of some motion, and then they would set about drawing all the individual frames in between the keyframes. We have a similar process today with CSS animations, where we instruct the browser what values CSS properties need to have at given points, and it fills in the gaps.

You can, for example, animate the box in the same way with transitions, but have it animate without any user interactions like clicking, and with infinite repetitions. You can also change multiple properties at the same time:

Box { /* Choose the animation */ animation-name: movingBox; /* The animation’s duration */ animation-duration: 1300ms; /* The number of times we want the animation to run */ animation-iteration-count: infinite; /* Causes the animation to reverse on every odd iteration */ animation-direction: alternate; } @keyframes movingBox { 0% { transform: translate(0, 0); opacity: 0.3; } 25% { opacity: 0.9; } 50% { transform: translate(100px, 100px); opacity: 0.2; } 100% { transform: translate(30px, 30px); opacity: 0.8; } }

With CSS animations you define the animation itself independently of the target element, and use the animation-name property to choose the required animation.

If you want your CSS animations to work on older browsers, you will need to add vendor prefixes. Many tools can help you create the prefixed versions of the CSS you need, allowing you to write the unprefixed version in your source files.

Animate with JavaScript and the Web Animations API

Creating animations with JavaScript is, by comparison, more complex than writing CSS transitions or animations, but it typically provides developers significantly more power. You can use the Web Animations API to either animate specific CSS properties or build composable effect objects.

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

  • Фейерверк
  • Эффект затемнения
  • Сворачивание или разворачивание.
  • Переход на страницу или выход из страницы
  • Движения объектов

Вам может быть интересна существующая анимационная библиотека на основе JavaScript: Script.Aculo.us.

В этой статье представлено базовое представление о том, как использовать JavaScript для создания анимации.

JavaScript может использоваться для перемещения нескольких элементов DOM (, или любого другого элемента HTML) на страницах в соответствии с каким-либо шаблоном, определяемым логическим уравнением или функцией.

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

  • setTimeout(function, duration) – эта функция вызывает function после duration миллисекунд, начиная с момента вызова.
  • setInterval(function, duration) – эта функция вызывает function после каждой duration миллисекунды.
  • clearTimeout(setTimeout_variable) – эта функция вызывает очистку любого таймера, установленного функциями setTimeout().

JavaScript также может устанавливать несколько атрибутов объекта , включая его положение на экране. Вы можете установить атрибут top и left объекта, чтобы поместить его в любом месте на экране. Вот его синтаксис.

// Установите расстояние от левого края экрана. object.style.left = distance in pixels or points; или // Заданном расстоянии от верхнего края экрана. object.style.top = distance in pixels or points;

Ручная анимация

Итак, давайте реализуем одну простую анимацию с использованием свойств объекта DOM и функций JavaScript следующим образом. Следующий список содержит различные методы DOM.

  • Мы используем функцию JavaScript getElementById() для получения объекта DOM, а затем присваиваем ему глобальную переменную imgObj .
  • Мы инициализировали функциюinit() для инициализации imgObj, где мы установили ее атрибуты position и left .
  • Мы вызываем функцию инициализации во время загрузки окна.
  • Наконец, мы вызываем функцию moveRight(), чтобы увеличить левое расстояние на 10 пикселей. Вы также можете установить его на отрицательное значение, чтобы переместить его влево.
Пример

Попробуйте следующий пример.

Анимация в JavaScript

Нажмите кнопку ниже, чтобы переместить изображение вправо

Автоматическая анимация

В приведенном выше примере мы увидели, как изображение перемещается вправо с каждым щелчком. Мы можем автоматизировать этот процесс, используя функцию setTimeout() в JavaScript следующим образом:

  • Функция moveRight() вызывает функцию setTimeout() для установки позиции imgObj .
  • Мы добавили новую функцию stop(), чтобы очистить таймер, установленный функцией setTimeout(), и установить объект в его исходное положение.
Пример

Попробуйте следующий пример кода.

Анимация в JavaScript

Нажмите кнопки ниже, чтобы обработать анимацию

Ролловер с событием мыши

Вот простой пример, показывающий опрокидывание изображения с событием мыши.

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

  • Во время загрузки этой страницы оператор «if» проверяет наличие объекта изображения. Если объект изображения недоступен, этот блок не будет выполнен.
  • Конструктор Image() создает и предварительно загружает новый объект изображения с именем image1 .
  • Свойству src присваивается имя файла внешнего изображения, называемого /images/html.gif.
  • Аналогично, мы создали объект image2 и назначаем /images/http.gif этому объекту.
  • Символ # (хэш-знак) отключает ссылку, чтобы браузер не пытался перейти к URL-адресу при нажатии. Эта ссылка является изображением.
  • Обработчик события OnMouseOver вызывается, когда пользователь движет мышь на ссылке, и обработчик события onMouseOut вызывается, когда мышь пользователя отходит от линии (изображение).
  • Когда мышь перемещается по изображению, изображение изменяется с первого изображения на второе. Когда мышь перемещается от изображения, отображается исходное изображение.
  • Когда мышь будет удалена от ссылки, на экране появится исходное изображение html.gif.
Ролловер с событиями мыши

Наведите курсор на изображение, чтобы увидеть результат

Аннотация: Простой пример: метод угасания желтого цвета. Анимация с помощью библиотек JavaScript. Более сложный пример: перемещение и изменение размера. Переходы CSS.

Принцип в основе угасания состоит в том, что задается желтый цвет фона элемента угасания, а затем, за некоторую последовательность шагов его цвет возвращается к исходному. Поэтому, если исходный цвет фона был красный, то затем цвет задается желтым, затем оранжево-желтым, затем оранжевым, затем красно-оранжевым, и затем красным. Число использованных шагов определяет, насколько плавно происходит изменение цвета, а время между шагами определяет, как долго продолжается изменение цвета. При изменении цвета можно использовать полезный факт из CSS : цвет можно определить как тройку обычных чисел или как шестнадцатеричную строку. Поэтому #FF0000 (красный цвет) можно определить также как rgb(255,0,0) . Изменение от желтого цвета до красного за пять шагов означает, поэтому, переход от rgb(255,255,0) (желтый) к rgb(255,0,0) за пять следующих шагов:

rgb(255,255,0) rgb(255,192,0) rgb(255,128,0) rgb(255,64,0) rgb(255,0,0)

Более сложный пример: перемещение и изменение размера

Хотя метод угасания желтого цвета демонстрирует анимацию, он несколько скучен. Когда большинство людей представляют себе анимацию, они обычно имеют в виду движение. Интересный прием предупреждения пользователя о том, что что-то произошло, не прерывая его рабочего процесса , состоит в немодальном сообщении. Вместо вывода диалогового окна alert() , которое требует от пользователя щелчка на OK , прежде чем он сможет продолжить, поместите сообщение просто в плавающий div на странице, который ненавязчиво остается там, пока не получит подтверждение. Второй достаточно интересной вещью затем может быть предоставление пользователю возможности вернуться к сообщению, для которого он подтвердил желание прочитать его еще раз. Поэтому давайте реализуем плавающее сообщение, которое, после щелчка на нем, "схлопывается" в угол экрана, и затем по щелчку может быть снова восстановлено. Вы можете посмотреть небольшую демонстрацию такого "схлопывающегося сообщения" (http://dev.opera.com/articles/view/javascript-animation/moving_messages_jq.html), чтобы понять общую идею.

Если вы делаете какую-то серьезную анимационную работу, или какую-то серьезную работу с JavaScript, почти всегда стоит использовать библиотеку JavaScript. Это позволит создать требуемое представление для пользователей, не беспокоясь о математических тонкостях, требуемых для выполнения анимации. (Познакомившись с представленным выше первым примером, вы знаете теперь, как выполнить математические вычисления и как использовать setInterval , но вы сохраните время и собственные силы, используя готовые решения.)

Приведенный выше демонстрационный пример использует для работы библиотеку jQuery (http://jquery.com/), но как упоминалось, большинство библиотек предоставляют достаточно похожую концепцию анимации, и поэтому вы сможете реализовать принципиальную часть, используя предпочитаемую библиотеку. По существу, необходимо сделать следующее:

  • Показать плавающее сообщение в центре экрана
  • Когда на нем производится щелчок:
  • Переместить его горизонтальную позицию в крайнее правое положение
  • Переместить его вертикальную позицию вверх
  • Задать его ширину равной 20px
  • Задать его высоту равной 20px
  • Сделать его плотность равной 20%, так что оно становится почти прозрачно и скрыть в нем текст
  • Когда выполняется щелчок на этой "мини"-версии сообщения, восстановить его в центре экрана (т.е., обратное тому, что мы делали для его сжатия) и чтобы пользователь получил четкую картину того, что произошло с его сообщением, переход от полноразмерного сообщения к мини-сообщению должен быть анимирован (чтобы они видели, что сообщение "сжалось" в угол окна).
  • Выполнить анимацию с помощью jQuery очень легко: используйте просто функцию . animate () и предоставьте желательный конечный результат анимации (и как долго она должна выполняться):

    $(ourObject).animate({ width: "20px", height: "20px", top: "20px", right: "20px", marginRight: "0px", opacity: "0.2" }, 300);

    Функция получает ourObject и, за 300 миллисекунд, заменяет его ширину и высоту на 20px, его верхнюю и правую позиции на 20px, его свойство стиля margin-right на 0px, и его плотность (в браузерах, которые поддерживают плотность изображения) на 20%. Затем это просто вопрос программирования в стиле