• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

使用Anime.js基于JavaScript的动画:回调、缓动和 SVG

完成本系列的前三个教程后,您现在应该对很多 Anime.js 功能感到非常熟悉。第一个教程向您展示了如何选择目标元素。在第二个教程中,您了解了不同类型的参数,这些参数可用于对不同元素的动画的延迟和持续时间进行精细控制。第三个教程的重点是学习如何在动画过程中更好地控制单个属性的值。

在本教程中,您将了解可用于根据动画进度执行函数的不同回调。几乎前面教程中的每个示例都使用css属性来演示不同的方法和参数是如何工作的。这可能使您认为该库更适合动画 CSS 属性。这一次,我们将有一个部分专门用于在 Anime.js 中创建与svg相关有趣动画。

回调

正如我在介绍中提到的,您可以使用回调来根据动画的进度执行函数。有四种不同的回调:  beginrunupdatecomplete每个回调函数在特定时间触发,每个回调函数都接受一个动画对象作为其参数。 

begin()函数在动画实际开始时调用。这意味着如果动画有 800 毫秒的延迟,begin()只有在延迟结束后才会调用。您可以检查动画是否已开始播放或未使用animationName.begin,分别返回truefalse

run回调可用于在动画实际开始播放后的每一帧中执行一个函数如果你想从动画的一开始就在每一帧中执行一个函数,而不考虑它的delay,你应该使用update回调来代替。

complete回调与动画类似,只是begin它在动画播放完毕后被调用。就像begin,您可以使用animationName.complete来检查动画是否已播放完毕。

您已经在第一个教程中看到了如何在动画 javascript 对象的数值update时使用回调在本教程中,我们将修改该示例并了解如何将所有这些回调一起使用以向用户提供更多信息。

var filesScanned = { count: 0, infected: 0 };
var scanCount = document.queryselector(".scan-count");
var infected = document.querySelector(".infected-count");

var scanning = anime({
  targets: filesScanned,
  autoplay: false,
  count: 100,
  infected: 8,
  delay: 1000,
  duration: 2000,
  easing: "linear",
  round: 1,
  update: function(anim) {
    if (anim.currentTime < 1000) {
      document.querySelector(".update-cb").innerhtml = "Creating an Index...";
    }
  },
  begin: function() {
    document.querySelector(".begin-cb").innerHTML = "Starting the Scan...";
  },
  run: function() {
    scanCount.innerHTML = filesScanned.count;
    infected.innerHTML = filesScanned.infected;
  },
  complete: function() {
    document.querySelector(".complete-cb").innerHTML = "Scan Complete...";
  }
});

我故意在这个动画中添加了一些延迟,以便我们可以注意到不同回调执行时间的差异。update一旦动画实例开始,回调就会开始执行其函数 

实际动画在 1000 毫秒后开始播放,此时begin函数向用户显示其“开始扫描...”消息。run函数也同时开始执行,并在每一帧之后更新对象的数值。动画完成后,complete回调会向用户显示“扫描完成...”消息。

使用Anime.js基于JavaScript的动画:回调、缓动和 SVG  第1张

缓动函数

缓动函数可用于控制属性值如何从初始值转换为最终值。这些缓动函数可以使用 easing 参数指定,该参数可以接受字符串以及自定义贝塞尔曲线坐标(以数组的形式)。 

有 31 种不同的内置缓动函数。其中一个是linear,另外 30 个由 、 和 的十个不同变 easeIneaseOut组成easeInOut共有三个弹性缓动方程,分别称为 easeInElastic、 easeOutElastic和 easeInOutElastic您可以使用参数控制它们的弹性elasticity的值elasticity可以是 0 到 1000 之间的任何值。

EaseIn方程从零开始加速属性的值变化。这意味着价值的变化在开始时会很慢,最后会很快。变化率在开始时为零,在结束时最大。EaseOut方程从最大速率变化开始减速属性的值变化。 

这意味着价值的变化在开始时会非常快,在结束时会非常缓慢。EaseInOut方程在开始时加速速率变化并在结束时减速。这意味着变化的速度在开始和结束时都会很慢,而在动画中间会最快。以下演示显示了每个缓动函数的变化率差异。

使用Anime.js基于JavaScript的动画:回调、缓动和 SVG  第2张

您还可以借助anime.easings这是创建自定义缓动函数的示例。

anime.easings['tanCube'] = function(t) {
  return Math.pow(Math.tan(t*Math.PI/4), 3);
}

anime.easings['tanSqr'] = function(t) {
  return Math.pow(Math.tan(t*Math.PI/4), 2);
}

var tanCubeSequence = anime({
  targets: '.tan-cube',
  translateX: '75vw',
  duration: 2000,
  easing: 'tanCube',
  autoplay: false
});

var tanSqrSequence = anime({
  targets: '.tan-sqr',
  translateX: '75vw',
  duration: 2000,
  easing: 'tanSqr',
  autoplay: false
});

使用Anime.js基于JavaScript的动画:回调、缓动和 SVG  第3张

基于 SVG 的动画

