“我只是想中个彩票一辈子不用不上班而已,很过分吗,又不是想要天上的星星”。
实现步骤
首先根据实现效果创建相应的结构,给刮刮乐画设置背景图片,让它看起来美观。
实现效果:
hml代码:
xxx.hml
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;}
完成后实现的效果。
通过ctx.fillRect方法实现矩形区域的涂层填充,将画布变为灰色;通过ctx.font设置字体大小。
ctx.fillText实现涂层上方文字效果,ctx.fillStyle实现文字颜色设置。在onShow处进行调用就能实现基础的涂层效果了。
效果图如下:
注意:这里在onInit处调用函数不能成功展示出画布,在onShow时调用才显示成功。
xxx.jsonShow(){this.draw();},draw(){varel=this.$refs.canvas;varctx=el.getContext('2d',{antialias:true});this.el=elthis.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画布上绑定触摸事件,在触摸时计算触摸点的位置,以触摸点的坐标为圆心,进行圆形区域的擦除。
触摸点坐标计算:通过触摸事件得到一个对象,将对象进行解析会得到对应的值,对数据进行处理,拿到触摸点的X,Y坐标点。
调用ctx.arc方法进行画圆,选中圆形区域进行消除。
xxx.hmlref="canvas"style="width:202px;height:43px;"@touchstart="touchstart"@touchmove="touchmove"@touchend="touchend"@touchcancel="touchcancel"class="canvas">
xxx.jstouchstart(){this.isDraw=true;},touchmove(e){letx=JSON.stringify(e.touches)//去掉中括号,将其变成对象letx1=x.replace(/[|]/g,'')letx2=JSON.parse(x1)letx3=JSON.stringify(x2)//计算触摸点位置letX1=parseInt(JSON.parse(x3).localX)letY1=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值:
color/alpha以数组形式存在,并存储于ImageData对象的data属性中。
通过判断像素点的A值是否为0来判断已经刮过的区域进行计算,最终将计算出的区域面积与总面积进行对比来设置刮除区域超过多少百分比时进行清除整个区域。
通过调用ctx.clearRect方法来进行整个区域的清除。
//计算已经刮过的区域占整个区域的百分比getFilledPercentage(){letimgData=this.ctx.getImageData(0,0,this.mWidth,this.mHeight);//imgData.data是个数组,存储着指定区域每个像素点的信息,数组中4个元素表示一个像素点的rgba值letpixels=imgData.data;lettransPixels=[];for(leti=0;i4){//需要判断像素点是否透明需要判断该像素点的a值是否为0if(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)}},