js运动框架之一条乱跑的虫子

克隆与运动框架的联合应用

效果:点击元素块后,元素块开始随机的向任何方向移动,并附带一堆颜色随机的“尾巴”。每个方向运动3秒后改变方向,同时笑脸变哭脸。

   如图所示:

js运动框架之一条乱跑的虫子

朝某个方向运动使用的是js运动框架的思想,并通过round()函数调用自身实现不停移动的;而“尾巴”的产生则是通过每隔20ms克隆一次元素块,并在一秒后删除完成的。

具体代码如下:

  1 <!DOCTYPE html>
  2 <html>
  3 <head lang="en">
  4     <meta charset="UTF-8">
  5     <title></title>
  6     <style>
  7         #box{
  8             width:600px;
  9             height: 600px;
 10             border:10px solid black;
 11             position: relative;
 12         }
 13         #box div{
 14             width: 100px;
 15             height: 100px;
 16             background: red;
 17             position: absolute;
 18             left: 0;
 19             top: 0;
 20             border-radius: 50%;
 21             font-size: 100px;
 22             line-height: 100px;
 23             text-align: center;
 24         }
 25     </style>
 26 </head>
 27 <body>
 28 <div id="box">
 29     <div></div>
 30 </div>
 31 </body>
 32 </html>
 33 <script>
 34     //随机数
 35     function rnd(n, m) {
 36         return parseInt(Math.random() * (m - n) + n);
 37     }
 38 
 39     //获取样式
 40     function getStyle(obj, attr) {
 41         if (obj.currentStyle) {
 42             return obj.currentStyle[attr];
 43         } else {
 44             return getComputedStyle(obj, false)[attr];
 45         }
 46     }
 47 
 48     //运动框架
 49     function move(obj, time, json, fn) {
 50         var dis = {};
 51         var start = {};
 52         for (var name in json) {
 53             start[name] = parseInt(getStyle(obj, name));
 54             dis[name] = json[name] - start[name];
 55         }
 56         var count = Math.floor(time / 30);
 57         var n = 0;
 58         clearInterval(obj.timer);
 59         obj.timer = setInterval(function () {
 60             n++;
 61             for (var name in json) {
 62                 var cur = start[name] + dis[name] / count * n;
 63                 if (name == "opacity") {
 64                     obj.style.opacity = cur;
 65                     obj.style.filter = "alpha(opacity=" + cur * 100 + ")";
 66                 } else {
 67                     obj.style[name] = cur + "px";
 68                 }
 69             }
 70 
 71             if (n == count) {
 72                 clearInterval(obj.timer);
 73                 if (fn) fn();
 74             }
 75         }, 30)
 76     }
 77 
 78     window.onload = function() {
 79         var oBox = document.getElementById("box");
 80         var oDiv = oBox.getElementsByTagName("div")[0];
 81         var timer = null;
 82         //移动方向改变时变换一次表情
 83         function face(){
 84             oDiv.innerHTML = "";
 85             setTimeout(function () {
 86                 oDiv.innerHTML = "";
 87             }, 300);
 88         }
 89         //运动循环执行
 90         function round() {
 91             var a = rnd(0, 256);
 92             var b = rnd(0, 256);
 93             move(oDiv, 3000, {left: rnd(0, 500), top: rnd(0, 500)}, function () {
 94                 face();
 95                 round();
 96             })
 97         }
 98         //元素块点击之后开始执行
 99         oDiv.onclick = function () {
100             var lMax = oBox.clientWidth - oDiv.offsetWidth;
101             var tMax = oBox.clientHeight - oDiv.offsetHeight;
102             round();
103             //每隔20ms克隆一次
104             timer = setInterval(function () {
105                 var newDiv = oDiv.cloneNode(true);
106                 oBox.insertBefore(newDiv, oDiv); //需要使用insertBefore,若是使用appendChild()会将原块覆盖
107                 newDiv.style.opacity = "0.3";
108                 newDiv.style.filter = "alpha(opacity = 30)";
109                 //克隆元素块的背景色随机
110                 newDiv.style.background = "rgb(" + rnd(0, 256) + "," + rnd(0, 256) + "," + rnd(0, 256) + ")";
111                 //克隆的元素1秒之后删除
112                 setTimeout(function () {
113                     oBox.removeChild(newDiv);
114                 }, 1000);
115             }, 20);
116         }
117     }
118 </script>