文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript+Canvas实现酷炫的粒子和流星效果

2023-01-31 12:04

关注

一:粒子效果

<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>

效果图

二:流星效果

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>一起来看流星雨</title>
</head>
<style type="text/css">
  body {
    background-color: black;
  }

  body,
  html {
    width: 100%;
    height: 100%;
    overflow: hidden;
  }
</style>

<body>
  <canvas id="stars"></canvas>
</body>

</html>
<script>
  var context;
  var arr = new Array();
  var starCount = 800;
  var rains = new Array();
  var rainCount = 20;
  //初始化画布及context
  function init() {
    //获取canvas
    var stars = document.getElementById("stars");
    windowWidth = window.innerWidth; //当前的窗口的高度
    stars.width = windowWidth;
    stars.height = window.innerHeight;
    //获取context
    context = stars.getContext("2d");
  }
  //创建一个星星对象
  var Star = function () {
    this.x = windowWidth * Math.random();//横坐标
    this.y = 5000 * Math.random();//纵坐标
    this.text = ".";//文本
    this.color = "white";//颜色
    //产生随机颜色
    this.getColor = function () {
      var _r = Math.random();
      if (_r < 0.5) {
        this.color = "#333";
      } else {
        this.color = "white";
      }
    }
    //初始化
    this.init = function () {
      this.getColor();
    }
    //绘制
    this.draw = function () {
      context.fillStyle = this.color;
      context.fillText(this.text, this.x, this.y);
    }
  }
  //画月亮
  function drawMoon() {
    var moon = new Image();
    moon.src = "./images/moon.jpg"
    context.drawImage(moon, -5, -10);
  }
  //页面加载的时候
  window.onload = function () {
    init();
    //画星星
    for (var i = 0; i < starCount; i++) {
      var star = new Star();
      star.init();
      star.draw();
      arr.push(star);
    }
    //画流星
    for (var i = 0; i < rainCount; i++) {
      var rain = new MeteorRain();
      rain.init();
      rain.draw();
      rains.push(rain);
    }
    drawMoon();//绘制月亮
    playStars();//绘制闪动的星星
    playRains();//绘制流星

  }
  //星星闪起来
  function playStars() {
    for (var n = 0; n < starCount; n++) {
      arr[n].getColor();
      arr[n].draw();
    }

    setTimeout("playStars()", 100);
  }

  
  var MeteorRain = function () {
    this.x = -1;
    this.y = -1;
    this.length = -1;//长度
    this.angle = 30; //倾斜角度
    this.width = -1;//宽度
    this.height = -1;//高度
    this.speed = 1;//速度
    this.offset_x = -1;//横轴移动偏移量
    this.offset_y = -1;//纵轴移动偏移量
    this.alpha = 1; //透明度
    this.color1 = "";//流星的色彩
    this.color2 = ""; //流星的色彩
    
    this.init = function () //初始化
    {
      this.getPos();
      this.alpha = 1;//透明度
      this.getRandomColor();
      //最小长度,最大长度
      var x = Math.random() * 80 + 150;
      this.length = Math.ceil(x);
      //         x = Math.random()*10+30;
      this.angle = 30; //流星倾斜角
      x = Math.random() + 0.5;
      this.speed = Math.ceil(x); //流星的速度
      var cos = Math.cos(this.angle * 3.14 / 180);
      var sin = Math.sin(this.angle * 3.14 / 180);
      this.width = this.length * cos; //流星所占宽度
      this.height = this.length * sin;//流星所占高度
      this.offset_x = this.speed * cos;
      this.offset_y = this.speed * sin;
    }
    
    this.getRandomColor = function () {
      var a = Math.ceil(255 - 240 * Math.random());
      //中段颜色
      this.color1 = "rgba(" + a + "," + a + "," + a + ",1)";
      //结束颜色
      this.color2 = "black";
    }
    
    this.countPos = function ()//
    {
      //往左下移动,x减少,y增加
      this.x = this.x - this.offset_x;
      this.y = this.y + this.offset_y;
    }
    
    this.getPos = function () //
    {
      //横坐标200--1200
      this.x = Math.random() * window.innerWidth; //窗口高度
      //纵坐标小于600
      this.y = Math.random() * window.innerHeight; //窗口宽度
    }
    
    this.draw = function () //绘制一个流星的函数
    {
      context.save();
      context.beginPath();
      context.lineWidth = 1; //宽度
      context.globalAlpha = this.alpha; //设置透明度
      //创建横向渐变颜色,起点坐标至终点坐标
      var line = context.createLinearGradient(this.x, this.y,
        this.x + this.width,
        this.y - this.height);
      //分段设置颜色
      line.addColorStop(0, "white");
      line.addColorStop(0.3, this.color1);
      line.addColorStop(0.6, this.color2);
      context.strokeStyle = line;
      //起点
      context.moveTo(this.x, this.y);
      //终点
      context.lineTo(this.x + this.width, this.y - this.height);
      context.closePath();
      context.stroke();
      context.restore();
    }
    this.move = function () {
      //清空流星像素
      var x = this.x + this.width - this.offset_x;
      var y = this.y - this.height;
      context.clearRect(x - 3, y - 3, this.offset_x + 5, this.offset_y + 5);
      //         context.strokeStyle="red";
      //         context.strokeRect(x,y-1,this.offset_x+1,this.offset_y+1);
      //重新计算位置,往左下移动
      this.countPos();
      //透明度增加
      this.alpha -= 0.002;
      //重绘
      this.draw();
    }
  }
  //绘制流星
  function playRains() {

    for (var n = 0; n < rainCount; n++) {
      var rain = rains[n];
      rain.move();//移动
      if (rain.y > window.innerHeight) {//超出界限后重来
        context.clearRect(rain.x, rain.y - rain.height, rain.width, rain.height);
        rains[n] = new MeteorRain();
        rains[n].init();
      }
    }
    setTimeout("playRains()", 2);
  }

</script>

效果图

到此这篇关于JavaScript+Canvas实现酷炫的粒子和流星效果的文章就介绍到这了,更多相关JavaScript粒子流星内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