经常看到有些SEO博客网站上有这种用动态线条作为网站背景的效果,当鼠标移动上去的时候会出现线条吸附在鼠标周围的特效,鼠标离开的时候线条就自动散开。这个效果之前在我的博客上也有加过,后来网站改版就没有继续用了,其实效果还是挺不错的。这种网站动态背景线条跟随鼠标移动,吸附鼠标效果代码是用JS来实现的,代码如下,喜欢的朋友可以为自己的博客添加。添加方法:将下方代码复制到网站想添加线条跟随鼠标移动效果的页面上方或添加到网站底部模板文件 foot.htm 里面,如果不喜欢页面代码太多,也可以写到JS文件里来进行调用。

特点:

1、不依赖jQuery等任何框架或者内库

2、原生javascript

3、使用外链

4、JS文件已经存储在CDN上,可以直接使用,支持ssl协议外链,github的外链

【引用代码】

<script type="text/javascript" src="https://cdn.bootcss.com/canvas-nest.js/1.0.1/canvas-nest.min.js"></script>

【JS代码】

!function(){function n(n,e,t){return n.getAttribute(e)||t}function e(n){return document.getElementsByTagName(n)}function t(){var t=e("script"),o=t.length,i=t[o-1];return{l:o,z:n(i,"zIndex",-1),o:n(i,"opacity",.5),c:n(i,"color","0,0,0"),n:n(i,"count",99)}}function o(){a=m.width=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,c=m.height=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}function i(){r.clearRect(0,0,a,c);var n,e,t,o,m,l;s.forEach(function(i,x){for(i.x+=i.xa,i.y+=i.ya,i.xa*=i.x>a||i.x<0?-1:1,i.ya*=i.y>c||i.y<0?-1:1,r.fillRect(i.x-.5,i.y-.5,1,1),e=x+1;e<u.length;e++)n=u[e],null!==n.x&&null!==n.y&&(o=i.x-n.x,m=i.y-n.y,l=o*o+m*m,l<n.max&&(n===y&&l>=n.max/2&&(i.x-=.03*o,i.y-=.03*m),t=(n.max-l)/n.max,r.beginPath(),r.lineWidth=t/2,r.strokeStyle="rgba("+d.c+","+(t+.2)+")",r.moveTo(i.x,i.y),r.lineTo(n.x,n.y),r.stroke()))}),x(i)}var a,c,u,m=document.createElement("canvas"),d=t(),l="c_n"+d.l,r=m.getContext("2d"),x=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(n){window.setTimeout(n,1e3/45)},w=Math.random,y={x:null,y:null,max:2e4};m.id=l,m.style.cssText="position:fixed;top:0;left:0;z-index:"+d.z+";opacity:"+d.o,e("body")[0].appendChild(m),o(),window.οnresize=o,window.οnmοusemοve=function(n){n=n||window.event,y.x=n.clientX,y.y=n.clientY},window.οnmοuseοut=function(){y.x=null,y.y=null};for(var s=[],f=0;d.n>f;f++){var h=w()*a,g=w()*c,v=2*w()-1,p=2*w()-1;s.push({x:h,y:g,xa:v,ya:p,max:6e3})}u=s.concat([y]),setTimeout(function(){i()},100)}();

附:网站动态背景线条跟随鼠标移动,吸附鼠标效果

动态背景线条,鼠标移动可以吸附,可以添加配置,代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>粒子线条canvas效果</title>
    <style>
        #J_dotLine {
            display: block;
            margin: 0 auto;
        }
    </style>
</head>

