用JavaScript 实现酷炫的粒子追踪动画

做者:Anna Prenzel

翻译:疯狂的技术宅javascript

原文:https://www.smashingmagazine....css

未经容许严禁转载html

你是否曾经想过用花哨的、闪闪发光的粒子动画分吸引你网站用户的注意力,而同时又在后台加载一些数据呢?幸运的是,没有必要用诸如 Three.js 之类的 3D 库进行很是深刻的图形编程。相反,你须要的是 CSS 和 JavaScript 的一些基本知识以及轻便的动画库(例如 anime.js)。最后咱们应该获得如下结果前端

4-partical-trail-animation-javascript.gif

Anime.Js 的下载和集成

你能够从官方 GitHub 下载 anime.js 库。从lib/文件夹下载文件anime.jsanime.min.jsjava

在个人例子中,HTML 部分以下所示:git

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>Anime.js Particles</title>
  <!--or use anime.min.js-->
  <script src="anime.js"></script>
  <link rel="stylesheet" href="style.css">
</head>
<body>
<div class="anime-container">
</div>
<script src="script.js"></script>
</body>
</html>

CSS 文件 styles.css 用来定义页面和每一个粒子的背景色。位置是必须要设置的,稍后咱们能够用 CSS 属性 lefttop 在页面上自由放置粒子。程序员

body {
 background-color: hsl(30, 3%, 14%);
}
.anime-container {
  position: relative;
}
 
.anime-container .dot{
  position: absolute;
  /*draw particles as circles:*/
  border-radius: 50%;
  background-color: hsl(60, 100%, 80%);
}

生成粒子

顾名思义,粒子动画由许多遵循特定模式在空间中移动的小粒子组成。在动画开始以前,同时生成全部粒子。github

对于如下解释,anime.js的官方文档 对你很是有用。面试

在个人例子中,粒子位于阿基米德螺旋上。屏幕上粒子的 x 和 y 位置(在 CSS 中又称为 lefttop)是根据其在螺旋上的位置 angle 来计算的:编程

x=a*angle*cos(angle)
y=a*angle*sin⁡(angle)

角度以及螺旋的长度由参数 l 肯定。经过参数 a,你能够控制螺旋线的密度。

var container = document.querySelector(".anime-container");
var n = 15;
var a = 20;
var l = 110;
for (var i = 0; i <= l; i += 1) {
  var angle = 0.1 * i;
  //shift the particles to the center of the window 
  //by adding half of the screen width and screen height
  var x = (a*angle) * Math.cos(angle) + window.innerWidth / 2;
  var y = (a*angle) * Math.sin(angle) + window.innerHeight / 2;
  var dot = document.createElement("div");
  dot.classList.add("dot");
  container.appendChild(dot);
  var size = 5;
  dot.style.width = size + "px";
  dot.style.height = size + "px";
  dot.style.left = x + "px";
  dot.style.top = y + "px";
  dot.style.backgroundColor = "hsl(60, 100%, 80%)";
  }
}

5-partical-trail-animation-javascript.png

这样,咱们获得一个螺旋,每一个位置只有一个粒子,可是只有在每一个位置生成一个以上的粒子时,才能实现真正的拖尾效果。为了使轨迹显得浓密,各个粒子的位置必须略有不一样。动画库为此提供了实用的辅助函数:

anime.random(minValue, maxValue);

粒子的大小也随机变化:

for (var i = 0; i <= l; i += 1) {
  var angle = 0.1 * i;
  //shift particles to the center of the window 
  //by adding half of the screen width and screen height
  var x = (a*angle) * Math.cos(angle) + window.innerWidth / 2;
  var y = (a*angle) * Math.sin(angle) + window.innerHeight / 2;
  var n = 15;
  
  //create n particles for each angle
  for (var j = 0; j < n; j++) {
    var dot = document.createElement("div");
    dot.classList.add("dot");
    container.appendChild(dot);
    var size = anime.random(5, 10); 
    dot.style.width = size + "px";
    dot.style.height = size + "px";
    dot.style.left = x + anime.random(-15, 15) + "px";
    dot.style.top = y + anime.random(-15, 15) + "px";
    dot.style.backgroundColor = "hsl(60, 100%, 80%)";
  }
}

