<view class="container">
<view class="zhuanpan_box_out">
<image class="zhunapan_bg" src="https://s1.ax1x.com/2023/06/14/pCuPMrT.png" mode="aspectFill"></image>
<view class="circle" wx:for="{{circleList}}" wx:key="index" style="top:{{item.topCircle}}rpx;left:{{item.leftCircle}}rpx;background-color: {{(index%2==0)?colorCircleFirst:colorCircleSecond}};"></view>
<view class="zhuanpan_box_in">
<view class="content-out" wx:for="{{awardList}}" wx:key="index" style="top:{{item.topAward}}rpx;left:{{item.leftAward}}rpx;background: {{item.isSelected?colorAwardSelect:colorAwardDefault}};">
<view class="award-text">{{item.awardText}}</view>
</view>
<view class="draw_btn" bindtap="startGame">
<image class="draw_btn_bg" src="https://s1.ax1x.com/2023/06/14/pCuPRQP.png" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
.container {
width: 100vw;
height: 100vh;
background: url('https://s1.ax1x.com/2023/06/14/pCuPAaQ.png') no-repeat center top;
background-size: 750rpx 1624rpx;
}
.zhuanpan_box_out {
width: 750rpx;
height: 732rpx;
/* 水平垂直居中 */
margin: auto auto;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.zhuanpan_box_out .zhunapan_bg {
display: block;
width: 750rpx;
height: 732rpx;
}
.zhuanpan_box_in .draw_btn {
width: 166rpx;
height: 150rpx;
position: absolute;
top: 346rpx;
left: 294rpx;
}
.zhuanpan_box_in .draw_btn .draw_btn_bg {
width: 100%;
height: 100%;
position: absolute;
}
.zhuanpan_box_in .draw_btn .draw_btn_text {
position: absolute;
left: 43rpx;
top: 80rpx;
width: 80rpx;
font-size: 20rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #B16042;
text-align: center;
}
/**小圆球*/
.circle {
position: absolute;
display: block;
border-radius: 50%;
height: 18rpx;
width: 18rpx;
}
/* 奖品的容器 */
.content-out {
position: absolute;
width: 166rpx;
height: 150rpx;
background-color: #f5f0fc;
border-radius: 10rpx;
/* box-shadow: 0 5px 0 #d87fde; */
}
/*奖品的文案 */
.content-out .award-text {
width: 100%;
height: 100%;
color: #3c3c3c;
font-weight: 500;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
1. 需要通过接口去获取奖品列表 (awardList)
2.绘制灯 实现闪烁的效果
3.设置奖品 的位置与设置圆点位置的原理一样 奖品可以用图片代替(根据需求来设置)
4.点击抽奖按钮时 判断抽奖状态,如果不在抽奖状态中,则执行抽奖旋转动画
5.调用接口获取奖品的id (可以设置必中某个奖品)
Page({
data: {
circleList: [], //圆点数组
colorCircleFirst: '#F8AC4C', //圆点颜色1
colorCircleSecond: '#FBF8D7', //圆点颜色2
colorAwardDefault: 'linear-gradient(180deg, #EFD98D 0%, #FAECBF 9%, #FAECBF 91%, #E7C86C 100%) ', //奖品默认颜色
colorAwardSelect: '#ffe400', //奖品选中颜色
indexSelect: '', //被选中的奖品index
//奖品数组
awardList: [{
awardId: 1,
awardText: "英语1"
}, {
awardId: 2,
awardText: "英语2"
}, {
awardId: 3,
awardText: "英语3"
}, {
awardId: 4,
awardText: "英语4"
}, {
awardId: 5,
awardText: "英语5"
}, {
awardId: 6,
awardText: "英语6"
}, {
awardId: 7,
awardText: "英语7"
}, {
awardId: 8,
awardText: "英语8"
}],
//抽中的奖品信息
prizeInfo: [],
num_interval_arr: [90, 80, 70, 60, 50, 50, 50, 100, 150, 250],
//所以得出转圈的执行顺序数组为
order_arr: [0, 1, 2, 5, 8, 7, 6, 3],
// 抽奖状态,是否转完了
isTurnOver: true,
// 是否需要复原,把没转完的圈转完
isRecover: false,
// 记录上一次抽奖后的奖品位置
awardSort_last: '',
prize_id: '', //奖品id
},
onShow() {
this.drawTheLamp()
this.setAwardList()
},
//绘制灯
drawTheLamp() {
let _this = this;
//设置圆点相对于左上角定位点的距离
let topCircle = 0; //距离顶部
let leftCircle = 0; //距离左边
let circleList = []; //创建圆点数据对象
// 创建圆点的位置顺序是 左上————右上————右下————左下————右上
for (let i = 0; i < 32; i++) {
if (i == 0) { //左上角圆点
topCircle = 162;
leftCircle = 146;
} else if (i < 8) {
topCircle = 162;
leftCircle = leftCircle + 64;
} else if (i == 8) { //右上角圆点
topCircle = 190;
leftCircle = 641;
} else if (i < 16) {
topCircle = topCircle + 64;
leftCircle = 641;
} else if (i == 16) { //右下角圆点
topCircle = 678;
leftCircle = 595;
} else if (i < 24) {
topCircle = 678;
leftCircle = leftCircle - 64;
} else if (i == 24) { //左下角圆点
topCircle = 640;
leftCircle = 94;
} else if (i < 32) {
topCircle = topCircle - 63;
leftCircle = 94;
} else {
return
}
// 添加圆点对象
circleList.push({
topCircle: topCircle,
leftCircle: leftCircle
});
}
this.setData({
circleList
})
//圆点闪烁 每500毫秒改变交换圆点的颜色
setInterval(function () {
if (_this.data.colorCircleFirst == '#F8AC4C') {
_this.setData({
colorCircleFirst: '#FBF8D7',
colorCircleSecond: '#F8AC4C',
})
} else {
_this.setData({
colorCircleFirst: '#F8AC4C',
colorCircleSecond: '#FBF8D7',
})
}
}, 500)
},
//设置奖品 的位置与设置圆点位置的原理一样
setAwardList() {
//奖品item设置
let awardList = [];
//设置奖品容器相对于左上角定位点的距离
let topAward = 0; //距离顶部
let leftAward = 0; //距离左边
for (let j = 0; j < 8; j++) {
if (j == 0) {
topAward = 190;
leftAward = 122;
} else if (j < 3) {
topAward = topAward;
//166.6666是宽.15是间距.下同
leftAward = leftAward + 166 + 6;
} else if (j < 5) {
leftAward = leftAward;
//150是高,15是间距,下同
topAward = topAward + 150 + 6;
} else if (j < 7) {
leftAward = leftAward - 166 - 6;
topAward = topAward;
} else if (j < 8) {
leftAward = leftAward;
topAward = topAward - 150 - 6;
}
let awardItem = this.data.awardList[j];
awardList.push({
...awardItem, //奖品对象
topAward: topAward,
leftAward: leftAward,
isSelected: false, //默认false 未被选中
isRemove: false, //默认false 未被选移除
});
}
this.setData({
awardList
})
},
//开始游戏
startGame() {
// 如果不在抽奖状态中,则执行抽奖旋转动画
if (this.data.isTurnOver) {
// 把抽奖状态改为未完成
this.setData({
isTurnOver: false
})
this.getPrizeInfo()
return;
} else {
wx.showToast({
title: '请勿重复点击',
icon: 'none'
})
return;
}
},
getPrizeInfo() {
// 这里开始假设已经调取后端接口拿到抽奖后返回的
// 将ID与奖品的id进行对比 ,如果相等就返回奖品的索引index
// 设置接口返回的ID为1
let id = 1
let {
awardList,
indexSelect
} = this.data
awardList.forEach((item, index) => {
if (item.awardId === id) {
indexSelect = index + 1
this.lottery(indexSelect);
}
})
// 随机抽中第几个奖品
// let {
// indexSelect
// } = this.data
// indexSelect = 1
// this.lottery(indexSelect);
},
// 抽奖旋转动画方法
async lottery(awardSort) {
console.log('中的是第几个奖品:' + awardSort)
// 如果不是第一次抽奖,需要等待上一圈没跑完的次数跑完再执行
this.recover().then(() => {
let num_interval_arr = this.data.num_interval_arr;
let order_arr = this.data.order_arr;
// 旋转的总次数
let sum_rotate = num_interval_arr.length;
// 每一圈所需要的时间
let interval = 0;
num_interval_arr.forEach((delay, index) => {
setTimeout(() => {
this.rotateCircle(delay, index + 1, sum_rotate, awardSort, order_arr);
}, interval)
//因为每一圈转完所用的时间是不一样的,所以要做一个叠加操作
interval += delay * 8;
})
})
},
rotateCircle(delay, index, sum_rotate, awardSort, order_arr_pre) {
// console.log("index", index)
let _this = this;
// 页面奖品总数组
let prize_arr = this.data.awardList;
// 执行顺序数组
let order_arr = []
// 如果转到最后以前,把数组截取到奖品项的位置
if (index == sum_rotate) {
order_arr = order_arr_pre.slice(0, awardSort)
} else {
order_arr = order_arr_pre;
}
for (let i = 0; i < order_arr.length; i++) {
setTimeout(() => {
// 清理掉选中的转态
prize_arr.forEach(item => {
item.isSelected = false
})
// 执行到第几个就改变它的选中状态
prize_arr[i].isSelected = true;
// 更新状态
_this.setData({
awardList: prize_arr
})
// 如果转到最后一圈且转完了,并且是非重置圈,把抽奖状态改为已经转完了
if (index === sum_rotate && i === order_arr.length - 1 && !this.data.isRecover) {
let timer = setTimeout(() => {
_this.setData({
isTurnOver: true,
isRecover: true,
awardSort_last: awardSort
})
clearInterval(timer)
}, 1000)
}
}, delay * i)
}
},
// 复原,把上一次抽奖没跑完的次数跑完
async recover() {
if (this.data.isRecover) { // 判断是否需要重置操作
let delay = this.data.num_interval_arr[0]; // 为了衔接流程,使用第一圈的转速
// console.log(delay)
let order_arr = this.data.order_arr;
// console.log(order_arr)
let awardSort_last = this.data.awardSort_last; // 上一次抽奖的奖品序列
// console.log(awardSort_last)
order_arr = order_arr.slice(awardSort_last); // 截取未跑完的格子数组
// console.log(order_arr)
return await new Promise(resolve => { // 确保跑完后才去执行新的抽奖
this.rotateCircle(delay, 1, 1, 8, order_arr); // 第一圈的速度,最多只有一圈,旋转一圈,跑到最后一个奖品为止,未跑完的数组
setTimeout(() => { // 确保跑完后才告诉程序不用重置复原了
this.setData({
isRecover: false,
})
resolve() // 告诉程序Promise执行完了
}, delay * order_arr.length)
})
}
},
})