基于canvas的粒子酷炫效果,可用作可视化大屏的背景展示,即拿即用......

简介: 基于canvas的粒子酷炫效果,可用作可视化大屏的背景展示,即拿即用......
<html>
<head>
  <meta charset="utf-8">
  <title>www.husonghe.com</title>
  <style>
    html {
      height: 100%;
      background-image: -webkit-radial-gradient(ellipse farthest-corner at center center, #1b44e4 0%, #020f3a 100%);
      background-image: radial-gradient(ellipse farthest-corner at center center, #1b44e4 0%, #020f3a 100%);
      cursor: move;
    }
    body {
      width: 100%;
      margin: 0;
      overflow: hidden;
    }
  </style>
</head>
<body>
  <canvas id="canv" width="1920" height="572"></canvas>
  <script>
    var num = 200;
    var w = window.innerWidth;
    var h = window.innerHeight;
    var max = 100;
    var _x = 0;
    var _y = 0;
    var _z = 150;
    var dtr = function (d) {
      return d * Math.PI / 180;
    };
    var rnd = function () {
      return Math.sin(Math.floor(Math.random() * 360) * Math.PI / 180);
    };
    var dist = function (p1, p2, p3) {
      return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2) + Math.pow(p2.z - p1.z, 2));
    };
    var cam = {
      obj: {
        x: _x,
        y: _y,
        z: _z
      },
      dest: {
        x: 0,
        y: 0,
        z: 1
      },
      dist: {
        x: 0,
        y: 0,
        z: 200
      },
      ang: {
        cplane: 0,
        splane: 0,
        ctheta: 0,
        stheta: 0
      },
      zoom: 1,
      disp: {
        x: w / 2,
        y: h / 2,
        z: 0
      },
      upd: function () {
        cam.dist.x = cam.dest.x - cam.obj.x;
        cam.dist.y = cam.dest.y - cam.obj.y;
        cam.dist.z = cam.dest.z - cam.obj.z;
        cam.ang.cplane = -cam.dist.z / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.z * cam.dist.z);
        cam.ang.splane = cam.dist.x / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.z * cam.dist.z);
        cam.ang.ctheta = Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.z * cam.dist.z) / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.y * cam.dist.y + cam.dist.z * cam.dist.z);
        cam.ang.stheta = -cam.dist.y / Math.sqrt(cam.dist.x * cam.dist.x + cam.dist.y * cam.dist.y + cam.dist.z * cam.dist.z);
      }
    };
    var trans = {
      parts: {
        sz: function (p, sz) {
          return {
            x: p.x * sz.x,
            y: p.y * sz.y,
            z: p.z * sz.z
          };
        },
        rot: {
          x: function (p, rot) {
            return {
              x: p.x,
              y: p.y * Math.cos(dtr(rot.x)) - p.z * Math.sin(dtr(rot.x)),
              z: p.y * Math.sin(dtr(rot.x)) + p.z * Math.cos(dtr(rot.x))
            };
          },
          y: function (p, rot) {
            return {
              x: p.x * Math.cos(dtr(rot.y)) + p.z * Math.sin(dtr(rot.y)),
              y: p.y,
              z: -p.x * Math.sin(dtr(rot.y)) + p.z * Math.cos(dtr(rot.y))
            };
          },
          z: function (p, rot) {
            return {
              x: p.x * Math.cos(dtr(rot.z)) - p.y * Math.sin(dtr(rot.z)),
              y: p.x * Math.sin(dtr(rot.z)) + p.y * Math.cos(dtr(rot.z)),
              z: p.z
            };
          }
        },
        pos: function (p, pos) {
          return {
            x: p.x + pos.x,
            y: p.y + pos.y,
            z: p.z + pos.z
          };
        }
      },
      pov: {
        plane: function (p) {
          return {
            x: p.x * cam.ang.cplane + p.z * cam.ang.splane,
            y: p.y,
            z: p.x * -cam.ang.splane + p.z * cam.ang.cplane
          };
        },
        theta: function (p) {
          return {
            x: p.x,
            y: p.y * cam.ang.ctheta - p.z * cam.ang.stheta,
            z: p.y * cam.ang.stheta + p.z * cam.ang.ctheta
          };
        },
        set: function (p) {
          return {
            x: p.x - cam.obj.x,
            y: p.y - cam.obj.y,
            z: p.z - cam.obj.z
          };
        }
      },
      persp: function (p) {
        return {
          x: p.x * cam.dist.z / p.z * cam.zoom,
          y: p.y * cam.dist.z / p.z * cam.zoom,
          z: p.z * cam.zoom,
          p: cam.dist.z / p.z
        };
      },
      disp: function (p, disp) {
        return {
          x: p.x + disp.x,
          y: -p.y + disp.y,
          z: p.z + disp.z,
          p: p.p
        };
      },
      steps: function (_obj_, sz, rot, pos, disp) {
        var _args = trans.parts.sz(_obj_, sz);
        _args = trans.parts.rot.x(_args, rot);
        _args = trans.parts.rot.y(_args, rot);
        _args = trans.parts.rot.z(_args, rot);
        _args = trans.parts.pos(_args, pos);
        _args = trans.pov.plane(_args);
        _args = trans.pov.theta(_args);
        _args = trans.pov.set(_args);
        _args = trans.persp(_args);
        _args = trans.disp(_args, disp);
        return _args;
      }
    };
    (function () {
      "use strict";
      var threeD = function (param) {
        this.transIn = {};
        this.transOut = {};
        this.transIn.vtx = (param.vtx);
        this.transIn.sz = (param.sz);
        this.transIn.rot = (param.rot);
        this.transIn.pos = (param.pos);
      };
      threeD.prototype.vupd = function () {
        this.transOut = trans.steps(
          this.transIn.vtx,
          this.transIn.sz,
          this.transIn.rot,
          this.transIn.pos,
          cam.disp
        );
      };
      var Build = function () {
        this.vel = 0.04;
        this.lim = 360;
        this.diff = 200;
        this.initPos = 100;
        this.toX = _x;
        this.toY = _y;
        this.go();
      };
      Build.prototype.go = function () {
        this.canvas = document.getElementById("canv");
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
        this.$ = canv.getContext("2d");
        this.$.globalCompositeOperation = 'source-over';
        this.varr = [];
        this.dist = [];
        this.calc = [];
        for (var i = 0, len = num; i < len; i++) {
          this.add();
        }
        this.rotObj = {
          x: 0,
          y: 0,
          z: 0
        };
        this.objSz = {
          x: w / 5,
          y: h / 5,
          z: w / 5
        };
      };
      Build.prototype.add = function () {
        this.varr.push(new threeD({
          vtx: {
            x: rnd(),
            y: rnd(),
            z: rnd()
          },
          sz: {
            x: 0,
            y: 0,
            z: 0
          },
          rot: {
            x: 20,
            y: -20,
            z: 0
          },
          pos: {
            x: this.diff * Math.sin(360 * Math.random() * Math.PI / 180),
            y: this.diff * Math.sin(360 * Math.random() * Math.PI / 180),
            z: this.diff * Math.sin(360 * Math.random() * Math.PI / 180)
          }
        }));
        this.calc.push({
          x: 360 * Math.random(),
          y: 360 * Math.random(),
          z: 360 * Math.random()
        });
      };
      Build.prototype.upd = function () {
        cam.obj.x += (this.toX - cam.obj.x) * 0.05;
        cam.obj.y += (this.toY - cam.obj.y) * 0.05;
      };
      Build.prototype.draw = function () {
        this.$.clearRect(0, 0, this.canvas.width, this.canvas.height);
        cam.upd();
        this.rotObj.x += 0.1;
        this.rotObj.y += 0.1;
        this.rotObj.z += 0.1;
        for (var i = 0; i < this.varr.length; i++) {
          for (var val in this.calc[i]) {
            if (this.calc[i].hasOwnProperty(val)) {
              this.calc[i][val] += this.vel;
              if (this.calc[i][val] > this.lim) this.calc[i][val] = 0;
            }
          }
          this.varr[i].transIn.pos = {
            x: this.diff * Math.cos(this.calc[i].x * Math.PI / 180),
            y: this.diff * Math.sin(this.calc[i].y * Math.PI / 180),
            z: this.diff * Math.sin(this.calc[i].z * Math.PI / 180)
          };
          this.varr[i].transIn.rot = this.rotObj;
          this.varr[i].transIn.sz = this.objSz;
          this.varr[i].vupd();
          if (this.varr[i].transOut.p < 0) continue;
          var g = this.$.createRadialGradient(this.varr[i].transOut.x, this.varr[i].transOut.y, this.varr[i].transOut.p, this.varr[i].transOut.x, this.varr[i].transOut.y, this.varr[i].transOut.p * 2);
          this.$.globalCompositeOperation = 'lighter';
          g.addColorStop(0, 'hsla(255, 255%, 255%, 1)');
          g.addColorStop(.5, 'hsla(' + (i + 2) + ',85%, 40%,1)');
          g.addColorStop(1, 'hsla(' + (i) + ',85%, 40%,.5)');
          this.$.fillStyle = g;
          this.$.beginPath();
          this.$.arc(this.varr[i].transOut.x, this.varr[i].transOut.y, this.varr[i].transOut.p * 2, 0, Math.PI * 2, false);
          this.$.fill();
          this.$.closePath();
        }
      };
      Build.prototype.anim = function () {
        window.requestAnimationFrame = (function () {
          return window.requestAnimationFrame ||
            function (callback, element) {
              window.setTimeout(callback, 1000 / 60);
            };
        })();
        var anim = function () {
          this.upd();
          this.draw();
          window.requestAnimationFrame(anim);
        }.bind(this);
        window.requestAnimationFrame(anim);
      };
      Build.prototype.run = function () {
        this.anim();
        window.addEventListener('mousemove', function (e) {
          this.toX = (e.clientX - this.canvas.width / 2) * -0.8;
          this.toY = (e.clientY - this.canvas.height / 2) * 0.8;
        }.bind(this));
        window.addEventListener('touchmove', function (e) {
          e.preventDefault();
          this.toX = (e.touches[0].clientX - this.canvas.width / 2) * -0.8;
          this.toY = (e.touches[0].clientY - this.canvas.height / 2) * 0.8;
        }.bind(this));
        window.addEventListener('mousedown', function (e) {
          for (var i = 0; i < 100; i++) {
            this.add();
          }
        }.bind(this));
        window.addEventListener('touchstart', function (e) {
          e.preventDefault();
          for (var i = 0; i < 100; i++) {
            this.add();
          }
        }.bind(this));
      };
      var app = new Build();
      app.run();
    })();
    window.addEventListener('resize', function () {
      canvas.width = w = window.innerWidth;
      canvas.height = h = window.innerHeight;
    }, false);
  </script>
