HarmonyOS 基于JSAPI实现刮刮乐效果 原创 精华

中软小助手
发布于 2022-4-11 10:02
浏览
2收藏

作者: 陈淇

前言:

“我只是想中个彩票一辈子不用不上班而已, 很过分吗 又不是想要天上的星星”。

前段时间经常听见这句话,但是对于我来说,中彩票的几率还是太小了,还是老老实实撸代码吧,用代码来实现一下中彩票的快乐。

效果展示

HarmonyOS   基于JSAPI实现刮刮乐效果-鸿蒙开发者社区

实现步骤

第一步:创建结构

首先根据实现效果创建相应的结构,给刮刮乐画设置背景图片,让它看起来美观

实现效果:

HarmonyOS   基于JSAPI实现刮刮乐效果-鸿蒙开发者社区

hml代码:

xxx.hml

<div class="container" >
    <div class="card">
        <div class="prize-box">
<!--            开奖区域-->
            <text class="text">
                {{ prize }}
            </text>
<!--            刮刮乐涂层-->
            <canvas ref="canvas" style="width:202px;height:43px;" @touchstart="touchstart"
                    @touchmove="touchmove" @touchend="touchend" @touchcancel="touchcancel" class="canvas"></canvas>
        </div>
    </div>
</div>

css代码部分:

.container {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    background-color:#284243 ;
    font-family: sans-serif;
}

/*设置刮奖背景*/
.card{
    width:300px;
    height:300px;
    background-image: url(/common/images/guaguale.png);
    background-size: cover;
    justify-content: space-around;
    align-items: center;
    flex-direction: column;
}


.prize-box{
    margin-left: 5%;
    margin-top: 33%;
    width:202px;
}

/*开奖区域样式*/
.text{
    text-align: center;
    position: absolute;
    width:202px;
    height:43px;
    background-color: #fff;
    z-index: 1;
    font-size: 18px;
    font-weight:600;
}

/*刮刮乐涂层*/
.canvas{
    z-index: 2;
}

完成后实现的效果

第二步:写js代码实现上层刮刮乐涂层效果

通过ctx.fillRect方法实现矩形区域的涂层填充,将画布变为灰色;通过ctx.font设置字体大小,ctx.fillText实现涂层上方文字效果,ctx.fillStyle实现文字颜色设置. 在onShow处进行调用就能实现基础的涂层效果了;

效果图如下:

HarmonyOS   基于JSAPI实现刮刮乐效果-鸿蒙开发者社区

注意:这里在onInit处调用函数不能成功展示出画布,在onShow 时调用才显示成功

xxx.js

	    onShow(){
        this.draw();
    },
    draw(){
        var el = this.$refs.canvas;
        var ctx = el.getContext('2d',{ antialias: true });
        this.el = el
        this.ctx = ctx

        //填充的颜色
        ctx.fillStyle = 'gray';
        //填充矩形  fillRect(起始X,起始Y,终点X,终点Y)
        ctx.fillRect(0, 0, 202, 43);

        this.ctx.fillStyle = '#000';
        //绘制填充文字
        this.ctx.font = "28px";
        this.ctx.fillText('刮开有奖', 50, 30);
    },
第三步:给canvas设置触摸事件,实现效果

给canvas画布上绑定触摸事件,在触摸时计算触摸点的位置,以触摸点的坐标为圆心,进行圆形区域的擦除。

触摸点坐标计算: 通过触摸事件得到一个对象, 将对象进行解析会得到对应的值,对数据进行处理,拿到触摸点的X,Y坐标点。

调用ctx.arc方法进行画圆,选中圆形区域进行消除。

xxx.hml

  <canvas ref="canvas" style="width:202px;height:43px;" @touchstart="touchstart"
                    @touchmove="touchmove" @touchend="touchend" @touchcancel="touchcancel" class="canvas"></canvas>
xxx.js


    touchstart() {
        this.isDraw = true;
    },

    touchmove(e) {
        let x = JSON.stringify(e.touches)
        //去掉中括号,将其变成对象
        let x1 = x.replace(/\[|]/g,'')
        let x2 = JSON.parse(x1)
        let x3 = JSON.stringify(x2)

        //计算触摸点位置
        let X1 = parseInt(JSON.parse(x3).localX)
        let Y1 = parseInt(JSON.parse(x3).localY)
        this.ctx.globalCompositeOperation = 'destination-out';

        //画圆
        this.ctx.arc(X1, Y1, 10, 0, 2 * Math.PI);
        console.log('6666666')
        //填充圆形
        this.ctx.fill();
    },

    touchend() {
        this.isDraw = false;
    },

    touchcancel(){
        this.isDraw = false
    },

第四步:设置超过一定百分比清除画布

计算刮过区域的面积:使用ctx.getImageData方法得到整个区域的图像信息。

getImageData() 方法返回 ImageData 对象,该对象拷贝了画布指定矩形的像素数据。

对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:

  • R - 红色 (0-255)
  • G - 绿色 (0-255)
  • B - 蓝色 (0-255)
  • A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)

color/alpha 以数组形式存在,并存储于 ImageData 对象的 data 属性中。

通过判断像素点的A值是否为0来判断已经刮过的区域进行计算,最终将计算出的区域面积与总面积进行对比来设置刮除区域超过多少百分比时进行清除整个区域。

通过调用ctx.clearRect方法来进行整个区域的清除。

    //计算已经刮过的区域占整个区域的百分比
    getFilledPercentage(){
        let imgData = this.ctx.getImageData(0,0,this.mWidth,this.mHeight);
        //imgData.data是个数组,存储着指定区域每个像素点的信息,数组中4个元素表示一个像素点的rgba值
        let pixels = imgData.data;
        let transPixels = [];
        for(let i=0;i<pixels.length;i+=4){
            //需要判断像素点是否透明需要判断该像素点的a值是否为0
            if(pixels[i+3] == 0){
                transPixels.push(pixels[i+3])
            }
        }
        return (transPixels.length/(pixels.length/4)*100).toFixed(2) + '%'
    },

    //设置阈值,去除灰色涂层
    handleFilledPercentage(percentage){
        percentage = percentage || 0;
        console.log('percentage =' + percentage)
        if(parseInt(percentage)>50){
            //去除画布方法一:直接将canvas涂层清除
            this.ctx.clearRect(0,0,this.mWidth,this.mHeight)
            console.log('清除画布')

            //方法2:将canvas涂层设置为透明
            //this.ctx.fillStyle = 'rgba(255,255,255)';
            //this.ctx.fillRect(0,0,this.mWidth,this.mHeight)
        }
    },

源码地址

https://gitee.com/chen-qi-7/demo-g

总结

以上就是制作一个刮刮乐的详细过程了,最终效果与上面的效果一样.其实是一个很简单的功能,利用了canvas的一些特性来进行操作,后期还可以给其增加更多的功能,欢迎各位开发者一起讨论与研究,希望本次分享对大家的学习有所帮助。

更多原创内容请关注:中软国际 HarmonyOS 技术团队

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

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
4
收藏 2
回复
举报
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

非常有意思的功能,感谢作者分享。

回复
2022-4-11 14:18:15
回复
    相关推荐