今天做了两种抽奖的走马灯功能, 一般来说, 抽奖的奖品是通过后台返回回来的, 不过因为是自己做的一个小demo, 因此就直接封装成了对象, 自己往对象里面传值实现抽奖
先来看一下第一种, 先上HTML和CSS
<div id="b_circle"> <div id="b_circle_c"> <img src="./1.png" alt=""> div> <div id="s_circle"><div class="arrow">div>div> div>
#b_circle { width: 500px; height: 500px; margin: 100px auto; border: 1px solid #ccc; border-radius: 50%; position: relative; } #b_circle_c { width: 500px; height: 500px; border: 1px solid #ccc; border-radius: 50%; transform: rotate(0deg); } #s_circle { width: 200px; height: 200px; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); background-color: red; border-radius: 50%; } .arrow { width: 3px; height: 80%; position: absolute; left: 50%; transform: translateX(-50%); top: -40px; background-color: blue; } img { width: 100%; }
我做的转盘抽奖的答题思路就是, 利用transform中的rotate属性, 以及transition的过度效果, 为转盘添加旋转动画, 下面是JS代码:
function Rotate (ele,num) { this.box = document.getElementById(ele) this.start = document.getElementById('s_circle') this.timer = null //定时器 this.endDe = 0 //第一次定时器旋转结束时的角度 this.count = 0 //利用开闭原则, 防止多次点击抽奖 this.start.onclick = () => { if(this.count === 0) { this.count=1 this.roll(num) } } } Rotate.prototype.roll = function(num) { //让装盘旋转三圈加上奖品对应的度数 this.box.style.transform="rotate("+(1440+ num*45-20)+"deg)" this.box.style.transition="all 9s cubic-bezier(0,0,0.25,1)"this.timer = setTimeout(()=>{ //转完之后, 让转盘的旋转角度变为奖品对应的度数, 并赋值给endDe变量 this.count=0 this.box.style.transition="" this.endDe = this.box.style.transform.slice(7,this.box.style.transform.indexOf('d'))%360 this.box.style.transform="rotate("+this.endDe+"deg)" switch(true){ case this.endDe<=45: alert("一等奖") break case this.endDe<=90: alert("二等奖") break case this.endDe<=135: alert("三等奖") break case this.endDe<=180: alert("四等奖") break case this.endDe<=225: alert("五等奖") break case this.endDe<=270: alert("六等奖") break case this.endDe<=315: alert("七等奖") break case this.endDe<=360: alert("八等奖") break } },90000) } var rotate = new Rotate('b_circle_c',6)
效果如图:
第二种抽奖:
<div id="box"> <ul id='ul'> <li class="li">1li> <li class="li">2li> <li class="li">3li> <li class="li">4li> <li class="li1" id="chou">点击li> <li class="li">6li> <li class="li">Iphone全家桶li> <li class="li">8li> <li class="li">9li> ul> div>
#box { width: 400px; height: 400px; margin: 100px auto; position: relative; background-color: pink; } #ul { width: 100%; height: 100%; position: absolute; padding: 20px; box-sizing: border-box; display: flex; flex-wrap: wrap; justify-content: space-between; } .li,.li1 { width: 30%; height: 30%; background-color: skyblue; list-style: none; } .chose { background-color: #fff; }
第二种抽奖的思路就是通过添加和删除类名, 来实现移动的效果, 同样也是用定时器, 当点击抽奖的时候, 触发定时器, 让一个元素高亮, 再通过回调自身, 来循环实现这种效果, JS代码如下:
function Chose (ele,num) { this.box = document.getElementById(ele), this.li = document.getElementsByClassName('li') this.cli = document.getElementById('chou') this.timer = null this.speed = 50 //定时器触发的速度 this.count = 0; //计数变量 this.cli.onclick = ()=>{ let date = new Date().getTime() this.move(num,date) } } Chose.prototype.move = function(num,date) { this.timer = setTimeout(()=>{ let date2 = new Date().getTime() let j = this.count //因为元素的顺序,并不是环形的, 所以这里设置一个变量j, 来设置正确的高亮元素 for(let i=0; i<this.li.length;i++) { this.li[i].classList.remove("chose"); } switch(this.count) { case 3: j = 4 break case 4: j = 7 break case 5: j = 6 break case 6: j = 5 break case 7: j = 3 break } this.li[j].classList.add("chose"); this.count++ if(this.count > 7 ) { this.count = 0 } if(date2-date>2000){ //如果时间大于2秒, 则让速度慢下来 this.speed +=30 if(num-1 === j && date2-date>5000){ //如果时间大于5秒, 并且转到了奖品项上, 则停止计时器 setTimeout(()=>{ alert(this.li[j].innerText)
this.speed = 50 },0) return } } this.move(num,date) },this.speed) } var chose = new Chose('box', 6)
效果图如下: