java 9宫格抽奖_js 实现9宫格抽奖(react)

最近工作中有个9宫格抽奖的需求,一开始没啥思绪,网上查阅一番,自己又修改了一下,希望与大家交流分享。

先看一下效果图8e9b960c8ccb1322398c46c1bc6d4f61.gif

整理一下思路

利用flex布局形成9宫格,每个格子的序号为0~8,创建一个记录当前指针的变量,点击抽奖,指正转动,当index等于变量的时候让当前格子与其他格子样式不一致,当请求后台有结果时,让指针等于结果值。

c14b4e72e45cd4a058294fbc829c2329.png

上图中黑色数组代表奖品元素排列的顺序,其中4为抽奖按钮,红色数字则为指针转动的路线。

上代码:

首先定义几个变量

constructor (props) {

super(props)

this.state = {

timer1: '', // 定时器1 快速旋转

timer2: '', // 定时器2 慢速旋转

prizeIndex: 0, // 转动指针

stopIndex: null, // 抽中奖品

arrNum: [0, 1, 2, 5, 8, 7, 6, 3], // 转动顺序

luckList: [], // 奖品集合

isRolling: false // 是否正在抽奖

}

// 这边绑定是必要的,这样 `this` 才能在回调函数中使用

this.drawPrize = this.drawPrize.bind(this);

this.move = this.move.bind(this);

this.lowSpeed = this.lowSpeed.bind(this);

}

复制代码

然后根据数据写DOM渲染的条件

因为后台返回数据只有8条奖品,所以再获取奖品集合时对数据做一些改变,这个根据实际情况而定

res.data.dtls.splice(4, 0, {prizeName: "抽奖按钮", type: 0});

复制代码

这里利用type属性对奖品和抽奖按钮做区分

renderLi = () => {

let {luckList} = this.state;

return luckList.map((list, index) => {

if (list.type !== 0) {

return

{list.type===1||list.type===2?

:

list.type===3?

: ""

}

{list.prizeName}

} else {

return

}

})

}

复制代码

{this.renderLi()}

复制代码

点击抽奖按钮运行函数drawPrize

// 点击抽奖 执行快速转动,2秒后执行慢速转动

async drawPrize() {

if (!this.state.isRolling) {

this.setState({

prizeIndex: 0,

stopIndex: null,

isRolling: true,

timer1: setInterval(this.move, 100)

});

setTimeout(() => { //转一圈半之后降速

clearInterval(this.state.timer1);

this.lowSpeed()

}, 2000)

}

}

复制代码

慢速转动

