作者:彭为杰
简介
分享一下HarmonyOS中JS如何实现抽奖效果的一种思路。
效果演示
实现思路
1,动态计算出奖品大小及固定好奖品位置;
js中一开始获取到的布局宽高为0,无法计算奖品宽高,采用js调java方式确认屏幕宽高
2,转动过程,不断改变当前高亮位置,直接停止;
1 项目结构
2 宫格布局
定义构造函数,声明绘制圆的参数;
<stack id="container" class="container">
<!-- 背景-->
<div class="lottery" style="margin-top : {{ bgPadding }};">
<image show="{{ ! bgState }}" src="common/images/k1.png"
style="width : {{ bgWidth }}; height : {{ bgHeight }};">
</image>
<image show="{{ bgState }}" src="common/images/k2.png"
style="width : {{ bgWidth }}; height : {{ bgHeight }};">
</image>
</div>
<div class="lottery" style="margin-top : {{ 3 * bgPadding }};">
<div class="{{ index == 0 ? 'lotteryBox_On' : 'lotteryBox_Off' }} lotteryBox" style="width : {{ itemWidth }}; height : {{ itemHeight }};">
<image class="img" src="{{ list[0].img }}"></image>
<text class="title"> {{ list[0].title }}</text>
</div>
<div class="{{ index == 1 ? 'lotteryBox_On' : 'lotteryBox_Off' }} lotteryBox" style="width : {{ itemWidth }}; height : {{ itemHeight }};
margin-left : {{ bgPadding }};">
<image class="img" src="{{ list[1].img }}"></image>
<text class="title">{{ list[1].title }}</text>
</div>
<div class="{{ index == 2 ? 'lotteryBox_On' : 'lotteryBox_Off' }} lotteryBox" style="width : {{ itemWidth }}; height : {{ itemHeight }};
margin-left : {{ bgPadding }};">
<image class="img" src="{{ list[2].img }}"></image>
<text class="title">{{ list[2].title }}</text>
</div>
</div>
<div class="lottery" style="margin-top : {{ 4 * bgPadding + itemHeight }};">
<div class="{{ index == 7 ? 'lotteryBox_On' : 'lotteryBox_Off' }} lotteryBox" style="width : {{ itemWidth }}; height : {{ itemHeight }};">
<image class="img" src="{{ list[7].img }}"></image>
<text class="title"> {{ list[7].title }}</text>
</div>
<div on:click="startLottery" class="lotteryBox {{ isStart ? 'lotteryBox_enable' : 'lotteryBox_On'}}" style="width : {{ itemWidth }}; height : {{ itemHeight }};
margin-left : {{ bgPadding }};">
<text class="start">开始</text>
</div>
<div class="{{ index == 3 ? 'lotteryBox_On' : 'lotteryBox_Off' }} lotteryBox" style="width : {{ itemWidth }}; height : {{ itemHeight }};
margin-left : {{ bgPadding }};">
<image class="img" src="{{ list[3].img }}"></image>
<text class="title">{{ list[3].title }}</text>
</div>
</div>
<div class="lottery" style="margin-top : {{ 5 * bgPadding + 2 * itemHeight }};">
<div class="{{ index == 6 ? 'lotteryBox_On' : 'lotteryBox_Off' }} lotteryBox" style="width : {{ itemWidth }}; height : {{ itemHeight }};">
<image class="img" src="{{ list[6].img }}"></image>
<text class="title"> {{ list[6].title }}</text>
</div>
<div class="{{ index == 5 ? 'lotteryBox_On' : 'lotteryBox_Off' }} lotteryBox" style="width : {{ itemWidth }}; height : {{ itemHeight }};
margin-left : {{ bgPadding }};">
<image class="img" src="{{ list[5].img }}"></image>
<text class="title">{{ list[5].title }}</text>
</div>
<div class="{{ index == 4 ? 'lotteryBox_On' : 'lotteryBox_Off' }} lotteryBox" style="width : {{ itemWidth }}; height : {{ itemHeight }};
margin-left : {{ bgPadding }};">
<image class="img" src="{{ list[4].img }}"></image>
<text class="title">{{ list[4].title }}</text>
</div>
</div>
<dialog id="deviceCommonDialog" oncancel="cancel">
<div class="dialogContainer lottery">
<text style="color: red; margin-top: 20px;"> 恭喜!</text>
<image class="img" src="{{ prizeItem.img }}"></image>
<text style="color: red; margin-bottom: 20px;">获得{{ prizeItem.title}}</text>
</div>
</dialog>
</stack>
3 转动动画逻辑
// 开始转动
startRoll() {
this.times += 1 // 转动次数
this.oneRoll() // 转动过程调用的每一次转动方法,这里是第一次调用初始化
// 如果当前转动次数达到要求 && 目前转到的位置是中奖位置
if (this.times > this.cycle + 10 && this.prize === this.index) {
clearTimeout(this.timer) // 清除转动定时器,停止转动
this.prize = -1
this.times = 0
this.speed = 200
this.isStart = false;
var that = this;
setTimeout(res => {
that.dialogShow();
}, 500)
} else {
if (this.times < this.cycle) {
this.speed -= 10 // 加快转动速度
} else if (this.times === this.cycle) {
const index = parseInt(Math.random() * 7, 0) || 0; // 随机获得一个中奖位置
this.prize = index; //中奖位置,可由后台返回
if (this.prize > 7) {
this.prize = 7
}
this.prizeItem = this.list[this.prize]
} else if (this.times > this.cycle + 10 && ((this.prize === 0 && this.index === 7) || this.prize === this.index + 1)) {
this.speed += 110
} else {
this.speed += 20
}
if (this.speed < 40) {
this.speed = 40
}
this.timer = setTimeout(this.startRoll, this.speed)
}
},
// 每一次转动
oneRoll() {
let index = this.index // 当前转动到哪个位置
const count = this.count // 总共有多少个位置
index += 1
if (index > count - 1) {
index = 0
}
this.index = index
}
总结
祝大家新的一年的好远连连!
代码地址
更多原创内容请关注:深开鸿技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
https://harmonyos.51cto.com/#bkwz
::: hljs-center
:::