<body>
    <canvas id="J_dotLine"></canvas>
    <script>
        ; (function (window) {
            function Dotline(option) {
                this.opt = this.extend({
                    dom: 'J_dotLine',//画布id
                    cw: 1000,//画布宽
                    ch: 500,//画布高
                    ds: 100,//点的个数
                    r: 0.5,//圆点半径
                    cl: '#000',//颜色
                    dis: 100//触发连线的距离
                }, option);
                this.c = document.getElementById(this.opt.dom);//canvas元素id
                this.ctx = this.c.getContext('2d');
                this.c.width = this.opt.cw;//canvas宽
                this.c.height = this.opt.ch;//canvas高
                this.dotSum = this.opt.ds;//点的数量
                this.radius = this.opt.r;//圆点的半径
                this.disMax = this.opt.dis * this.opt.dis;//点与点触发连线的间距
                this.color = this.color2rgb(this.opt.cl);//设置粒子线颜色
                this.dots = [];
                //requestAnimationFrame控制canvas动画
                var RAF = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
                    window.setTimeout(callback, 1000 / 60);
                };
                var _self = this;
                //增加鼠标效果
                var mousedot = { x: null, y: null, label: 'mouse' };
                this.c.onmousemove = function (e) {
                    var e = e || window.event;
                    mousedot.x = e.clientX - _self.c.offsetLeft;
                    mousedot.y = e.clientY - _self.c.offsetTop;
                };
                this.c.onmouseout = function (e) {
                    mousedot.x = null;
                    mousedot.y = null;
                }
                //控制动画
                this.animate = function () {
                    _self.ctx.clearRect(0, 0, _self.c.width, _self.c.height);
                    _self.drawLine([mousedot].concat(_self.dots));
                    RAF(_self.animate);
                };
            }
            //合并配置项,es6直接使用obj.assign();
            Dotline.prototype.extend = function (o, e) {
                for (var key in e) {
                    if (e[key]) {
                        o[key] = e[key]
                    }
                }
                return o;
            };
            Dotline.prototype.color2rgb = function (colorStr) {
                var red = null,
                    green = null,
                    blue = null;
                var cstr = colorStr.toLowerCase();//变小写
                var cReg = /^#[0-9a-fA-F]{3,6}$/;//确定是16进制颜色码
                if (cstr && cReg.test(cstr)) {
                    if (cstr.length == 4) {
                        var cstrnew = '#';
                        for (var i = 1; i < 4; i++) {
                            cstrnew += cstr.slice(i, i + 1).concat(cstr.slice(i, i + 1));
                        }
                        cstr = cstrnew;
                    }
                    red = parseInt('0x' + cstr.slice(1, 3));
                    green = parseInt('0x' + cstr.slice(3, 5));
                    blue = parseInt('0x' + cstr.slice(5, 7));
                }
                return red + ',' + green + ',' + blue;
            }
            //画点
            Dotline.prototype.addDots = function () {
                var dot;
                for (var i = 0; i < this.dotSum; i++) {//参数
                    dot = {
                        x: Math.floor(Math.random() * this.c.width) - this.radius,
                        y: Math.floor(Math.random() * this.c.height) - this.radius,
                        ax: (Math.random() * 2 - 1) / 1.5,
                        ay: (Math.random() * 2 - 1) / 1.5
                    }
                    this.dots.push(dot);
                }
            };
            //点运动
            Dotline.prototype.move = function (dot) {
                dot.x += dot.ax;
                dot.y += dot.ay;
                //点碰到边缘返回
                dot.ax *= (dot.x > (this.c.width - this.radius) || dot.x < this.radius) ? -1 : 1;
                dot.ay *= (dot.y > (this.c.height - this.radius) || dot.y < this.radius) ? -1 : 1;
                //绘制点
                this.ctx.beginPath();
                this.ctx.arc(dot.x, dot.y, this.radius, 0, Math.PI * 2, true);
                this.ctx.stroke();
            };
            //点之间画线
            Dotline.prototype.drawLine = function (dots) {
                var nowDot;
                var _that = this;
                //自己的思路:遍历两次所有的点,比较点之间的距离,函数的触发放在animate里
                this.dots.forEach(function (dot) {

                    _that.move(dot);
                    for (var j = 0; j < dots.length; j++) {
                        nowDot = dots[j];
                        if (nowDot === dot || nowDot.x === null || nowDot.y === null) continue;//continue跳出当前循环开始新的循环
                        var dx = dot.x - nowDot.x,//别的点坐标减当前点坐标
                            dy = dot.y - nowDot.y;
                        var dc = dx * dx + dy * dy;
                        if (Math.sqrt(dc) > Math.sqrt(_that.disMax)) continue;
                        // 如果是鼠标,则让粒子向鼠标的位置移动
                        if (nowDot.label && Math.sqrt(dc) > Math.sqrt(_that.disMax) / 2) {
                            dot.x -= dx * 0.02;
                            dot.y -= dy * 0.02;
                        }
                        var ratio;
                        ratio = (_that.disMax - dc) / _that.disMax;
                        _that.ctx.beginPath();
                        _that.ctx.lineWidth = ratio / 2;
                        _that.ctx.strokeStyle = 'rgba(' + _that.color + ',' + parseFloat(ratio + 0.2).toFixed(1) + ')';
                        _that.ctx.moveTo(dot.x, dot.y);
                        _that.ctx.lineTo(nowDot.x, nowDot.y);
                        _that.ctx.stroke();//不描边看不出效果

                        //dots.splice(dots.indexOf(dot), 1);
                    }
                });
            };
            //开始动画
            Dotline.prototype.start = function () {
                var _that = this;
                this.addDots();
                setTimeout(function () {
                    _that.animate();
                }, 100);
            }
            window.Dotline = Dotline;
        }(window));
        //调用
        window.onload = function () {
            var dotline = new Dotline({
                dom: 'J_dotLine',//画布id
                cw: 1000,//画布宽
                ch: 500,//画布高
                ds: 100,//点的个数
                r: 0.5,//圆点半径
                cl: '#fff',//粒子线颜色
                dis: 100//触发连线的距离
            }).start();
        }
    </script>
