Разрушение мифов: CSS анимации vs. JavaScript

С появлением CSS3-анимаций, HTML-документы стали гораздо привлекательней, и разрабатывать их стало проще. Используя правило @keyframes, вы можете без труда определять различные параметры, включая расположение и размер HTML-элемента. Параметр animation, в свою очередь, отвечает за запуск и перемещение ключевых кадров в зависимости от определенных параметров. Без необходимости использовать javascript и плагины, мы можем без труда создавать даже самые сложные анимации, которые будут работать очень плавно во всех современных браузерах.

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

Комбинируем CSS и javascript при помощи нового метода animate()

Новый javascript-метод animate() позволяет нам управлять анимациями посредством скрипта. Конечно же, нам все равно нужно использовать целую пачку CSS-параметров для определения наших ключевых кадров.


{height: "0"},
{height: "100%"}
], {
duration: 3000,
iteration: 2,
delay: 1000
});
В вышеприведенном примере мы прикрепляем метод animate() к элементу. Внутри квадратных скобок определяется столько состояний заданного параметра, сколько нам требуется, и в нашем примере мы будем работать над height. Каждое значение записано в виде буквы объекта, а значения используются лишь для одного отдельного параметра. Комбинации вроде width и height недопустимы. Учтите, что сами значения должны быть обрамлены цитированием, и оформлены синтаксисом, отвечающим требованиям javascript, а это значит, что нужно использовать “backgroundColor” вместо “background-color”. В другой букве объекта, сразу после закрытия квадратных скобок, мы определяем дальнейшую анимацию. Мы хотим изменить длину анимацию посредством duration, частоту повторений посредством iteration и может на усмотрение определить задержку посредством параметра delay, - этот параметр определяет момент, когда должна быть запущена анимация. Все временные значения указываются в миллисекундах.

Управляем набором ключевых кадров и их продолжительностью

Нам нужно запустить метод animate() отдельно от каждого параметра, который нам нужно изменить. Это значит, что при желании изменить как height, так и width, нам нужно будет повторно запускать animate().

Document.getElementById("element").animate([
{width: "0", offset: 0},
{width: "10%", offset, 1/3},
{width: "100%", offset: 1}
], {
duration: 3000,
iteration: 2,
delay: 1000
});
Вы вышеприведенном примере мы изменяем ширину элемента. Ширина должна изменяться, начиная от 0, и поднимаясь до 10 процентов, а затем завершиться при достижении 100 процентов. Все это будет сопровождаться плавной анимацией, естественно. Дополнительный параметр offset определяет, что изменения от 0 до 10 процентов будут занимать 1/3 всего времени, а переход от 10 к 100 займет 2/3 всего времени анимации. И при этом всем, общая продолжительность анимации определяется параметром duration. В данном случае, первая часть будет происходит на протяжении одной секунды, а вторая – на протяжении 2.

Вместо того, чтобы определять значение в виде дробей, вы также можете воспользоваться десятичными числами. Нужно использовать цифры от 0 до 1. К примеру, вместо 1/3 вы можете использовать 0.33.

Больше опций для анимации

Если вы знакомы с CSS3-параметром animation, то наверняка знаете о том, что метод animate() позволяет управлять процессом анимации. Вы можете изменять направление, а также скорость анимации, и ее ускорение. Если вы хотите указать, что после окончания, анимация должна вернуться к началу, то можете сделать это.

Document.getElementById("element").animate([

], {
duration: 3000,
iteration: 2,
delay: 1000,
direction: "reverse",
easing: "ease-in",
fill: "forwards"
});
Значение direction содержит в себе информацию о направлении анимации. Если вы установите значение reverse, то анимация будет воспроизведена в обратном направлении. Значение же alternate позволит вам воспроизвести анимацию в стандартном направлении, а затем в обратном. А значение alternate-reverse комбинирует два последних значения.

Значение easing позволяет вам использовать самые распространенные функции модификаций, которые уже хорошо известны по CSS3, так как там можно встречать ease-in, ease-out и так далее. По умолчанию, каждая анимация настроена на линейный ход без ускорения или замедления. Значение fill определяет, что будет представлено после окончания анимации. По умолчанию, анимация должна вернуться к стартовой точке. При использовании значения forward, анимация остановится на последнем ключевом кадре.

Управление анимацией

Применение animate() к переменной позволяет нам управлять анимацией посредством javascript. Мы можем запускать и останавливать ее по собственному усмотрению.

Var animation = document.getElementById("element").animate([
{height: "0"},
{height: "100%"}
], {
duration: 3000,
iteration: 2,
delay: 1000
});

document.getElementById("animation_start").addEventListener("click", function() {
animation.play();
}, false);

