![](https://s5-media.51cto.com/ost/pc/static/noavatar.gif)
回复
【本文正在参加 2023「盲盒」+码有奖征文活动】 https://ost.51cto.com/posts/25284
@toc
使用ArkTS+Grid布局实现抽奖功能,效果如下
// 礼物数据
@State numbers: number[] = [1, 2, 3, 8, 0, 4, 7, 6, 5]
gifts_images: Resource[] = [$r('app.media.1'), $r('app.media.2'), $r('app.media.3'), $r('app.media.4'), $r('app.media.5'), $r('app.media.6'), $r('app.media.7'), $r('app.media.8')]
gifts_hints: string[] = ['玫瑰花', '项链', '戒指', '手表', '护肤品', '口红', '华为Mete60', '红包']
// 礼物索引
@State idx: number = 0
// 抽奖进行进行中标记
@State running: boolean = false
// 当前步数
@State currentStep: number = 0
// 随机步数
@State randomSteps: number = 0
// 随机减速步数
@State randomDecelerationSteps: number = 0
// 速度
@State speed: number = 100
// 抽奖结果
@State resultIndex: number = -1
build() {
Column({ space: 5 }) {
// 标题栏
Text('节日礼物').height(65).fontSize(28).fontWeight(FontWeight.Bold)
// 抽奖区
Grid() {
ForEach(this.numbers, (val: number) => {
GridItem() {
Stack() {
if (val != 0) {
Image(this.gifts_images[val-1])
} else {
Text('开始')
.fontSize(24)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}
.backgroundColor(this.getBGColor(val))
.padding(3)
}.onClick(()=>{
if (val != 0) {
return
}
if (this.running) {
promptAction.showToast({message: '正在抽取中...', duration: 1000})
return
}
this.start()
})
}, day => day)
}
.columnsTemplate('1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('90%')
.backgroundColor(0xFFFFFF)
.height(320)
// 普通提示区
Text('还在纠结节日送什么礼物吗?\n\n来抽一个吧,绝对没有空哒~')
.margin({top:20})
.fontSize(22)
// 中奖提示区
Text('抽到了:' + this.gifts_hints[this.resultIndex] + (this.resultIndex == 7 ? ',快去发吧~' : ',快去买吧~'))
.fontColor('#ff0000')
.margin({top:20})
.fontSize(22)
.visibility(this.running || this.resultIndex == -1 ? Visibility.Hidden : Visibility.Visible)
}.width('100%').margin({ top: 5 })
}
// 获取格子背景色
getBGColor(val: number) {
if (val == 0) {
return '#dddddd'
}
if (val == this.idx) {
return '#ff0000'
}
return '#eeeeee'
}
// 开始抽取
start() {
// 重置索引和启动标记
this.idx = 0
this.running = true
// 随机步数
this.randomSteps = this.getRandom(16, 32)
// 随机减速步数
this.randomDecelerationSteps = this.getRandom(3, 5)
this.loop()
}
loop() {
// 停止和重置
if (this.currentStep >= this.randomSteps) {
this.running = false
this.resultIndex = this.idx - 1
this.currentStep = 0
this.randomSteps = 0
this.randomDecelerationSteps = 0
this.speed = 100
return
}
// 步数递增和控制索引重置
this.currentStep++
if (this.idx == 8) {
this.idx = 1
} else {
this.idx++
}
// 步数是否在减速范围内
if (this.randomSteps - this.currentStep <= this.randomDecelerationSteps) {
this.speed = 300
}
setTimeout(()=>{
this.loop()
}, this.speed)
}
// 获取随机数
getRandom(start, end, fixed = 0) {
let differ = end - start
let random = Math.random()
return (start + differ * random).toFixed(fixed)
}