# demoG **Repository Path**: chen-qi-7/demo-g ## Basic Information - **Project Name**: demoG - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-03-29 - **Last Updated**: 2022-04-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### HarmonyOS 基于JSAPI实现刮刮乐效果 作者: 陈淇 ### 前言: "我只是想中个彩票一辈子不用不上班而已, 很过分吗 又不是想要天上的星星" 前段时间经常听见这句话,但是对于我来说,中彩票的几率还是太小了,还是老老实实撸代码吧,用代码来实现一下中彩票的快乐. ### 效果展示 ![](D:\chenqi\demo\HarmonyOS - 基于JSAPI实现刮刮乐\刮刮乐效果图.gif) ### 实现步骤 ##### 第一步:创建结构 首先根据实现效果创建相应的结构,创建一个div和一个canvas画布,div展示中奖内容,canvas画布实现刮刮乐涂层效果. hml代码: ```html xxx.hml
//展示文字 恭喜您获得带薪工作5日奖 //canvas涂层
``` css代码部分: ```css xxx.css .container { flex-direction: column; justify-content: center; align-items: center; width: 100%; height: 100%; } .text { position: absolute; left:10%; top: 50%; z-index: -1; font-size: 20px; } ``` ##### 第二步:实现上层灰色蒙版和刮刮乐文字效果 通过ctx.fillRect方法实现矩形区域的涂层填充,将画布变为灰色;通过ctx.fillText实现涂层上方文字效果,在onShow处进行调用就能实现基础的涂层效果了; 效果图如下: ![](D:\chenqi\demo\HarmonyOS - 基于JSAPI实现刮刮乐\涂层效果图.gif) 注意:这里在onInit处调用函数不能成功展示出画布,在onShow 时调用才显示成功 ```js 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, 400, 100); ctx.fillStyle = "#fff"; //绘制填充文字 ctx.fillText("刮刮卡", 180, 50); console.log("cqtest 0 文字填充完成") }, ``` ##### 第三步:给canvas设置触摸事件,实现效果 给canvas画布上绑定触摸事件,在触摸时计算触摸点的位置,以触摸点的坐标为圆心,进行圆形区域的擦除. 触摸点坐标计算: 通过触摸事件得到一个对象, 将对象进行解析会得到对应的值,对数据进行处理,拿到触摸点的X,Y坐标点. 调用ctx.arc方法进行画圆,选中圆形区域. ```html xxx.hml ``` ```js xxx.js touchstart() { console.log("cqtest 1 开始触摸") this.isDraw = true; console.log("clientX" + this.el.clientX) console.log("clientY" + this.el.clientY) }, touchmove(e) { console.log("cqtest 2 触摸" + JSON.stringify(e)) let x = JSON.stringify(e.touches) console.log("cqtest 2 触摸" + x) //去掉中括号,将其变成对象 let x1 = x.replace(/\[|]/g,"") console.log("cqtest 2 触摸" + x1) let x2 = JSON.parse(x1) console.log("cqtest 2 触摸2" + x2) 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(); } ``` ##### 第四步:设置超过一定百分比清除画布 计算刮过区域的面积:使用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](https://www.w3school.com.cn/tags/canvas_imagedata_data.asp) 属性中. 通过判断像素点的A值是否为0来判断已经刮过的区域进行计算,最终将计算出的区域面积与总面积进行对比来设置刮除区域超过多少百分比时进行清除整个区域. 通过调用ctx.clearRect方法来进行整个区域的清除. ```js //计算已经刮过的区域占整个区域的百分比 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