探索 Anime.js:JavaScript 动画值、时间轴与播放控制

古风汉服美女图集

探索 Anime.js:JavaScript 动画值、时间轴与播放控制

在 Anime.js 系列的上一篇教程中,您了解了控制不同目标元素的动画方式的不同类型的参数。您还学习了如何使用函数参数来逐渐更改元素的延迟或持续时间。

在本教程中,我们将更进一步,学习如何使用常规数字、基于函数的值和关键帧来指定属性值本身。您还将学习如何使用时间轴按顺序播放动画。

指定属性值

Anime.js 允许您指定目标元素的可动画属性的最终值。动画的初始值或起始值是该属性的默认值。 CSS 中指定的任何值也可以作为起始值。有多种指定最终值的方法。

它也可以是无单位的数字。在这种情况下,在计算任何属性值时将使用属性的原始或默认单位。您还可以将值指定为字符串,但该字符串必须至少包含一个数值。字符串值的示例为 10vh80%9.125turn

您还可以指定相对于当前值的属性值,而不是指定绝对值。例如,您可以使用 +=150px 作为值,将最终 translateY 值设置为比当前值大 150px 。请记住,在指定相对值时只能使用加法、乘法和减法。

在设置颜色动画时,您不能使用红色、黑色和蓝色等颜色名称来设置动画的最终颜色值。在这种情况下,颜色动画根本不会发生,并且变化将是即时的。对颜色进行动画处理的唯一方法是将值指定为十六进制数字或 RGB 和 HSL 值。

您可能已经注意到,我们没有为目标元素指定初始值来为其设置动画。 Anime.js 根据我们的 CSS 和这些属性的默认值自动确定初始值。但是,您可以使用数组指定属性的默认值以外的初始值。数组中的第一项表示初始值,第二项表示最终值。

您可以使用函数为不同的参数设置不同的值,而不是为所有目标元素使用相同的最终值。该过程类似于指定基于函数的属性参数。

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 之间的随机整数。此函数有助于分配随机积分translateYrotate 等属性的值。使用此函数分配随机比例值将产生极端结果。

不同元素的边框半径值是通过使用 el 函数参数计算目标元素的宽度来确定的。最后,代码的最后一部分也为 durationdelay 参数分配随机值。

可以看到最后一部分实现的动画是非常随机的。元素的不同属性值或其延迟和持续时间值之间没有关系。在现实生活中,使用可以为动画添加一些方向感的值更为明智。

还可以使用关键帧为目标元素的不同属性设置动画。每个关键帧都包含属性对象的数组。您可以使用该对象来指定该部分动画的属性值,durationdelayeasing。以下代码创建一个基于关键帧的平移动画。

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() 方法将不同的动画添加到时间轴。添加到时间线的所有动画将按照添加顺序播放。可以指定绝对或相对偏移值来控制动画的播放顺序。

当使用相对偏移值时,当前动画的开始时间是相对于前一个动画的时间确定的。相对偏移可以分为三种类型:

  • +=offset:在这种情况下,当前动画会在上一个动画结束后经过 offset 毫秒后开始播放。
  • -=offset:在这种情况下,当前动画在上一个动画结束前 offset 毫秒开始播放。
  • *=offset:在这种情况下,当前动画会在前一个动画的动画持续时间的 offset 倍后的毫秒数后开始播放。

以下代码展示了如何创建基本时间线和具有相对偏移值的时间线。

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 。因此,使用默认值 1000ms 或 1s 作为持续时间。蓝色方形动画的乘数偏移量使该值加倍,这会导致动画延迟两秒。

当使用绝对偏移值时,时间线的起始时间用作参考点。通过对时间线开头发生的动画使用较大的偏移值,可以反转动画的播放顺序。

播放选项

Anime.js 有多种选项可以在任何给定点播放、暂停、重新启动或搜索动画或时间线。

play() 函数允许我们从当前进度开始播放动画。 pause() 函数将在调用该函数时冻结动画。 restart() 函数从头开始播放动画,无论其当前进度如何。 seek(value) 函数可用于将动画提前 value 毫秒数。

您应该记住,play() 函数仅从暂停时恢复动画。如果动画已经结束,则无法使用 play() 重播动画。要重播动画,您必须使用 restart() 函数。

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 市场中提供的资源。

如果您对本教程有任何疑问,请在评论中告诉我。

© 版权声明

相关文章