用html+js用canvas 实现刮风下雨特效【建议收藏】

分享一个用js实现下雨特效

1、效果展示

2、代码分享 

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta charset="utf-8">
  <title>Particle Web</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
  </style>
</head>

<body>
  <canvas id="canvas" style="position: absolute; height: 100%; width:100%;">
</canvas>

  <script>
    window.onload = main;

    function getRgb(r, g, b) {
      return "rgb(" + r + "," + g + "," + b + ")";
    }

    function main() {
      //drop
      let dropList = [];
      let gravity = 0.5;
      //
      let linelist = [];
      let canvasEl = document.getElementById('canvas');
      let ctx = canvasEl.getContext('2d');
      let mousePos = [0, 0];
      let backgroundColor = '#000';
      canvasEl.width = canvasEl.clientWidth;
      canvasEl.height = canvasEl.clientHeight;
      let speedx = 0;
      let maxspeedx = 0;

      // 当 window 窗口大小发生改变的时候,重置 canvas 画布的大小
      window.onresize = function () {
        canvasEl.width = canvasEl.clientWidth;
        canvasEl.height = canvasEl.clientHeight;
      }
      // 当鼠标进入 window 窗口时,获取鼠标的位置
      window.onmousemove = function (e) {
        mousePos[0] = e.clientX;
        mousePos[1] = e.clientY;
        maxspeedx = (e.clientX - canvasEl.clientWidth / 2) / (canvasEl.clientWidth / 2);
      }

      function createLine(e) {
        let temp = 0.25 * (50 + Math.random() * 100);
        let myline = {
          speed: 5.5 * (Math.random() * 6 + 3),
          die: false,
          posx: e,
          posy: -200,
          h: temp,
          color: getRgb(Math.floor(temp * 255 / 75), Math.floor(temp * 255 / 75), Math.floor(temp * 255 / 75))
        };
        linelist.push(myline);
      }
      window.requestAnimationFrame(update);
      function createDrop(x, y) {
        let mydrop = {
          die: false,
          posx: x,
          posy: y,
          vx: (Math.random() - 0.5) * 8,
          vy: Math.random() * (-6) - 3,
          radius: Math.random() * 1.5 + 1
        };
        return mydrop;
      }

      function madedrops(x, y) {
        let maxi = Math.floor(Math.random() * 5 + 5);
        for (let i = 0; i < maxi; i++) {
          dropList.push(createDrop(x, y));
        }
      }

      function update() {
        if (dropList.length > 0) {
          dropList.forEach(function (e) {
            e.vx = e.vx + (speedx) / 2;
            e.posx = e.posx + e.vx;
            e.vy = e.vy + gravity;
            e.posy = e.posy + e.vy;
            if (e.posy > canvasEl.clientHeight) {
              e.die = true;
            }
          });
        }
        for (let i = dropList.length - 1; i >= 0; i--) {
          //delite die
          if (dropList[i].die) {
            dropList.splice(i, 1);
          }
        }

        speedx = speedx + (maxspeedx - speedx) / 50;

        if (Math.random() > 0) {
          createLine(Math.random() * 2 * canvasEl.width - (0.5 * canvasEl.width));
          createLine(Math.random() * 2 * canvasEl.width - (0.5 * canvasEl.width));
          createLine(Math.random() * 2 * canvasEl.width - (0.5 * canvasEl.width));
        }
        let mydeadline = canvasEl.clientHeight - Math.random() * canvasEl.clientHeight / 5;
        linelist.forEach(function (e) {
          let dis = Math.sqrt(((e.posx + speedx * e.h) - mousePos[0]) * ((e.posx + speedx * e.h) - mousePos[0]) + (e.posy + e.h - mousePos[1]) * (e.posy + e.h - mousePos[1]));
          if (dis < 35) {
            madedrops(e.posx + speedx * e.h, e.posy + e.h);
            e.die = true;
          }

          if ((e.posy + e.h) > mydeadline) {
            if (Math.random() > 0.85) {
              madedrops(e.posx + speedx * e.h, e.posy + e.h);
              e.die = true;
            }
          }
          if (e.posy >= canvasEl.clientHeight) {
            e.die = true;
          } else {
            e.posy = e.posy + e.speed;
            e.posx = e.posx + (e.speed * speedx);
          }
        });
        for (let i = linelist.length - 1; i >= 0; i--) {
          if (linelist[i].die) {
            linelist.splice(i, 1);
          }
        }
        render();
        window.requestAnimationFrame(update);
      }
      function render() {
        ctx.fillStyle = backgroundColor;
        ctx.fillRect(0, 0, canvasEl.width, canvasEl.height);

        linelist.forEach(
          function (line) {

            ctx.strokeStyle = line.color;
            ctx.lineWidth = 4.5;
            ctx.beginPath();
            ctx.moveTo(line.posx, line.posy);
            ctx.lineTo(line.posx + speedx * line.h, line.posy + line.h);
            ctx.stroke();
          });
        ctx.lineWidth = 1;
        ctx.strokeStyle = "#fff";
        dropList.forEach(function (e) {
          ctx.beginPath();
          ctx.arc(e.posx, e.posy, e.radius, Math.random() * Math.PI * 2, 1 * Math.PI);
          ctx.stroke();
        });
      }
    }
  </script>

</body>

</html>

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值