粒子效果实现分析

效果是这样的

代码是这样的

引入

npm install vue-particles --save-dev
// 引入粒子背景的js
import VueParticles from 'vue-particles'
Vue.use(VueParticles)  

写入界面

<vue-particles color="#e5e5e5"></vue-particles>

全部属性

color: String类型。默认'#dedede'。粒子颜色。

particleOpacity: Number类型。默认0.7。粒子透明度。

particlesNumber: Number类型。默认80。粒子数量。

shapeType: String类型。默认'circle'。可用的粒子外观类型有:"circle","edge","triangle", "polygon","star"。

particleSize: Number类型。默认80。单个粒子大小。

linesColor: String类型。默认'#dedede'。线条颜色。

linesWidth: Number类型。默认1。线条宽度。

lineLinked: 布尔类型。默认true。连接线是否可用。

lineOpacity: Number类型。默认0.4。线条透明度。

linesDistance: Number类型。默认150。线条距离。

moveSpeed: Number类型。默认3。粒子运动速度。

hoverEffect: 布尔类型。默认true。是否有hover特效。

hoverMode: String类型。默认true。可用的hover模式有: "grab", "repulse", "bubble"。

clickEffect: 布尔类型。默认true。是否有click特效。

clickMode: String类型。默认true。可用的click模式有: "push", "remove", "repulse", "bubble"。

上原理分析图

实际js库地址

https://github.com/VincentGarreau/particles.js

我们分析一下这个效果:

主要包括生成点,点连接点,点移动,鼠标悬停点击触动点

生成点

nb表示节点总数量
 for(var i = 0; i < nb; i++){
//放入数组中
      pJS.particles.array.push(
        new pJS.fn.particle(
          pJS.particles.color,
          pJS.particles.opacity.value,
          {
            'x': pos ? pos.pos_x : Math.random() * pJS.canvas.w,
            'y': pos ? pos.pos_y : Math.random() * pJS.canvas.h
          }
        )
      )

点连接点(线)

pJS.fn.interact.linkParticles = function(p1, p2){
//获取两点的直线距离
    var dx = p1.x - p2.x,
        dy = p1.y - p2.y,
        dist = Math.sqrt(dx*dx + dy*dy);

   //小于设定的最远两点(默认是100)
    if(dist <= pJS.particles.line_linked.distance){

      var opacity_line = pJS.particles.line_linked.opacity - (dist / (1/pJS.particles.line_linked.opacity)) / pJS.particles.line_linked.distance;

      if(opacity_line > 0){        
        
        //构建线的样式
        var color_line = pJS.particles.line_linked.color_rgb_line;
        pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')';
        pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width;
        //pJS.canvas.ctx.lineCap = 'round'; /* performance issue */
        
        //通过canvas画线
        pJS.canvas.ctx.beginPath();
        pJS.canvas.ctx.moveTo(p1.x, p1.y);
        pJS.canvas.ctx.lineTo(p2.x, p2.y);
        pJS.canvas.ctx.stroke();
        pJS.canvas.ctx.closePath();

      }

    }

  };

点移动

 if(pJS.particles.move.enable){
        //按照速度计算上下一个点位置,
        var ms = pJS.particles.move.speed/2;
        p.x += p.vx * ms;
        p.y += p.vy * ms;
}

鼠标悬停点击触动点(补充上一点 p.vx和p.vy)

//其中的一种计算出点方法(远离鼠标)
pJS.fn.modes.grabParticle = function(p){
    if(pJS.interactivity.events.onhover.enable && pJS.interactivity.status == 'mousemove'){
//这里获取了当前鼠标的位置
      var dx_mouse = p.x - pJS.interactivity.mouse.pos_x,
          dy_mouse = p.y - pJS.interactivity.mouse.pos_y,
          dist_mouse = Math.sqrt(dx_mouse*dx_mouse + dy_mouse*dy_mouse);

      if(dist_mouse <= pJS.interactivity.modes.grab.distance){
        var opacity_line = pJS.interactivity.modes.grab.line_linked.opacity - (dist_mouse / (1/pJS.interactivity.modes.grab.line_linked.opacity)) / pJS.interactivity.modes.grab.distance;

        if(opacity_line > 0){
          /* style */
          var color_line = pJS.particles.line_linked.color_rgb_line;
          pJS.canvas.ctx.strokeStyle = 'rgba('+color_line.r+','+color_line.g+','+color_line.b+','+opacity_line+')';
          pJS.canvas.ctx.lineWidth = pJS.particles.line_linked.width;
          //pJS.canvas.ctx.lineCap = 'round'; /* performance issue */
          
          /* path */
          pJS.canvas.ctx.beginPath();
          pJS.canvas.ctx.moveTo(p.x, p.y);
          pJS.canvas.ctx.lineTo(pJS.interactivity.mouse.pos_x, pJS.interactivity.mouse.pos_y);
          pJS.canvas.ctx.stroke();
          pJS.canvas.ctx.closePath();

        }

      }

    }

  };

完毕

发布了58 篇原创文章 · 获赞 10 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_34203714/article/details/99684617