August 15, 2018

Анимация в JavaScript. Статья первая. А может, CSS?

CSS или JS?

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

Библиотека Anime.js

Anime.js — библиотека для создания анимации на основе JavaScript. С её помощью можно анимировать свойства CSS, SVG-изображения или атрибуты DOM-дерева на веб-странице. Библиотека позволяет контролировать все аспекты анимации и предоставляет много способов для обозначения элементов, которые нужно привести в движение.

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

Устанавливаем библиотеку

Для установки библиотеки нужно сделать несколько шагов.

Скачиваем с GitHub файл (в красной рамочке):

Далее создаем на компьютере две папки. Одна папка должна быть внутри другой. У нас в "Папке 1" находится "Папка 2" и документ "Код.html". В "Папка 2" мы сохраним документ из загруженного файла, а в документе "Код.html" мы будем писать код JS.

Затем открываем загруженный файл, заходим в папку "anime-master", находим документ "anime.min.js". Перетаскиваем его в папку "Папка 2".

После этого открываем документ "Код.html" в редакторе кода. И в нужное место вставляем следующий ниже код:

<script src="Папка 2/anime.min.js"></script>

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

Определяем целевые элементы

Для создания анимации с помощью Anime.js нужно вызвать функцию anime() и передать ей объект с парами ключ-значение, которые определяют целевые элементы и свойства, которые вы хотите анимировать. Вы можете использовать ключевое слово targets, чтобы дать библиотеке понять, что вам нужно анимировать. Это ключевое слово может принимать значение в разных форматах.

CSS-селекторы: вы можете передавать один или более селекторов в виде значений для ключевого слова targets.

var blue = anime({
  targets: '.blue',
  translateY: 200
});
 
var redBlue = anime({
  targets: '.red, .blue',
  translateY: 200
});
 
var even = anime({
  targets: '.square:nth-child(even)',
  translateY: 200
});
 
var notRed = anime({
  targets: '.square:not(.red)',
  translateY: 200
});

В первом случае Anime.js будет анимировать все элементы с классом blue. Во втором — blue или red. В третьем случае Anime.js будет анимировать все дочерние чётные элементы с классом square. А в последнем случае библиотека будет взаимодействовать со всеми элементами с классом square, у которых нет класса red.

DOM-узлы (DOM node) или коллекция узлов (NodeList): вы можете также использовать DOM-узел или NodeList в качестве значения для ключевого слова targets. Посмотрите на пример использования DOM-узла для targets.

var special = anime({
  targets: document.getElementById('special'),
  translateY: 200
});
 
var blue = anime({
  targets: document.querySelector('.blue'),
  translateY: 200
});
 
var redBlue = anime({
  targets: document.querySelectorAll('.red, .blue'),
  translateY: 200
});
 
var even = anime({
  targets: document.querySelectorAll('.square:nth-child(even)'),
  translateY: 200
});
 
var notRed = anime({
  targets: document.querySelectorAll('.square:not(.red)'),
  translateY: 200
});

В первом случае использовалась функция getElementById(), чтобы обратиться к определённому элементу. Функция querySelector()использовалась для обращения к элементу с классом blue. А функция querySelectorAll() применялась для обращения ко всем элементам внутри документа, которые соответствуют группе определённых селекторов или же, наоборот, не входят в неё.

Существует множество функций, которые вы также можете использовать для выбора целевого элемента. Например, вы можете обратиться к элементам с определённым классом, используя функцию getElementsByClassName(). Или к элементам с определённым тегом, используя функцию getElementsByTagName().

Любая функция, возвращающая DOM-узел или NodeList, может использоваться для установки значения targets в Anime.js.

Объект: вы можете использовать объекты JavaScript в качестве значения для targets. Ключ этого объекта используется в качестве идентификатора, а значение — в качестве числа, которое нужно анимировать.

Затем вы сможете показать анимацию внутри другого HTML-элемента с помощью дополнительного JavaScript-кода. Ниже приведён пример анимации значений двух разных ключей одного объекта.

var filesScanned = { count: 0, infected: 0 };
 
var scanning = anime({
  targets: filesScanned,
  count: 1000,
  infected: 8,
  round: 1,
  update: function() {
    var scanCount = document.querySelector('.scan-count');
    scanCount.innerHTML = filesScanned.count;
     
    var infectedCount = document.querySelector('.infected-count');
    infectedCount.innerHTML = filesScanned.infected;
  }
});

