页面雪花飘落(html、CSS、JS)

在这里插入图片描述

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK" />
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      #box {
        width: 100vw;
        height: 100vh;
        padding: 3px;
        position: absolute;
        background: black;
      }
    </style>
  </head>

  <body>
    <div id="box"></div>
  </body>

  <script>
    (function () {
      var screenWidth = screen.availWidth; // 获取屏幕宽度
      var screenHeight = screen.availHeight; // 获取屏幕高度
      var speed = 20; // 雪花下落的速度
      function Snow(size, downSize) {
        this.box = document.getElementById("box"); // 获取容器元素
        this.size = size; // 雪花数量
        this.downSize = downSize || 10; // 每次落下的雪花数量,默认为10个
        this.item = []; // 雪花元素数组
        this.init(); // 初始化
        this.start(); // 开始下雪
      }
      // 获取相关随机数据的方法
      Snow.prototype.getRandomThings = function (type) {
        var res;
        if (type == "left") {
          // 初始的left
          res = Math.round(Math.random() * (screenWidth - 30 - 10)) + 10; // 随机生成left值
          Math.random() > 0.8 ? (res = -res) : null; // 80%的概率使左边的雪花出现在左侧(left为负值)
        } else if (type == "top") {
          // 初始的top
          res = -(Math.round(Math.random() * (50 - 40)) + 40); // 随机生成top值,负值使雪花在屏幕上方
        } else if (type == "incre") {
          // 向下的速度
          res = Math.random() * (4 - 1) + 1; // 随机生成向下的速度
        } else if (type == "increLeft") {
          // 向右的速度
          res = Math.random() * (0.8 - 0.5) + 0.5; // 随机生成向右的速度
        } else {
          // 雪花的大小
          res = Math.round(Math.random() * (30 - 10)) + 10; // 随机生成雪花的大小
        }
        return res;
      };
      Snow.prototype.init = function () {
        this.box.style.width = screenWidth + "px"; // 设置容器宽度为屏幕宽度
        this.box.style.height = screenHeight + "px"; // 设置容器高度为屏幕高度
        var fragment = document.createDocumentFragment(); // 创建文档片段,用于性能优化
        for (var i = 0; i < this.size; i++) {
          // 创建雪花元素
          var left = this.getRandomThings("left"); // 获取随机的left值
          var top = this.getRandomThings("top"); // 获取随机的top值
          var snowSize = this.getRandomThings("size"); // 获取随机的雪花大小
          var snow = document.createElement("div"); // 创建雪花元素
          snow.style.cssText = "position:absolute;color:#FFFFFF;"; // 设置元素样式
          snow.style["font-size"] = snowSize + "px"; // 设置字体大小
          snow.style.left = left + "px"; // 设置left值
          snow.style.top = top + "px"; // 设置top值
          snow.innerHTML = "❄"; // 设置雪花图标(Unicode编码)
          this.item.push(snow); // 添加到雪花元素数组中
          fragment.appendChild(snow); // 添加到文档片段中
        }
        box.appendChild(fragment); // 将文档片段添加到容器中
      };

      Snow.prototype.start = function () {
        var that = this;
        var num = 0;
        for (var i = 0; i < this.size; i++) {
          // 遍历雪花元素数组
          var snow = this.item[i];
          if ((i + 1) % this.downSize == 0) {
            // 每downSize个雪花一组,控制下落速度
            num++;
          }
          (function (s, n) {
            // 使用闭包保存snow和num的值
            setTimeout(function () {
              // 定时器,实现雪花分批下落
              that.doStart(s); // 调用doStart方法使雪花开始下落
            }, 1000 * n); // 每隔n秒下落一组雪花
          })(snow, num);
        }
      };

      // 针对每个雪花的定时处理
      Snow.prototype.doStart = function (snow) {
        var that = this;
        (function (s) {
          var increTop = that.getRandomThings("incre"); // 获取向下的速度
          var increLeft = that.getRandomThings("increLeft"); // 获取向右的速度
          var x = parseInt(getStyle(s, "left")),
            y = parseInt(getStyle(s, "top")); // 获取当前的left和top值

          if (s.timmer) return; // 如果定时器已存在,则不执行后续代码
          s.timmer = setInterval(function () {
            // 设置定时器,使雪花动起来
            // 超过右边或者底部重新开始
            if (y > screenHeight - 5 || x > screenWidth - 30) {
              // 重新回到天上开始往下
              increTop = that.getRandomThings("incre");
              increLeft = that.getRandomThings("increLeft");

              // 重新随机属性
              var left = that.getRandomThings("left");
              var top = that.getRandomThings("top");
              var snowSize = that.getRandomThings("size");
              s.style.left = left + "px";
              s.style.top = top + "px";
              s.style["font-size"] = snowSize + "px";
              y = top;
              x = left;
              n = 0;

              return;
            }

            // 加上系数,当随机数大于0.5时速度加快,小于0.5时速度减慢,形成飘动效果
            x += Math.random() > 0.5 ? increLeft * 1.1 : increLeft * 0.9;
            y += Math.random() > 0.5 ? increTop * 1.1 : increTop * 0.9;

            // 设置left和top值使雪花动起来
            s.style.left = x + "px";
            s.style.top = y + "px";
          }, speed); // 每隔speed毫秒执行一次定时器中的代码
        })(snow);
      };

      // 获取元素的样式值
      function getStyle(obj, prop) {
        var prevComputedStyle = document.defaultView
          ? document.defaultView.getComputedStyle(obj, null)
          : obj.currentStyle;
        return prevComputedStyle[prop];
      }
      new Snow(300, 30); // 创建一个Snow对象,传入雪花数量和每批下落的雪花数量
    })();
  </script>
</html>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值