春节不停更,此文正在参加「星光计划-春节更帖活动」

作者:彭为杰

简介

分享一下HarmonyOS中JS如何实现抽奖效果的一种思路。

效果演示

luck.gif

实现思路

1,动态计算出奖品大小及固定好奖品位置;

js中一开始获取到的布局宽高为0,无法计算奖品宽高,采用js调java方式确认屏幕宽高

2,转动过程,不断改变当前高亮位置,直接停止;

1 项目结构

daima.jpg

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
    }

总结

祝大家新的一年的好远连连!

代码地址

JS之幸运大抽奖demo

更多原创内容请关注:深开鸿技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

想了解更多关于鸿蒙的内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#bkwz

::: hljs-center

21_9.jpg

:::