最近双十一双十二都有抽奖活动,之前双十一的时候写了一个抽奖代码,双十二也继续用上了这个代码,正好双十二也结束了,抽空把抽奖代码给整理一下.
抽奖步骤.
我的这个抽奖大致分为以下五个步骤.
- 获取奖品列表数据.
- 获取到是否有抽奖次数.
- 有抽奖次数开始请求接口抽奖,没有抽奖次数提示没有抽奖次数.
- 获取到抽奖结果,开始抽奖动画.
- 结束抽奖,提示中奖信息.
开始拆分代码.
由于之前写的是微信小程序的抽奖代码,我把代码思路理了一下重新用
vue
来梳理一遍.
布局.
九宫格顾名思义就是有九个格子,一共八个奖品,中间是抽奖的按钮,先把九个格子的html
写好,css
代码我会放在文末.
<div class="draw-bow">
<div class="lotteryButtom" style="" @click="startDraw">
<div class="ButtomMask" v-show="!lotteryButtom"></div>
</div>
<div v-for="(item, index) in prizeList" :key="item.id" :class="['Item',prizeIndex==index+1?'action':'']">
<!-- <image src="{{item.image}}"/> -->
<div class="textCon">
<text>{{ item.name }}</text>
</div>
</div>
</div>
参数变量.
// 抽奖次数
lotteryNumber: 2,
// 抽奖按钮控制
lotteryButtom: true,
// 转盘索引(开始抽奖时高亮哪个奖品)
prizeIndex: 0,
// 抽中的奖品索引
prizeResult: null,
// 抽中的奖品名称
prizeName: null,
// 奖品图片
prizeImage: "",
// 奖品列表
prizeList: [ {name:'一等奖',id:1},
{name:'二等奖',id:2},
{name:'三等奖',id:3},
{name:'四等奖',id:4},
{name:'五等奖',id:5},
{name:'六等奖',id:6},
{name:'七等奖',id:7},
{name:'八等奖',id:8}],
// 活动规则弹窗
activityRules: false,
// 奖品弹窗
prizePopup: false,
timer:null//定时器
获取抽奖次数.
在页面加载前获取到是否有抽奖次数.
created(){
//请求接口获取抽奖次数并且修改`lotteryNumber`(抽奖次数),与抽奖按钮控制`lotteryButtom`
}
抽奖动画函数.
这个函数写的是抽奖动画的控制,每调用一次动画循环一圈,你所设置的圈数跑完之后赋值给指定的值函数匹配成功停止动画.
//抽奖过程奖品切换
changePrize(){
// 开始切换class,动画开始
// ---------------------
// class所在的索引增加
let prizeIndex=this.prizeIndex;
prizeIndex++;
// 做判断,判断索引是否大于奖品数量,如果是,清空,从第一个开始.
this.prizeIndex=prizeIndex > this.prizeList.length ? 1 : prizeIndex;
// 给结果赋值之后,开始做判断,抽奖将停止
if(this.prizeResult==this.prizeList[this.prizeIndex-1].id){
// 清除最后一个动画
clearInterval(this.timer);
console.log('获得奖品:' + this.prizeName)
// 显示奖品框
setTimeout(()=>{
this.prizePopup=true
},700)
// 判断是否还有抽奖机会
if(this.lotteryNumber!==0){
// 有抽奖机会抽奖按钮取消置灰
this.lotteryButtom=true
// 清空定时器
this.timer=null;
clearInterval(this.timer);
}
// 抽奖结束
// end.
}
}
开始抽奖.
开始抽奖时判断是否有抽奖次数,有次数将次数减去一次,开始请求接口,接口返回正确的参数后开始动画,这个时候先不赋值,先指定跑几圈动画,动画的快慢通过定时器调整,等指定的圈数跑完开始赋值停止动画.
模拟一个接口请求函数
// 模拟接口返回字段
lotteryDraw(){
return new Promise((resolve,reject)=>{
resolve({data:{
id:1,
title:'二等奖',
code:200
}})
})
}
startDraw (){
// 判断按钮是否为灰色,灰色时不可再抽奖
if(!this.lotteryButtom){
alert('您没有抽奖资格哦')
return
}
// 清空上一次抽奖
this.prizeResult=null,
this.prizeName=null,
this.prizeIndex=0
// 如果当前有抽奖机会
if(this.lotteryNumber>0){
// 抽奖按钮不可再点击
this.lotteryButtom=false
// 请求到数据并且没有错误返回code==200
this.lotteryDraw().then((res)=>{
// 抽奖结果数据
var result = res.data;
console.log(result)
if(result.code==200){
// 次数减1
this.lotteryNumber=this.lotteryNumber-1
// 开始抽奖动画
// -----------
// 管你有没有定时器,先清除一遍.
clearInterval(this.timer)
// 正片开始,开始抽奖动画.
// -----------
// 第一遍,来个快的.
this.timer=setInterval(this.changePrize,80)
console.log("第一遍")
// 把第一遍抽奖动画关闭.
// -----------
// 两秒后关闭第一个动画
setTimeout(()=>{
// 关闭上一个抽奖动画
// ---------
clearInterval(this.timer)
// 开始第二个动画
this.timer=setInterval(this.changePrize,160)
console.log("第二遍")
// 一秒后关闭第二个动画
setTimeout(()=>{
// 关闭上一个抽奖动画
clearInterval(this.timer)
this.timer=setInterval(this.changePrize,300)
console.log("第三遍")
setTimeout(()=>{
// 给结果赋值(抽奖动画函数里面有判断,如果当前结果==抽奖的动画的索引,结束动画,抽奖结束.)
this.prizeResult=result.id
this.prizeName=result.title
this.isType=true
// end.
},1000)
},1000)
},2000)
}
// 接口返回其它状态处理
else if(result.code==500){
}
})
}
// 没有抽机会,点了也没用
else {
return
}
}
抽奖结束.
抽奖结束后在changePrize
函数里面放一些控制弹窗进行奖品的提示,我这里就没有继续写了,这个思路其实非常简单.
CSS代码
html,
body {
padding: 0;
margin: 0;
font-size: 16px;
}
.lotteryButtom {
width: 95px;
height: 95px;
border-radius: 10px;
background-size: cover;
background-image: url("https://www.nanbk.com/usr/themes/Akina/images/avatar.png");
box-shadow: 0.5px 2px 2px 0px rgba(0, 0, 0, 0.8),
1.5px 1.5px 3px 0px rgba(255, 255, 255, 0.8),
-1.5px -1.5px 3px 0px rgba(217, 148, 88, 0.5);
display: flex;
justify-content: center;
position: absolute;
left: 99px;
top: 99px;
.ButtomMask {
width: 85px;
height: 85px;
border-radius: 10px;
background-color: #9b2f10;
opacity: 0.3;
margin-top: 5px;
}
}
.draw-bow {
position: relative;
margin: 20px auto;
width: 293px;
height: 293px;
background-color: aquamarine;
.Item {
width: 95px;
height: 95px;
background: #9b2f10;
box-shadow: 0.5px 2px 2px 0px rgba(0, 0, 0, 0.8),
1.5px 1.5px 3px 0px rgba(255, 255, 255, 0.8),
-1.5px -1.5px 3px 0px rgba(217, 148, 88, 0.5);
background-size: cover;
border-radius: 10px;
display: inline-block;
}
.Item:nth-child(2) {
position: absolute;
left: 0px;
top: 0px;
}
.Item:nth-child(3) {
position: absolute;
left: 99px;
top: 0px;
}
.Item:nth-child(4) {
position: absolute;
right: 0px;
top: 0px;
}
.Item:nth-child(5) {
position: absolute;
right: 0px;
top: 98px;
}
.Item:nth-child(6) {
position: absolute;
right: 0px;
bottom: 0px;
}
.Item:nth-child(7) {
position: absolute;
right: 99px;
bottom: 0px;
}
.Item:nth-child(8) {
position: absolute;
left: 0px;
bottom: 0px;
}
.Item:nth-child(9) {
position: absolute;
left: 0px;
top: 99px;
}
.action{
background-color: red !important;
color: #ffffff;
}
}
Comments | NOTHING