九宫格实现抽奖功能
需求:
1.能够实现跑马灯效果(抽奖效果)
2.中奖消息轮播
3.根据后端返回抽中奖品,跑马灯跑到抽中奖品的位置
实现思路:
1.目标:将静态页面布局出来
–奖品卡片组件(基操)
–奖品池,将奖品卡片依次放入(弹性布局实现)
–中奖的奖品样式(添加属性样式)
2.目标:实现抽奖效果
–逐个改变和还原卡片的背景色,从而实现跑起来的效果
–用一个变量来告知当前卡片是否是选中的状态(变量对应样式类名)
–然后使用定时器,每隔多少毫秒使得当前卡片的背景色为正常状态,下一张卡片为选中状态(改变变量)
3.目标:使得跑马灯停到目标位置
–获取到指定奖品之后,清除定时器使得无目标跑马灯停下啦
–开启新的定时器,使跑马灯跑到指定的位置
–清除定时器
页面代码实现:
<View>
<Message />//轮播消息组件
<View className="prize-card-store">//奖池容器
{
this.state.dataSource.map((item, index) => {//讲奖品放入奖池中布局
return <View key={index} className={["prize-card", item.isActive && "active"]}>//变量控制是否选中状态
<Image source={'./assets/images/sweepStakes/' + item.name}></Image>//奖品元素
</View>
})
}
</View>
<View onPress={() => this.startlucky()} className="start">//开始按钮容器
<Image source={'./assets/images/sweepStakes/button.gif'}></Image>
</View>
</View>
逻辑代码:
startlucky() {
if(this.state.flag){//防止二次点击
this.setState({
flag:false
})
this.roll(0, 999, 50)//跑马灯函数
this.getPrize()//获取奖品函数
}
}
roll(position, result, speed) {//position:初始中奖位置,result:指定中奖位置,speed:跑马灯速度
let round = 0; // 跑的次数
let active = position; // 起始位置
const { dataSource } = this.state;
this.timer = setInterval(() => {
if (round < result) { //跑到中奖位置后断开
if (active === 8) { //到最后一个奖品后,重新回到第一个奖品
active = 0;
} else {
active += 1;
}
round += 1;
for (let i = 0, l = dataSource.length; i < l; i += 1) {//每次讲当前奖品选中,其他奖品未选中(跑马灯效果)
if (i === active) {
dataSource[i].isActive = true;
} else {
dataSource[i].isActive = false;
}
}
this.setState({ dataSource, activeIndex: active });
} else {
if(result != 999 ){//跑完后可以重新开始抽奖
this.setState({
flag: true
})
}
clearInterval(this.timer); //清除定时器,停止抽奖
}
}, speed);
}
getPrize() {
let resultIndex = 8 //获取指定奖品(实际为通过接口获取)
setTimeout(() => {
clearInterval(this.timer);// 清除定时器
const { activeIndex } = this.state; //获取跑马灯停止的位置
// 获取清除上一次定时器时停在的位置,作为开启下一个定时器起始位置,并补上未转一整圈的个数,到达指定奖品位置
this.roll(activeIndex, (9 - activeIndex) + resultIndex, 200);
}, 2000);
}
参考原文:http://www.voidcn.com/article/p-aybvrxzd-bww.html