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

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

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

Вадим Дворниковавтор материала

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

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

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

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

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

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

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

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

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

Вы увидите синий круг, который неподвижен. Нажмите на кнопку « 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 в каждом интервале обновления кадра.

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

При добавлении вызова 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();

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

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

Заключение

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

Вадим Дворниковавтор-переводчик статьи «Creating Animations in JavaScript»

Комментарии

Оставьте свой комментарий
Пока никто не оставил комментариев