随机抽人效果,需求:所有的名字都在屏幕上四处漂泊,点击抽人后,加快速度,5秒后,抽中的人跑向中间,其他所有人,飞出屏幕外,并保证每个人抽中的概率只有一次。看到这个需求后,对于一个Android开发者而言,懵逼了!不过还是细细钻研了一番,最终实现效果如下,当然,有参考他人的思路,效果如下:
这里主要说下实现思路,主要用到了requestAnimationFrame这个函数,以及JQery里animate动画,数据源,自己写了一个txt文件,里面存储所有人姓名。
{ "result":[ "张三", "李四", "王五", "赵六", "闫七", "李八", "李九", "李十", "张十一", "钱十二", "孙大", "周二", "吴三", "郑四", "王洛", "冯九", "都偶", "某某" ], "message":"成功", "status":"0000" }
页面其实很简单,一个用于动态添加到的p标签,还有两个div按钮,页面底部的js文件, 首先使用JQuery获取了所有人的姓名,然后赋值给了p标签,需要注意的是,获取完名字后,这里我做了一个遍历,即让每个名字后都带了一个空格,然后调用了animate.js中的Animate对象。
<html><head><metacharset="utf-8"/><title>随机抽人</title><metaname="author"content=AbnerMing/><linkrel="stylesheet"type="text/css"href="css/animate.css"/><scriptsrc="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script><scriptsrc="js/animate.js"type="text/javascript"charset="utf-8"></script></head><body><article><pclass="text"id="text"></p></article><divclass="div_bottom"><divid="btn">随机抽人</div><divclass="reset">重置</div></div><scripttype="text/javascript">$(function () { $.get("data.txt", function (data, status) { varjson=JSON.parse(data); if (json.status=="0000") {//成功varresult=json.result; varcontent=""; for (vari=0; i<result.length; i++) { varcon=result[i]; content=content+con+" "; } $(".text").text(content); varneontext=newAnimate("text"); neontext.render.run(); $("#btn").click(function () { if (isClick) { randomNum(result); isClick=false; } else { isClick=true; } neontext.render.killer(isClick); }); } else { alert(json.message);//否则给出提示 } }); varisClick=true; //去重functionrandomNum(nameArr) { varsize=nameArr.length; vara=0; while (true) { a++; varnum=Math.floor(Math.random() *size); varname=localStorage.getItem("name"); if ((name+"").indexOf(num) ==-1) { localStorage.setItem("name", name+"="+num); localStorage.setItem("vip", nameArr[num]); break; } if (a==size-1) { alert("所有人都抽完了!"); localStorage.setItem("vip", ""); break;//停止 } } } $(".reset").click(function () { localStorage.setItem("name", ""); localStorage.setItem("vip", ""); }); }); </script></body></html>
animate.js里,由于前边设置的文字携带了空格,这里对于设置的文字做了分割,动态创建span标签,并定义了一个随机的集合,具体看下面代码:
varisRun=true; functionAnimate(id) { varele=document.getElementById(id), eletext=ele.innerText, arr=eletext.split(" "), _this=this; this.resetTime=10; //最大值100this.color= [ '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4caf50', '#8bc34a', '#cddc39', '#ffeb3b', '#ffc107', '#ff9800', '#ff5722', '#795548', '#9e9e9e', '#607d8b' ]; this.randomColor=function () { varcolorIndex=Math.floor(this.color.length*Math.random()); returnthis.color[colorIndex]; }; this.posRangencala=function () { returnele.hasAttribute("ele-range") ? { minRange: { x: ele.getBoundingClientRect().left, y: ele.getBoundingClientRect().top }, maxRange: { x: ele.getBoundingClientRect().right, y: ele.getBoundingClientRect().bottom } } : { minRange: { x: 0, y: 0 }, maxRange: { x: document.documentElement.clientWidth, y: document.documentElement.clientHeight } } }; this.spanArr= (function () { ele.innerHTML=""; varspanArr= []; arr.forEach(function (value, index) { varspanDom=document.createElement("span"); spanDom.style.display="inline-block"; spanDom.innerHTML=value; spanDom.style.position="relative"; spanDom.style.color=_this.randomColor(); spanDom.style.fontSize="26px"; spanDom.own= { pos: { x: 0, y: 0 }, ran: { x: -.5+Math.random(), y: -.5+Math.random() }, speed: { x: 1, y: 1 }, dir: { x: 1, y: 1 } }; ele.appendChild(spanDom); spanArr.push(spanDom); }); returnspanArr; })(); this.spanOrigin=function () { this.spanArr.forEach(function (value, index) { value.own.realPos= { minx: value.getBoundingClientRect().left, maxx: value.getBoundingClientRect().right, miny: value.getBoundingClientRect().top, maxy: value.getBoundingClientRect().bottom } }); this.posRangen=this.posRangencala(); }; this.spanOrigin(); this.resetpos=function () { this.spanOrigin(); this.spanArr.forEach(function (span, index) { if (span.own.realPos.minx+span.own.pos.x<_this.posRangen.minRange.x) span.own.pos.x=0; if (span.own.realPos.maxx+span.own.pos.x>_this.posRangen.maxRange.x) span.own.pos.x=0; if (span.own.realPos.miny+span.own.pos.y<_this.posRangen.minRange.y) span.own.pos.y=0; if (span.own.realPos.maxy+span.own.pos.y>_this.posRangen.maxRange.y) span.own.pos.y=0; }) }; this.floatText=function () { this.spanArr.forEach(function (span, index) { if (span.own.realPos.minx+span.own.pos.x<_this.posRangen.minRange.x||span.own.realPos.maxx+span.own.pos.x>_this.posRangen.maxRange.x) { span.own.dir.x=-span.own.dir.x; } if (span.own.realPos.miny+span.own.pos.y<_this.posRangen.minRange.y||span.own.realPos.maxy+span.own.pos.y>_this.posRangen.maxRange.y) { span.own.dir.y=-span.own.dir.y; } if (isRun) { timeOut(span, 0); } else { for (vara=0; a<20; a++) { timeOut(span, 10); } } }) }; functiontimeOut(span, time) { setTimeout(function () { span.own.pos.x+=span.own.ran.x*span.own.speed.x*span.own.dir.x; span.own.pos.y+=span.own.ran.y*span.own.speed.y*span.own.dir.y; span.style.transform="translateX("+span.own.pos.x+"px) translateY("+span.own.pos.y+"px)"; }, time); } varboolClick=true; this.floatBack=function () { this.spanArr.forEach(function (value, index) { vartext=value.innerText; varx=value.own.pos.x-value.own.pos.x*_this.resetTime/100-100; vary=value.own.pos.y-value.own.pos.y*_this.resetTime/100-100; varvip=localStorage.getItem("vip"); if (vip==text) { if (boolClick) { vartTop=value.getBoundingClientRect().top; vartLeft=value.getBoundingClientRect().left; varsizeW=winW/2; varsizeH=winH/2; vars=value.getBoundingClientRect().width/3; varendX=sizeW-tLeft-s*2; varendY=sizeH-tTop-36; $(value).animate({top: endY, left: endX, fontSize: '36px'}); boolClick=false; } } else { value.style.transform="translateX("+x+"px) translateY("+y+"px)"; setTimeout(function () { $(value).animate({top: '-150px'}); }, 200); } }); if (this.resetTime===100) { cancelAnimationFrame(_this.send); returntrue; } else { this.resetTime+=5; } }; this.restart=function () { this.spanArr.forEach(function (value, index) { value.own.pos.x=0; value.own.pos.y=0; }) }; this.render= { run: function () { _this.sren=requestAnimationFrame(_this.render.run); _this.floatText(); }, end: function () { _this.send=requestAnimationFrame(_this.render.end); _this.floatBack(); }, killer: function (bool) { if (bool) { isRun=true; window.location.reload(); } else { isRun=false; setTimeout(function () { varthat=_this; cancelAnimationFrame(that.sren); that.render.end(); }, 5000); } } }; varwinW=0; varwinH=0; window.onresize=function () { _this.resetpos(); }; getWh(); functiongetWh() { winW=document.body.offsetWidth; winH=document.documentElement.clientHeight; } }
animate.css
* { margin: 0; padding: 0; } html { font-family: "微软雅黑"; font-size: 20px; } ::scrollbar { overflow-x: hidden; } body { background: #000; overflow: hidden; } p { width: 80%; margin: 100pxauto30px; line-height: 1.5; } .div_bottomdiv { width: 100%; height: 50px; background: orange; color: #ffffff; font-family: "微软雅黑"; border-radius: 10px; border: 1pxsolidorange; text-align: center; line-height: 50px; cursor: pointer; } .reset { margin-top: 20px; } .div_bottom { position: absolute; bottom: 5%; width: 10%; height: 120px; left: 45%; }
全部都是已写好的代码,可以直接复制使用,只需要更改txt文件里的名字即可。