到目前为止,我们创建的所有与运动相关的动画都以直线移动目标元素。在 Anime.js 中也可以沿着具有大量曲线的复杂 SVG 路径移动元素。您可以控制路径上动画元素的位置和角度。要将元素移动到路径的 x 坐标,可以使用 path(x)类似地,可以使用 . 根据路径的 y 坐标移动元素path(y)。 

除非路径是一条直线,否则它几乎总是相对于水平基线形成一个角度。如果您正在旋转任何非圆形元素,如果元素遵循路径的角度会感觉更自然。您可以通过将rotate属性设置为等于 来做到这一点path('angle')这是沿 SVG 路径为具有不同缓动值的四个元素设置动画的代码。

var path = anime.path('path');

var easings = ['linear', 'easeInCubic', 'easeOutCubic', 'easeInOutCubic'];

var motionPath = anime({
  targets: '.square',
  translateX: path('x'),
  translateY: path('y'),
  rotate: path('angle'),
  easing: function (el, i) {
    return easings[i];
  },
  duration: 10000,
  loop: true
});

您可以在下面的演示中看到,带有easeInCubic缓动的红色方块在开始时最慢,在结束时最快。类似地,橙色方块easeOutCubic在开始时最快,在结束时最慢。

使用Anime.js基于JavaScript的动画:回调、缓动和 SVG  第4张

您还可以使用 Anime.js 为不同 SVG 形状的变形制作动画。唯一的条件是两个形状应具有相同数量的点。这意味着您只能将三角形变形为其他三角形,将四边形变形为其他四边形。尝试在数量不等的多边形点之间变形会导致形状突然变化。这是变形三角形的示例

var morphing = anime({
  targets: 'polygon',
  points: [
    { value: '143 31 21 196 286 223' },
    { value: '243 31 21 196 286 223' },
    { value: '243 31 121 196 286 223' },
    { value: '243 31 121 196 386 223' },
    { value: '543 31 121 196 386 223' }
  ],
  easing: 'linear',
  duration: 4000,
  direction: 'alternate',
  loop: true
});


您可以使用 SVG 创建的另一种有趣的效果是线条绘制。您所要做的就是为 Anime.js 提供您想要用于线条绘制的路径以及控制其持续时间、延迟或缓动的其他参数。在下面的演示中,我使用回调将font Awesome 锚图标complete的线条绘制填充为黄色。

var lineDrawing = anime({
  targets: 'path',
  strokeDashoffset: [anime.setDashoffset, 0],
  easing: 'easeInOutCubic',
  duration: 4000,
  complete: function(anim) {
    document.querySelector('path').setAttribute("fill", "yellow");
  }
});

使用Anime.js基于JavaScript的动画:回调、缓动和 SVG  第5张

结合您迄今为止所学的所有概念的知识,您可以创建更复杂的线条图,并更好地控制它们的绘制方式。这是一个示例,其中我使用 SVG 编写了自己的名字。

var letterTime = 2000;

var lineDrawing = anime({
  targets: "path",
  strokeDashoffset: [anime.setDashoffset, 0],
  easing: "easeInOutCubic",
  duration: letterTime,
  delay: function(el, i) {
    return letterTime * i;
  },
  begin: function(anim) {
    var letters = document.querySelectorAll("path"), i;

    for (i = 0; i < letters.length; ++i) {
      letters[i].setAttribute("stroke", "black");
      letters[i].setAttribute("fill", "none");
    }
  },
  update: function(anim) {
    if (anim.currentTime >= letterTime) {
      document.querySelector(".letter-m").setAttribute("fill", "#e91e63");
    }
    if (anim.currentTime >= 2 * letterTime) {
      document.querySelector(".letter-o").setAttribute("fill", "#3F51B5");
    }
    if (anim.currentTime >= 3 * letterTime) {
      document.querySelector(".letter-n").setAttribute("fill", "#8BC34A");
    }
    if (anim.currentTime >= 4 * letterTime) {
      document.querySelector(".letter-t").setAttribute("fill", "#FF5722");
    }
    if (anim.currentTime >= 5 * letterTime) {
      document.querySelector(".letter-y").setAttribute("fill", "#795548");
    }
  },
  autoplay: false
});

我首先将值 2000 分配给变量letterTime这是我希望 Anime.js 绘制名字的每个字母的时间。该属性使用基于函数的索引参数在变量的帮助下delay设置适当的值。 delayletterTime

第一个字母“M”的索引为零,因此 Anime.js 立即开始绘制它。字母“O”有 2000 毫秒的延迟,因为这是完全绘制字母“M”所需的时间。

begin回调中,我将stroke所有字母的值设置为 ,black并将它们的fill值设置为none这样我们可以清除update回调中应用的所有颜色值,以便字母在多个循环中运行时可以返回到它们的初始状态。尝试单击以下演示中的写入名称按钮以查看实际代码。

使用Anime.js基于JavaScript的动画:回调、缓动和 SVG  第6张

最后的想法

在本教程中,您了解了不同的回调函数,它们可用于执行诸如更新dom或根据动画进度更改属性值等任务。您还了解了不同的缓动函数以及如何创建自己的缓动函数。本教程的最后一部分侧重于创建基于 SVG 的动画。


文章目录
  • 回调
  • 缓动函数
  • 基于 SVG 的动画
  • 最后的想法