</body>
</html>
目录
相关文章
|
5月前
|
Linux iOS开发 MacOS
【随手记】maplotlib.use函数设置图像的呈现方式
【随手记】maplotlib.use函数设置图像的呈现方式
56 0
|
6月前
|
编解码 数据可视化
R语言动态可视化:绘制历史全球平均温度的累积动态折线图动画gif视频图
R语言动态可视化:绘制历史全球平均温度的累积动态折线图动画gif视频图
|
数据可视化 前端开发 搜索推荐
数据可视化大屏百度地图GPS轨迹位置感知状态开发实战案例解析(百度地图jsAPI,包含缩放控件、点线覆盖物、弹窗、标注图标分类功能)
数据可视化大屏百度地图GPS轨迹位置感知状态开发实战案例解析(百度地图jsAPI,包含缩放控件、点线覆盖物、弹窗、标注图标分类功能)
281 0
|
数据可视化 物联网
Threejs物联网,养殖场3D可视化(三)模型展示,轨道控制器设置,模型沿着路线运动,模型添加边框,自定义样式显示标签,点击模型获取信息
Threejs物联网,养殖场3D可视化(三)模型展示,轨道控制器设置,模型沿着路线运动,模型添加边框,自定义样式显示标签,点击模型获取信息
942 15
Threejs物联网,养殖场3D可视化(三)模型展示,轨道控制器设置,模型沿着路线运动,模型添加边框,自定义样式显示标签,点击模型获取信息
|
数据可视化 前端开发
漏刻有时数据大屏CSS样式表成长教程(2):九宫格图表背景自适应的解决方案
漏刻有时数据大屏CSS样式表成长教程(2):九宫格图表背景自适应的解决方案
136 1
|
定位技术 API 图形学
unity-2D游戏官方案例--带视频案例(1)(层级渲染,物理碰撞,粒子动画,UI等多位基础一体化)
unity-2D游戏官方案例--带视频案例(1)(层级渲染,物理碰撞,粒子动画,UI等多位基础一体化)
206 1
|
存储 JSON 数据可视化
ChatGPT工作提效之数据可视化大屏组件Echarts的实战方案(大数据量加载、伪3D饼图、地图各省cp中心坐标属性、map3D材质)
ChatGPT工作提效之数据可视化大屏组件Echarts的实战方案(大数据量加载、伪3D饼图、地图各省cp中心坐标属性、map3D材质)
642 0
|
数据可视化 搜索推荐 JavaScript
数据可视化大屏Echarts高级开发散点图实战案例分析(地图扩展插件bmap.min.js、散点图、百度地图控件、柱图、涟漪动图、条件判断颜色)
数据可视化大屏Echarts高级开发散点图实战案例分析(地图扩展插件bmap.min.js、散点图、百度地图控件、柱图、涟漪动图、条件判断颜色)
592 0
|
前端开发
Echarts实战案例代码(49):基于不支持立体漏斗图Funnel的HTML+CSS解决方案
Echarts实战案例代码(49):基于不支持立体漏斗图Funnel的HTML+CSS解决方案
188 0
Echarts实战案例代码(9):图表纹理填充的解决方案(柱图为例)
Echarts实战案例代码(9):图表纹理填充的解决方案(柱图为例)
1501 0