Код выше будет приводить в движение счётчик сканированных файлов от 0 до 1 000 и счётчик заражённых файлов от 0 до 8. Помните, что вы можете анимировать числовые значения только таким образом. При попытке анимировать ключ из AAA в BOY будет выведено сообщение об ошибке.

Кроме того, в коде использовалась функция обратного вызова ключа update, который вызывается на каждый кадр во время выполнения анимации. Здесь она использовалась для обновления количества сканированных и заражённых файлов. Однако вы можете пойти дальше и показать пользователям сообщение об ошибке, когда количество заражённых файлов превысит определённый порог.

Массив: возможность указывать массив JavaScript в качестве значения targets будет полезна, если вам нужно анимировать множество элементов, которые относятся к разным категориям. Например, если вы хотите анимировать DOM-узел, объект и множество других элементов, основанных на CSS-селекторах, то можно это сделать, поместив их в массив, а затем определить массив в качестве значения для targets. Пример ниже должен прояснить ситуацию.

var multipleAnimations = anime({
  targets: [document.querySelectorAll('.blue'), '.red, #special'],
  translateY: 250
});

Какие свойства можно анимировать с помощью Anime.js

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

Свойства CSS

К таким, например, относятся ширина, высота и цвет для разных целевых элементов. Финальные значения разных анимируемых свойств вроде background-color определяются с использованием lowerCamelCase. Таким образом background-color превращается в backgroundColor. Код ниже иллюстрирует анимацию положения объекта left и цвета фона (backgroundColor) целевого объекта.

var animateLeft = anime({
  targets: '.square',
  left: '50%'
});
 
var animateBackground = anime({
  targets: '.square',
  backgroundColor: '#f96'
});

Свойства могут принимать разные виды значений, которые они бы приняли при использовании обычного CSS. Например, свойство left может иметь такие значения: 50vh500px или 25em. Вы также можете не указывать единицу измерения после числа, но в таком случае ею станет px по умолчанию. Аналогичные действия можно выполнить с background-color, указав цвет в виде шестнадцатеричного значения или при помощи кода RGB или HSL.

CSS-трансформирование

Преобразование по осям X и Y достигается с помощью свойств translateX и translateY. Аналогичным образом можно масштабировать, наклонять или вращать элемент вдоль определённой оси, используя свойства: scale (масштабирование), skew (наклон) или rotate (поворот), соответствующие этой конкретной оси.

Существует возможность определения разных углов или в градусах, или с помощью свойства turn. Значение turn, равное 1, соответствует 360 градусам. Это позволяет сделать вычисления проще, так как вы знаете, на сколько нужно повернуть элементы относительно своей оси. В примере ниже показано, как происходит анимация масштабирования, перехода или поворота как единичного свойства, так и всех сразу.

var animateScaling = anime({
  targets: '.square',
  scale: 0.8
});
 
var animateTranslation = anime({
  targets: '.square',
  translateX: window.innerWidth*0.8
});
 
var animateRotation = anime({
  targets: '.square',
  rotate: '1turn'
});
 
var animateAll = anime({
  targets: '.square',
  scale: 0.8,
  translateX: window.innerWidth*0.8,
  rotate: '1turn'
});

Атрибуты SVG

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

По мере углубления в библиотеку вы будете узнавать, как создаются более сложные анимации. Ниже представлен код для анимации атрибутов круга cycx и stroke-width. Как и с другими свойствами CSS, для stroke-width надо использовать CamelCase, чтобы код работал корректно.

var animateX = anime({
  targets: '.circle',
  cx: window.innerWidth*0.6
});
 
var animateStrokeWidth = anime({
  targets: '.circle',
  strokeWidth: '25'
});

Атрибуты DOM

Можно анимировать числовые атрибуты DOM, подобно тому, как вы анимировали атрибуты SVG. Это может быть полезным для работы с элементом progress в HTML5. У него есть два атрибута: value и max. В примере ниже будет выполняться анимация атрибута value, чтобы продемонстрировать прогресс перемещения файла на жёсткий диск.

var animateProgress = anime({
  targets: 'progress',
  value: 100,
  easing: 'linear'
});

Заключение

Вы познакомились со всеми вариантами выбора элементов в Anime.js, а также узнали, как анимировать разные свойства CSS и атрибуты, связанные с ними.

В следующей статье Lizard Squad расскажет, как контролировать плавность, задержку и длительность анимации как для единичных свойств, так и для группы. Затем вы научитесь контролировать все эти параметры для каждого отдельного элемента.