• 原生JS实现雪花特效


    今天在校园招聘上被问到的问题,用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{
    			 100%;
    			height: 100%;
    			background-color: #000;
    			overflow: hidden;
    		}
    		#divCanvas{
    			 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{
    			 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{
    			 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 {
           100%;
          height: 600px;
          background-color: #111123;
        }
    
        .snow {
           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来实现雪花特效

    待更...

  • 相关阅读:
    面试题目小结
    面试题目3
    C#中new和override区别
    [转]:存储过程与函数的区别
    [转载]:C# 面试题大全
    [转]:C++虚函数表解析
    【修订版】C#/ASP.Net 面试题及答案(1)
    [转载]:C# 中结构与类的区别
    [转载]:C#笔试题面试题锦集
    [转载]:SQL Server性能调优之执行计划深度剖析 第一节 浅析SQL执行的过程
  • 原文地址:https://www.cnblogs.com/can-i-do/p/6867826.html
Copyright © 2020-2023  润新知