lowSpeed() {//慢速转动

// 先清除快速转动的定时器

clearInterval(this.state.timer1);

// 请求接口,获取转动结果

api.lotteryId(this.state.lotteryId, token).then(res => {

if(res.resultCode === '0') {

let stopIndex = null

// 对转动结果做处理

switch (res.data) {

case 4:

stopIndex = 3

break;

case 7:

stopIndex = 4

break;

case 6:

stopIndex = 5

break;

case 5:

stopIndex = 6

break;

case 3:

stopIndex = 7

break;

case 0:

stopIndex = 0

break;

case 1:

stopIndex = 1

break;

case 2:

stopIndex = 2

break;

default:

stopIndex = null

break

}

// 得到结果再起调用move函数,速度降低

this.setState({

stopIndex: stopIndex,

timer2: setInterval(this.move, 300)

});

}

}

复制代码

执行转动函数move

move() {//转动

let luckList = this.state.luckList

let arrNum = this.state.arrNum

// chose=1为转动到位置,0为正常位置

luckList[arrNum[this.state.prizeIndex]].chose = 1

luckList[arrNum[this.state.prizeIndex-1<0?7:this.state.prizeIndex-1]].chose = 0

// 如果指针位置prizeIndex与结果位置相同,则抽奖完成,清除所有定时器

if (this.state.stopIndex !== null && (this.state.prizeIndex === this.state.stopIndex)) {

clearInterval(this.state.timer1);

clearInterval(this.state.timer2);

setTimeout(() => {

this.setState({

isRolling: false // 可以继续抽奖

})

}, 300);

}

// 否则,继续转动,这里需要对零界位置做一下处理

else {

this.setState({

prizeIndex: this.state.prizeIndex + 1 === 8 ? 0 : this.state.prizeIndex + 1

})

}

}

复制代码

另外需要在第二次点击时恢复状态值,我是在其他条件下做的处理,这个根据实际情况而定。

好了,一个简单的9宫格抽奖就完成了,有更好的,更丰富的方案的请不吝赐教。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现9宫格抽奖,可以使用Vue.js框架的component组件进行实现。具体步骤如下: 1. 创建一个九宫格的组件,可以通过table标签和tr、td标签组合实现: ``` <template> <table> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> <tr> <td>4</td> <td>5</td> <td>6</td> </tr> <tr> <td>7</td> <td>8</td> <td>9</td> </tr> </table> </template> ``` 2. 在组件中定义数据,用于控制九宫格指针的指向,以及奖品的位置: ``` <script> export default { data() { return { pointer: 0, // 指针位置 prizeIndex: 4, // 奖品位置 rotating: false // 是否正在旋转 }; } }; </script> ``` 3. 在组件中定义方法,用于处理抽奖逻辑,例如开始抽奖、停止抽奖等: ``` <script> export default { data() { return { pointer: 0, // 指针位置 prizeIndex: 4, // 奖品位置 rotating: false // 是否正在旋转 }; }, methods: { start() { if (this.rotating) return; this.rotating = true; let interval = setInterval(() => { this.pointer = (this.pointer + 1) % 9; }, 100); setTimeout(() => { clearInterval(interval); this.rotating = false; if (this.pointer === this.prizeIndex) { alert("恭喜您中奖了!"); } else { alert("很遗憾,您没有中奖!"); } }, 3000); } } }; </script> ``` 4. 在组件中添加样式,用于实现宫格的样式,以及指针的指向: ``` <style scoped> table { width: 200px; height: 200px; border-collapse: collapse; } td { width: 30px; height: 30px; text-align: center; vertical-align: middle; border: 1px solid #ccc; } .active { background-color: orange; } .pointer { position: relative; &::before, &::after { content: ""; position: absolute; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-style: solid; border-width: 0 10px 20px 10px; } &::before { top: -20px; border-color: transparent transparent orange transparent; } &::after { bottom: -20px; border-color: orange transparent transparent transparent; } } </style> ``` 5. 在组件中添加指针的样式类,并根据指针位置动态添加该样式类: ``` <template> <table> <tr> <td :class="{ active: pointer === 0 }">1</td> <td :class="{ active: pointer === 1 }">2</td> <td :class="{ active: pointer === 2 }">3</td> </tr> <tr> <td :class="{ active: pointer === 7 }">4</td> <td :class="{ active: pointer === 8 }">5</td> <td :class="{ active: pointer === 3 }">6</td> </tr> <tr> <td :class="{ active: pointer === 6 }">7</td> <td :class="{ active: pointer === 5 }">8</td> <td :class="{ active: pointer === 4 }">9</td> </tr> </table> </template> ``` 6. 在组件中添加开始抽奖按钮,以及绑定开始抽奖方法: ``` <template> <div> <table> ... </table> <button @click="start">开始抽奖</button> </div> </template> ``` 完整代码如下: ``` <template> <div> <table> <tr> <td :class="{ active: pointer === 0 }">1</td> <td :class="{ active: pointer === 1 }">2</td> <td :class="{ active: pointer === 2 }">3</td> </tr> <tr> <td :class="{ active: pointer === 7 }">4</td> <td :class="{ active: pointer === 8 }">5</td> <td :class="{ active: pointer === 3 }">6</td> </tr> <tr> <td :class="{ active: pointer === 6 }">7</td> <td :class="{ active: pointer === 5 }">8</td> <td :class="{ active: pointer === 4 }">9</td> </tr> </table> <button @click="start">开始抽奖</button> </div> </template> <script> export default { data() { return { pointer: 0, // 指针位置 prizeIndex: 4, // 奖品位置 rotating: false // 是否正在旋转 }; }, methods: { start() { if (this.rotating) return; this.rotating = true; let interval = setInterval(() => { this.pointer = (this.pointer + 1) % 9; }, 100); setTimeout(() => { clearInterval(interval); this.rotating = false; if (this.pointer === this.prizeIndex) { alert("恭喜您中奖了!"); } else { alert("很遗憾,您没有中奖!"); } }, 3000); } } }; </script> <style scoped> table { width: 200px; height: 200px; border-collapse: collapse; } td { width: 30px; height: 30px; text-align: center; vertical-align: middle; border: 1px solid #ccc; } .active { background-color: orange; } .pointer { position: relative; &::before, &::after { content: ""; position: absolute; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-style: solid; border-width: 0 10px 20px 10px; } &::before { top: -20px; border-color: transparent transparent orange transparent; } &::after { bottom: -20px; border-color: orange transparent transparent transparent; } } </style> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值