当前位置: 首页 > 工具软件 > Curtain.js > 使用案例 >

原生JS实现雪花特效

史宸
2023-12-01

今天在校园招聘上被问到的问题,用JS写出雪花的效果。我打算使用多种方法来试试如何实现雪花。

这是目前按照网上某种思路模仿的第一种雪花,不太好看,但是大致意思清楚。

思路1:该思路直接由JS实现。

  • 雪花对象的定时创建 + 雪花对象的下落方法(包含消失判定)
  • 雪花创建的位置和雪花形状的建立 + 雪花的速度和雪花可能的左右移动和消失

缺点:

  • 不好看
  • 兼容性
  • 雪花方法不好,需要实时检索元素,应该改用数组维持
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        body,div{
            margin: 0;
            padding: 0;
        }
        body{
            width: 100%;
            height: 100%;
            background-color: #000;
            overflow: hidden;
        }
        #divCanvas{
            width: 800px;
            height: 800px;
            background: #212123;
        }
    </style>
</head>
<body>
<div id="divCanvas"></div>
</body>
<script type="text/javascript">
    var canvas = document.getElementById("divCanvas");
    var maxWidth = canvas.clientWidth;
    var maxHeight = canvas.clientHeight;

    function Obj() {};
    Obj.prototype.action = function(o) {
        o.style.left = Math.ceil(Math.random() * maxWidth) + "px";
        o.style.top = 0 + "px";
        var speed = 0;
        setInterval(function() {
            if (parseInt(o.style.top) < maxHeight) {
                o.style.top = parseInt(o.style.top) + speed + "px";
                speed += 5;
            } else {
                o.style.display = "none";
            }

        }, 400);
    }

    setInterval(function() {
        var oDiv = document.createElement("div");
        oDiv.style.color = "#fff";
        oDiv.innerHTML = "*";
        oDiv.style.position = "absolute";
        canvas.appendChild(oDiv);
        var obj = new Obj();
        obj.action(oDiv);
    }, 300);


</script>
</html>

思路2:该思路由JS和CSS3共同实现。

  • 雪花对象的创建 + 雪花的方法
  • 用CSS3完善雪花的渐隐和出现动画 + 雪花固定的top值增加

缺点:

  • 依旧没有用数组来维持,比较占内存
  • 不够好看
  • 兼容性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        body,div{
            margin: 0;
            padding: 0;
        }
        body{
            background: #000;
        }
        .snow{
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background: #fff;
            animation: mysnow 20s;
            position: absolute;
        }
        @keyframes mysnow{
            0%{opacity: 0;}
            50%{opacity: 1}
            100%{opacity: 0;}
        }
        #canvas{
            width: 800px;
            height: 800px;
            background: #213123;
        }
    </style>
    <script type="text/javascript">
        window.onload=function(){
            var canvas=document.getElementById("canvas");
            var maxWidth=canvas.clientWidth;
            var maxHeight=canvas.clientHeight;

            function Snow(){};
            Snow.prototype.Move=function(x){
                var speed=Math.ceil(Math.random()*1);
                x.style.top=Math.floor(Math.random()*maxWidth);
                x.style.left=Math.floor(Math.random()*maxHeight);
                setInterval(function(){
                    if(parseInt(x.style.top)<maxHeight){
                        x.style.top=parseInt(x.style.top)+speed+"px";
                    }else{
                        x.style.display="none";
                    }
                },30);

            }
            setInterval(function(){
                var oDiv=document.createElement("div");
                oDiv.className="snow";
                oDiv.style.top=0+"px";
                oDiv.style.left=Math.ceil(Math.random()*maxHeight)+"px";
                canvas.appendChild(oDiv);
                var snow=new Snow();
                snow.Move(oDiv);
            },200);
        };
    </script>
</head>
<body>
<div id="canvas"></div>
</body>
</html>

思路3:使用数组维持雪花对象,在一开始的时候便随机创建好每个雪花的动态属性

原型模式创建的雪花对象 + 雪花方法

优点:数组维持

缺点:

  • 没有用上 window.requestAnimationFrame方法
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>mySnow- oH!!!Sexy!</title>
  <style type="text/css">
    body,
    div {
      margin: 0;
      padding: 0;
    }

    body {
      background: #000;
    }

    #curtain {
      width: 100%;
      height: 600px;
      background-color: #111123;
    }

    .snow {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: #fff;
      position: absolute;
      animation: mysnow 10s;
    }

    @keyframes mysnow {
      0% {
        opacity: 0;
      }
      50% {
        opacity: 1;
      }
      100% {
        opacity: 0;
      }
    }

    .empty {
      display: none;
    }
  </style>
</head>

<body>
  <div id="curtain"></div>
</body>
<script type="text/javascript">
(function () {
  var $ = function (id) { return typeof id === "string" ? document.getElementById(id) : id };
  var curtain = $("curtain");
  var maxWidth = curtain.clientWidth - 50;
  var maxHeight = curtain.clientHeight;

  var snowControl = function () {};

  snowControl.prototype = {
    Obj: [],
    maxCount: 10,
    count: 0,
    Prepare: function () {
      for (var i = 0; i < this.maxCount; i++) {
        var o = {
          positionX: Math.ceil(Math.random() * maxWidth),
          positionY: Math.ceil(Math.random() * 50),
          speed: Math.ceil(Math.random() * 5 + 3),
          shake: Math.ceil(Math.random() * 3)
        };
        this.Obj.push(o);
      };
    },
    Init: function () {
      if (this.Obj.length) {
        var oDiv = document.createElement("div");
        oDiv.className = "snow";
        var now = this.Obj.shift();
        oDiv.style.top = now.positionY + "px";
        oDiv.style.left = now.positionX + "px";
        curtain.appendChild(oDiv);
        // 唤醒 div
        this.Move(oDiv, now);
        ++this.count;
      } else {
        return false;
      }
    },
    Move: function (oDiv, now) {
      var timer = setInterval(function () {
        if (now.positionX < maxWidth && now.positionY < maxHeight - 50) {
          now.positionY = now.positionY + now.speed;
          now.positionX = now.positionX + now.shake;
          oDiv.style.top = now.positionY + "px";
          oDiv.style.left = now.positionX + "px";
        } else {
          now.positionX = Math.ceil(Math.random() * maxWidth);
          now.positionY = Math.ceil(Math.random() * 50);
          oDiv.style.left = now.positionX + "px";
          oDiv.style.top = 0 + "px";
        }
      }, 30);
    },

    Letsgo: function () {
      var oThis = this;
      var gotimer = setInterval(function () {
        if (oThis.count == oThis.maxCount) {
          clearInterval(gotimer);
        } else {
          oThis.Init();
        }
      }, 400);
    }

  };

  var snow = new snowControl();
  snow.Prepare();
  snow.Letsgo();
})();

</script>

</html>

思路4: 使用canvas来实现雪花特效

待更...

转载于:https://www.cnblogs.com/can-i-do/p/6867826.html

 类似资料: