Статьи

Анимации на основе JavaScript с использованием Anime.js, часть 3: значения, временная шкала и воспроизведение

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

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

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

Это также может быть число без единицы. В этом случае при вычислении любых значений свойства используются исходные единицы измерения или единицы измерения по умолчанию. Вы также можете указать значение в виде строки, но строка должна содержать хотя бы одно числовое значение. Примеры строковых значений: 10vh , 80% и 9.125turn .

Вместо указания абсолютного значения вы также можете указать значения свойств относительно их текущего значения. Например, вы можете установить конечное значение translateY на 150px больше текущего значения, используя +=150px в качестве значения. Имейте в виду, что вы можете использовать только сложение, умножение и вычитание при указании относительных значений.

Во время анимации цветов нельзя использовать названия цветов, такие как красный, черный и синий, чтобы установить окончательное значение цвета для анимации. В таких случаях цветовая анимация вообще не происходит, и изменение будет мгновенным. Единственный способ анимировать цвета — указывать значения в виде шестнадцатеричных цифр или в терминах значений RGB и HSL.

Как вы могли заметить, мы не указывали начальное значение для наших целевых элементов для их анимации. Anime.js автоматически определяет начальное значение на основе нашего CSS и значения по умолчанию этих свойств. Однако вы можете указать начальное значение, отличное от значения по умолчанию для свойства, используя массивы. Первый элемент в массиве обозначает начальное значение, а второй элемент обозначает окончательное значение.

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
var uniqueTranslation = anime({
  targets: ‘.square’,
  translateY: function(el, i) {
    return 50 * (i + 1);
  },
  autoplay: false
});
 
var randomScaling = anime({
  targets: ‘.square’,
  scale: function(el, i) {
    return Math.random()*1.5 + i/10;
  },
  autoplay: false
});
 
var randomRotation = anime({
  targets: ‘.square’,
  rotate: function() {
    return anime.random(-180, 180);
  },
  autoplay: false
});
 
var randomRadius = anime({
  targets: ‘.square’,
  borderRadius: function(el) {
    return 20 + Math.random()*el.offsetWidth/4;
  },
  autoplay: false
});
 