</body>

</html>

vue,react写法,类分装:
创建一个dotline.js

class Dotline {
  constructor(option) {
    this.opt = this.extend({
      dom: 'J_dotLine',//画布id
      cw: 1000,//画布宽
      ch: 500,//画布高
      ds: 100,//点的个数
      r: 0.5,//圆点半径
      cl: '#000',//颜色
      dis: 100//触发连线的距离
    }, option);
    this.c = document.getElementById(this.opt.dom);//canvas元素id
    this.ctx = this.c.getContext('2d');
    this.c.width = this.opt.cw;//canvas宽
    this.c.height = this.opt.ch;//canvas高
    this.dotSum = this.opt.ds;//点的数量
    this.radius = this.opt.r;//圆点的半径
    this.disMax = this.opt.dis * this.opt.dis;//点与点触发连线的间距
    this.color = this.color2rgb(this.opt.cl);//设置粒子线颜色
    this.dots = [];
    //requestAnimationFrame控制canvas动画
    var RAF = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
      window.setTimeout(callback, 1000 / 60);
    };
    var _self = this;
    //增加鼠标效果
    var mousedot = { x: null, y: null, label: 'mouse' };
    this.c.onmousemove = function (e) {
      var e = e || window.event;
      mousedot.x = e.clientX - _self.c.offsetLeft;
      mousedot.y = e.clientY - _self.c.offsetTop;
    };
    this.c.onmouseout = function (e) {
      mousedot.x = null;
      mousedot.y = null;
    }
    //控制动画
    this.animate = function () {
      _self.ctx.clearRect(0, 0, _self.c.width, _self.c.height);
      _self.drawLine([mousedot].concat(_self.dots));
      RAF(_self.animate);
    };
  }

  //合并配置项,es6直接使用obj.assign();
  extend(o, e) {
    for (var key in e) {
      if (e[key]) {
        o[key] = e[key]
      }
    }
    return o;
  }

  //设置线条颜色
  color2rgb(colorStr) {
    var red = null,
      green = null,
      blue = null;
    var cstr = colorStr.toLowerCase();//变小写
    var cReg = /^#[0-9a-fA-F]{3,6}$/;//确定是16进制颜色码
    if (cstr && cReg.test(cstr)) {
      if (cstr.length == 4) {
        var cstrnew = '#';
        for (var i = 1; i < 4; i++) {
          cstrnew += cstr.slice(i, i + 1).concat(cstr.slice(i, i + 1));
        }
        cstr = cstrnew;
      }
      red = parseInt('0x' + cstr.slice(1, 3));
      green = parseInt('0x' + cstr.slice(3, 5));
      blue = parseInt('0x' + cstr.slice(5, 7));
    }
    return red + ',' + green + ',' + blue;
  }

  //画点
  addDots() {
    var dot;
    for (var i = 0; i < this.dotSum; i++) {//参数
      dot = {
        x: Math.floor(Math.random() * this.c.width) - this.radius,
        y: Math.floor(Math.random() * this.c.height) - this.radius,
        ax: (Math.random() * 2 - 1) / 1.5,
        ay: (Math.random() * 2 - 1) / 1.5
      }
      this.dots.push(dot);
    }
  }

  //点运动
  move(dot) {
    dot.x += dot.ax;
    dot.y += dot.ay;
    //点碰到边缘返回
    dot.ax *= (dot.x > (this.c.width - this.radius) || dot.x < this.radius) ? -1 : 1;
    dot.ay *= (dot.y > (this.c.height - this.radius) || dot.y < this.radius) ? -1 : 1;
    //绘制点
    this.ctx.beginPath();
    this.ctx.arc(dot.x, dot.y, this.radius, 0, Math.PI * 2, true);
    this.ctx.stroke();
  }

  //点之间画线
  drawLine(dots) {
    var nowDot;
    var _that = this;
    //自己的思路:遍历两次所有的点,比较点之间的距离,函数的触发放在animate里
    this.dots.forEach(function (dot) {

      _that.move(dot);
      for (var j = 0; j < dots.length; j++) {
        nowDot = dots[j];
        if (nowDot === dot || nowDot.x === null || nowDot.y === null) continue;//continue跳出当前循环开始新的循环
        var dx = dot.x - nowDot.x,//别的点坐标减当前点坐标
          dy = dot.y - nowDot.y;
        var dc = dx * dx + dy * dy;
        if (Math.sqrt(dc) > Math.sqrt(_that.disMax)) continue;
        // 如果是鼠标,则让粒子向鼠标的位置移动
        if (nowDot.label && Math.sqrt(dc) > Math.sqrt(_that.disMax) / 2) {
          dot.x -= dx * 0.02;
          dot.y -= dy * 0.02;
        }
        var ratio;
        ratio = (_that.disMax - dc) / _that.disMax;
        _that.ctx.beginPath();
        _that.ctx.lineWidth = ratio / 2;
        _that.ctx.strokeStyle = 'rgba(' + _that.color + ',' + parseFloat(ratio + 0.2).toFixed(1) + ')';
        _that.ctx.moveTo(dot.x, dot.y);
        _that.ctx.lineTo(nowDot.x, nowDot.y);
        _that.ctx.stroke();//不描边看不出效果

        //dots.splice(dots.indexOf(dot), 1);
      }
    });
  }

  //开始动画
  start() {
    var _that = this;
    this.addDots();
    setTimeout(function () {
      _that.animate();
    }, 100);
  }
}

export default Dotline;

调用方法:
html:

<canvas id="J_dotLine"></canvas>

js:

import Dotline from "./dotline.js";

const option = {
   dom: 'J_dotLine',//画布id
   cw: 1000,//画布宽
   ch: 500,//画布高
   ds: 250,//点的个数
   r: 3,//圆点半径
   cl: '#061eb3',//粒子线颜色
   dis: 120//触发连线的距离
 }
const dotline = new Dotline(option).start();

JS代码不利于搜索引擎优化,也会在一定程度上增加网站加载时间,因此,如果你不喜欢这个效果,可以看看用CSS在网站底部加上蒲公英动态效果的实现方法


一个好奇的人