Создание анимации в JavaScript

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

Содержание

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

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

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

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

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

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

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

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

0

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

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

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

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Animating in Code!</title>
  <style>
    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;
    }
  </style>
</head>

<body>
  <div id="contentContainer">
    <div id="circle"></div>
  </div>

  <input id="move" type="button" value="move"></input>

  <script>
    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;
      }
    }
  </script>
</body>

</html>

Создайте новый 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. Давайте изменим наш пример.

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

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();

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

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

Мы также удалили код, связанный с работой кнопки. Если бы мы просматривали анимацию в ее текущем состоянии, она выглядела бы следующим образом:

0

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

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

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

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

var circle = document.querySelector("#circle");

var xPos = 0;
var yPos = 0;
var angle = 0;

function animate() {
  xPos += 5;
  angle += .1;
  
  yPos = Math.round(50 * Math.sin(angle));

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

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

  if (angle > 2 * Math.PI) {
    angle = 0;
  }

  requestAnimationFrame(animate);
}
animate();

Этот код добавляют эффект отскока. Теперь наша анимация будет выглядеть следующим образом:

0

Эффект отскока стал возможен благодаря функции Math.sin(). Цель этого примера состояла в том, чтобы продемонстрировать анимацию, которую вы сможете создать с помощью JavaScript, и не сможете реализовать в CSS.

Заключение

То, что мы рассмотрели, едва затрагивает все возможные виды анимации, которые можно создать в JavaScript. Все великие путешествия должны где-то начинаться, и мы начинаем наше путешествие отсюда.

Данная публикация представляет собой перевод статьи «Creating Animations in JavaScript» , подготовленной дружной командой проекта Интернет-технологии.ру

Меню