var randomAll = anime({
  targets: ‘.square’,
  translateY: function(el, i) {
    return 50 + 50 * i;
  },
  scale: function(el, i) {
    return Math.random()*1.5 + i/10;
  },
  rotate: function() {
    return anime.random(-180, 180);
  },
  borderRadius: function(el) {
    return Math.random()*el.offsetWidth/2;
  },
  duration: function() { return anime.random(1500, 2400);
  delay: function() { return anime.random(0, 1000);
  autoplay: false
});

Для свойства translateY мы используем индекс элемента для установки значения перевода. Использование 50 * (i + 1) увеличивает значение translateY для каждого элемента на 50 пикселей.

Анимация масштабирования также использует индекс элемента вместе со встроенной Math.random() чтобы возвращать псевдослучайное число с плавающей точкой меньше 1. Таким образом, элементы масштабируются случайным образом, но часть i/10 свойства немного увеличивает вероятность того, что элементы, которые появляются в конце, имеют больший размер.

Внутри кода для анимации вращения мы используем вспомогательную функцию anime.random(a, b) для получения случайных целых чисел от -180 до 180. Эта функция полезна для назначения случайных интегральных значений таким свойствам, как translateY и rotate . Использование этой функции для назначения случайных значений масштаба приведет к экстремальным результатам.

Значение радиуса границы для разных элементов определяется путем вычисления ширины целевых элементов с использованием параметра функции el . Наконец, последняя часть кода также назначает случайные значения параметрам duration и delay .

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

Также возможно анимировать различные свойства ваших целевых элементов, используя ключевые кадры. Каждый ключевой кадр состоит из массива объекта свойства. Вы можете использовать объект, чтобы указать значение свойства, duration , delay и easing для этой части анимации. Следующий код создает анимацию перевода на основе ключевых кадров.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var keyframeTranslation = anime({
  targets: ‘.square’,
  translateY: [
    { value: 100, duration: 500},
    { value: 300, duration: 1000, delay: 1000},
    { value: 40, duration: 500, delay: 1000}
  ],
  autoplay: false
});
 
var keyframeAll = anime({
  targets: ‘.square’,
  translateY: [
    { value: 100, duration: 500},
    { value: 300, duration: 1000, delay: 1000},
    { value: 40, duration: 500, delay: 1000}
  ],
  scale: [
    { value: 1.1, duration: 500},
    { value: 0.5, duration: 1000, delay: 1000},
    { value: 1, duration: 500, delay: 1000}
  ],
  rotate: [
    { value: 60, duration: 500},
    { value: -60, duration: 1000, delay: 1000},
    { value: 75, duration: 500, delay: 1000}
  ],
  borderRadius: [
    { value: 10, duration: 500},
    { value: 50, duration: 1000, delay: 1000},
    { value: 25, duration: 500, delay: 1000}
  ],
  delay: function(el, i) { return 100*(i+1) },
  autoplay: false
});

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

До сих пор в этой серии мы использовали параметр delay для воспроизведения различных анимаций в определенной последовательности. Чтобы использовать задержку для этой цели, нам также нужно знать продолжительность предыдущей анимации.

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

Лучшее решение этой проблемы — использование временных шкал для управления последовательностью анимации. Вы должны использовать anime.timeline() для создания временной шкалы в Anime.js. Вы также можете передать различные параметры этой функции как объект. Эти параметры могут указывать направление воспроизведения временной шкалы, количество циклов и параметр autoplay чтобы определить, должна ли анимация воспроизводиться автоматически. Все эти параметры были подробно обсуждены в руководстве по параметрам этой серии .

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

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

  • + = смещение : в этом случае текущая анимация начинает воспроизводиться после того, как смещение прошло миллисекунды с момента окончания предыдущей анимации.
  • — = смещение : в этом случае текущая анимация начинает воспроизводиться со смещением за миллисекунды до конца предыдущей анимации.
  • * = смещение : в этом случае текущая анимация начинает воспроизводиться через миллисекунды, равные смещению, умноженному на продолжительность анимации предыдущей анимации.

В следующем коде показано, как создать базовую временную шкалу и временную шкалу с относительными значениями смещения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var basicTimeline = anime.timeline({
  direction: «alternate»,
  loop: 2,
  autoplay: false
});
 
basicTimeline.add({
    targets: ‘.square’,
    translateY: 200
 }).add({
    targets: ‘.red’,
    translateY: 100
 }).add({
    targets: ‘.blue’,
    translateY: 0
 });
 
var offsetTimeline = anime.timeline({
  direction: «alternate»,
  loop: 2,
  autoplay: false
});
 
offsetTimeline.add({
    targets: ‘.square’,
    translateY: 200
 }).add({
    targets: ‘.red’,
    offset: ‘+=1000’,
    translateY: 100
 }).add({
    targets: ‘.blue’,
    offset: ‘*=2’,
    translateY: 0
 });

Попробуйте нажать кнопку « Смещение временной шкалы» в приведенной выше демонстрации. Вы увидите, что между окончанием анимации красных квадратов и началом анимации синих квадратов существует задержка в 2 секунды.

Мы не указали duration анимации красного квадрата. Поэтому в качестве длительности используется значение по умолчанию 1000 мс или 1 с. Смещение множителя анимации синего квадрата удваивает это значение, и в результате анимация задерживается на две секунды.

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

Anime.js имеет множество опций для воспроизведения, приостановки, перезапуска или поиска анимаций или временных шкал в любой заданной точке.

Функция play() позволяет нам запускать анимацию с текущего прогресса. Функция pause() анимацию в момент вызова функции. Функция restart() запускает анимацию с самого начала, независимо от ее текущего прогресса. Функция seek(value) может использоваться для продвижения анимации на value числа миллисекунд.

Следует помнить, что функция play() возобновляет анимацию только с момента ее приостановки. Если анимация уже достигла своего конца, вы не можете воспроизвести анимацию с помощью play() . Чтобы воспроизвести анимацию, вам нужно использовать функцию restart() .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
var slowAnimation = anime({
  targets: ‘.square’,
  translateY: 250,
  borderRadius: 50,
  duration: 4000,
  easing: ‘linear’,
  autoplay: false
});
 
document.querySelector(‘.play’).onclick = slowAnimation.play;
document.querySelector(‘.pause’).onclick = slowAnimation.pause;
document.querySelector(‘.restart’).onclick = slowAnimation.restart;
 
var seekInput = document.querySelector(‘.seek’);
 
seekInput.oninput = function() {
  slowAnimation.seek(slowAnimation.duration * (seekInput.value / 100));
};

Обратите внимание, что мы не используем seekInput.value для установки значения для функции поиска. Это связано с тем, что в разметке максимальное значение для ввода диапазона было установлено равным 100. Непосредственное использование значения для входного диапазона позволит нам искать только до 100 мс. Умножение входного значения диапазона на длительность анимации гарантирует, что мы можем искать анимацию от начала до конца на нашем слайдере диапазона.

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

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

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