在Anime.js 系列的上一个教程中,您了解了控制不同目标元素的动画效果的不同类型的参数。您还学习了如何使用函数参数逐渐改变元素的延迟或持续时间。
在本教程中,我们将更进一步,学习如何使用常规数字、基于函数的值和关键帧来指定属性值本身。您还将学习如何使用时间轴按顺序播放动画。
指定属性值
Anime.js 允许您为目标元素的动画属性指定最终值或结束值。动画的初始值或起始值是该属性的默认值。css中指定的任何值也可以作为起始值。有多种方法可以指定最终值。
它也可以是一个无单位的数字。在这种情况下,在计算任何属性值时都会使用属性的原始或默认单位。您也可以将值指定为字符串,但字符串必须至少包含一个数值。字符串值的示例是10vh
、80%
和9.125turn
。
除了指定绝对值,您还可以指定相对于当前值的属性值。例如,您可以使用作为值将最终translateY
值设置为150px
大于当前值。+=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)
增加50 个像素。translateY
缩放动画还使用元素的索引以及内置Math.random()
函数返回一个小于 1 的浮点伪随机数。这样元素随机缩放,但i/10
属性的一部分稍微增加了可能最后出现的元素具有更大的尺寸。
在旋转动画的代码中,我们使用anime.random(a, b)
辅助函数来获取 -180 到 180 之间的随机整数。该函数有助于将随机整数值分配给 和 等translateY
属性 rotate
。使用此函数分配随机比例值将产生极端结果。
不同元素的边界半径值是通过使用el
函数参数计算目标元素的宽度来确定的。最后,代码的最后一部分也为duration
和delay
参数分配随机值。
可以看到最后一部分实现的动画非常随意。元素的不同属性的值或它们的延迟和持续时间值之间没有关系。在现实生活中,使用可以为动画添加一些方向感的值更为明智。
也可以使用关键帧为目标元素的不同属性设置动画。每个关键帧都包含一个属性对象数组。您可以使用该对象为动画的该部分指定属性值duration
和。以下代码创建基于关键帧的平移动画。delay
easing
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:在这种情况下,当前动画在等于偏移乘以前一个动画的动画持续时间的毫秒后开始播放。
以下代码显示了如何创建基本时间线和具有相对偏移值的时间线。
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
为红色方块动画指定 a。因此,使用默认值 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
为 seek 函数设置值。这是因为范围输入的最大值已在标记中设置为 100。直接使用输入范围的值将允许我们最多搜索 100 毫秒。将范围输入值与动画持续时间相乘确保我们可以在范围滑块上从头到尾寻找动画。
最后的想法
在本教程中,您学习了如何为数字、函数或关键帧等不同的属性值设置动画。您还学习了如何在 Anime.js 中控制和操作时间线来控制动画序列的播放顺序。