document.getElementById("animation_pause").addEventListener("click", function() {
animation.pause();
}, false);
В нашем примере мы прикрепляем анимацию к переменной animation, как это ни странно. Затем мы прикрепляем 2 слушателя событий к элементам с id animation_start и animation_pause. Эти слушатели позаботятся о выполнении определенных функций при клике. Play запускает анимацию, pause уже понятно, что делает, а reverse немедленно перенесет вас к последнему ключевому кадру и полностью остановит анимацию.

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

Animation.addEventListener("finish", function() {
alert("The animation has ended.");
}, false);
В вышеприведенном примере мы просто запускаем сообщение о том, что анимация завершена.

Браузерная поддержка

animate() сейчас находится на ранней стадии разработки и сейчас обременена ярлыком «experimental». Поддержка этого параметра появится в Chrome, начиная с 36 версии. Если вы хотите опробовать ее сейчас, то можете скачать и установить Chrome Canary.

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, то сразу им станете, как только увидите, сколько классных анимаций можно создать этого языка.

Зачем анимировать элементы с помощью JavaScript

При использовании CSS браузер выполняет за вас большую часть анимации. Для ее реализации разработчик просто определяете начальное и конечное состояние:

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

Но это не является анимацией. Это значения свойств, заданные в определенные моменты анимации. Именно изменение значений между этими точками важно для работы анимации:

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

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

Цикл анимации

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

Вы увидите синий круг, который неподвижен. Нажмите на кнопку « move » и обратите внимание, что произойдет. Круг сместится немного вправо. Нажмите на кнопку « move » снова , чтобы продолжить смещение.

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

Разметка и код примера:

Animating in Code! body { background-color: #FFF; margin: 30px; margin-top: 10px; display: flex; align-items: center; justify-content: center; flex-direction: column; } #contentContainer { width: 550px; height: 350px; border: 5px black solid; overflow: hidden; background-color: #DFF2FF; display: flex; align-items: center; } #circle { width: 200px; height: 200px; background-color: #20A6FF; border-radius: 50%; } #move { background-color: gold; margin-top: 20px; font-size: 16px; font-weight: bold; border: 5px solid #333; outline: none; } #move:hover { background-color: coral; } #move:active { background-color: yellowgreen; } var circle = document.querySelector("#circle"); var button = document.querySelector("#move"); button.addEventListener("click", animate, false); var xPos = 0; function animate() { xPos += 10; circle.style.transform = `translate3d(${xPos}px, 0, 0)`; if (Math.abs(xPos) >= 900) { xPos = -500; } }

Создайте новый HTML-документ и скопируйте в него приведенный выше код. Сохраните файл и откройте его в браузере. Вы должны увидеть тот же пример, который работает локально на вашем компьютере:

В нашем примере функция animate вызывается каждый раз, когда для кнопки запускается событие click :

var button = document.querySelector("#move"); button.addEventListener("click", animate, false);

Код, окружающий функцию animate, выглядит следующим образом:

var xPos = 0; function animate() { xPos += 10; circle.style.transform = `translate3d(${xPos}px, 0, 0)`; if (Math.abs(xPos) >= 900) { xPos = -500; } }

Переменной xPos задано значение 0 . Каждый раз, когда вызывается функция animate, значение переменной увеличивается на 10 . Круг перемещается вправо благодаря следующей строке кода:

circle.style.transform = `translate3d(${xPos}px, 0, 0)`;

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

if (Math.abs(xPos) >= 900) { xPos = -500; }

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

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

Цикл анимации — это функция, которая вызывается многократно благодаря обычной функции таймера requestAnimationFrame. Давайте изменим наш пример.

Внутри тега внесите следующие изменения:

var circle = document.querySelector("#circle"); var xPos = 0; function animate() { xPos += 10; circle.style.transform = `translate3d(${xPos}px, 0, 0)`; if (Math.abs(xPos) >= 900) { xPos = -500; } requestAnimationFrame(animate); } animate();

Что мы сделали:

  • Вызвали функцию animate явно, чтобы она запускалась автоматически, без нажатия кнопки.
  • Поместили ниже функцию requestAnimationFrame,который будет вызывать функцию animate в каждом интервале обновления кадра.
  • Мы также удалили код, связанный с работой кнопки. Если бы мы просматривали анимацию в ее текущем состоянии, она выглядела бы следующим образом:

    При добавлении вызова requestAnimationFrame мы добавили функцию animate в захватывающий цикл анимации. Он отвечает за перемещение круга вправо на 10 пикселей при каждом обновлении кадра.

    Можно пойти еще дальше

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

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



    error: Content is protected !!