3-partical-trail-animation-javascript.png

在这里,你能够尝试中间结果:

请参阅 CodePen 上的 js 粒子动画 wip:https://codepen.io/smashingma...

在动画开始以前,全部粒子都必须是不可见的。因此我将添加:

dot.style.opacity = "0";

粒子动画

动画的基本设置

个人动画的基本设置以下:

  • 动画要连续重复(loop:true),
  • 移动是线性的(可是你能够尝试不一样的值),
  • 目标是全部带有 "dot" 类的元素。
anime({
  loop: true,
  easing: "linear",
  targets: document.querySelectorAll(".dot"),
});

在下一步中,我将为目标的各类 CSS 属性设置动画。 CSS 动画的基本步骤能够在 anime.js 文档中属性相关的章节中找到。

动画效果

这是咱们第一个属性动画的样子,其中全部粒子在 50 毫秒内逐渐可见:

anime({
  loop: true,
  easing: "linear",
  targets: document.querySelectorAll(".dot"),
  opacity: { value: 1, duration: 50}
});

如今,我将揭示致使粒子螺旋运动的技巧!想法是使粒子以必定的时间延迟(例如,以 2 ms 的间隔)可见。首先使螺旋中间的粒子可见,而后从内到外的使全部其余粒子可见。 anime.js 的 stagger 函数很是适合此功能。我认为,交错是该库的最大优点之一,它使你能够实现出色的效果。

opacity: { value: 1, duration: 50, delay: anime.stagger(2) }

为了产生飞行轨迹的错觉,粒子一旦出现就必须开始缓慢消失。幸运的是 anime.js 提供了属性的关键帧符号

opacity: [
    { value: 1, duration: 50, delay: anime.stagger(2) },
    { value: 0, duration: 1200}
  ],

在这里,你能够看到中间结果:

请参阅 CodePen 上的 js 粒子动画 wip 2:https://codepen.io/smashingma...

动画大小

彗星踪影出现时应该比消失前更大。为此,我让粒子在 500ms 内缩小到 2px 的直径。选择与不透明度动画相同的时间延迟很重要,这样每一个粒子只有在出现后才开始收缩:

width: { value: 2, duration: 500, delay: anime.stagger(2) },
height: { value: 2, duration: 500, delay: anime.stagger(2) },

个体运动

粒子动画的典型特征是粒子的独立性、不可预测的行为。最后,我经过沿 xy 方向的运动将粒子带入动画:

translateX: {
    value: function() {
      return anime.random(-30, 30);
    },
    duration: 1500,
    delay: anime.stagger(2)
  },

translateY: {
    value: function() {
      return anime.random(-30, 30);
    },
    duration: 1500,
    delay: anime.stagger(2)
  }

一样,重要的是运动开始的时间应该与粒子的出现有相同的时间延迟。

另外在这种状况下,绝对有必要用 functions 来计算 translateXtranslateY 的值。在这里,咱们将参数用做基于函数的参数,其值是针对每一个目标单所独肯定的。不然全部目标移动相同的量都会是相同的(尽管是随机肯定的)。

最后的想法

你能够在此处查看最终结果:

请参阅查看 CodePen 上的 js 动画粒子:https://codepen.io/smashingma...

你能够经过简单地调整这些值来根据本身的喜爱修改动画。关于最后的修饰有一个小技巧:如今咱们熟悉了基于函数的参数,能够稍微改善动画的透明度:

opacity: [
    { value: 1, duration: 50, delay: anime.stagger(2) },
    { value: 0, duration: function(){return anime.random(500,1500);}}
],

如今分别为每一个粒子设置粒子消失以前的持续时间。这可以使动画在视觉上更加精致。

我建议你访问 CodePen,在这里你能够看到更多使人印象深入的例子。


本文首发微信公众号:前端先锋

欢迎扫描二维码关注公众号,天天都给你推送新鲜的前端技术文章

欢迎扫描二维码关注公众号,天天都给你推送新鲜的前端技术文章

欢迎继续阅读本专栏其它高赞文章:


相关文章
相关标签/搜索