js运动框架之一条乱跑的虫子
克隆与运动框架的联合应用
效果:点击元素块后,元素块开始随机的向任何方向移动,并附带一堆颜色随机的“尾巴”。每个方向运动3秒后改变方向,同时笑脸变哭脸。
如图所示:
朝某个方向运动使用的是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>