“我只是想中個(gè)彩票一輩子不用不上班而已,很過(guò)分嗎,又不是想要天上的星星”。
前段時(shí)間經(jīng)常聽(tīng)見(jiàn)這句話,但是對(duì)于我來(lái)說(shuō),中彩票的幾率還是太小了,還是老老實(shí)實(shí)擼代碼吧,用代碼來(lái)實(shí)現(xiàn)一下中彩票的快樂(lè)。
實(shí)現(xiàn)步驟
第一步:創(chuàng)建結(jié)構(gòu)
首先根據(jù)實(shí)現(xiàn)效果創(chuàng)建相應(yīng)的結(jié)構(gòu),給刮刮樂(lè)畫(huà)設(shè)置背景圖片,讓它看起來(lái)美觀。
實(shí)現(xiàn)效果:
hml 代碼:
xxx.hml
<divclass="container">
<divclass="card">
<divclass="prize-box">
<textclass="text">
{{prize}}
text>
<canvasref="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;
}
/*設(shè)置刮獎(jiǎng)背景*/
.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;
}
/*開(kāi)獎(jiǎng)區(qū)域樣式*/
.text{
text-align:center;
position:absolute;
width:202px;
height:43px;
background-color:#fff;
z-index:1;
font-size:18px;
font-weight:600;
}
/*刮刮樂(lè)涂層*/
.canvas{
z-index:2;
}
完成后實(shí)現(xiàn)的效果。
第二步:寫(xiě) js 代碼實(shí)現(xiàn)上層刮刮樂(lè)涂層效果
通過(guò) ctx.fillRect 方法實(shí)現(xiàn)矩形區(qū)域的涂層填充,將畫(huà)布變?yōu)榛疑?;通過(guò) ctx.font 設(shè)置字體大小。
ctx.fillText 實(shí)現(xiàn)涂層上方文字效果,ctx.fillStyle 實(shí)現(xiàn)文字顏色設(shè)置。在 onShow 處進(jìn)行調(diào)用就能實(shí)現(xiàn)基礎(chǔ)的涂層效果了。
效果圖如下:
注意:這里在 onInit 處調(diào)用函數(shù)不能成功展示出畫(huà)布,在 onShow 時(shí)調(diào)用才顯示成功。
xxx.js
onShow(){
this.draw();
},
draw(){
varel=this.$refs.canvas;
varctx=el.getContext('2d',{antialias:true});
this.el=el
this.ctx=ctx
//填充的顏色
ctx.fillStyle='gray';
//填充矩形fillRect(起始X,起始Y,終點(diǎn)X,終點(diǎn)Y)
ctx.fillRect(0,0,202,43);
this.ctx.fillStyle='#000';
//繪制填充文字
this.ctx.font="28px";
this.ctx.fillText('刮開(kāi)有獎(jiǎng)',50,30);
},
第三步:給 canvas 設(shè)置觸摸事件,實(shí)現(xiàn)效果
給 canvas 畫(huà)布上綁定觸摸事件,在觸摸時(shí)計(jì)算觸摸點(diǎn)的位置,以觸摸點(diǎn)的坐標(biāo)為圓心,進(jìn)行圓形區(qū)域的擦除。
觸摸點(diǎn)坐標(biāo)計(jì)算:通過(guò)觸摸事件得到一個(gè)對(duì)象,將對(duì)象進(jìn)行解析會(huì)得到對(duì)應(yīng)的值,對(duì)數(shù)據(jù)進(jìn)行處理,拿到觸摸點(diǎn)的 X,Y 坐標(biāo)點(diǎn)。
調(diào)用 ctx.arc 方法進(jìn)行畫(huà)圓,選中圓形區(qū)域進(jìn)行消除。
xxx.hml
xxx.js
touchstart(){
this.isDraw=true;
},
touchmove(e){
letx=JSON.stringify(e.touches)
//去掉中括號(hào),將其變成對(duì)象
letx1=x.replace(/[|]/g,'')
letx2=JSON.parse(x1)
letx3=JSON.stringify(x2)
//計(jì)算觸摸點(diǎn)位置
letX1=parseInt(JSON.parse(x3).localX)
letY1=parseInt(JSON.parse(x3).localY)
this.ctx.globalCompositeOperation='destination-out';
//畫(huà)圓
this.ctx.arc(X1,Y1,10,0,2*Math.PI);
console.log('6666666')
//填充圓形
this.ctx.fill();
},
touchend(){
this.isDraw=false;
},
touchcancel(){
this.isDraw=false
},
第四步:設(shè)置超過(guò)一定百分比清除畫(huà)布
計(jì)算刮過(guò)區(qū)域的面積:使用 ctx.getImageData 方法得到整個(gè)區(qū)域的圖像信息。
getImageData() 方法返回 ImageData 對(duì)象,該對(duì)象拷貝了畫(huà)布指定矩形的像素?cái)?shù)據(jù)。
對(duì)于 ImageData 對(duì)象中的每個(gè)像素,都存在著四方面的信息,即 RGBA 值:
-
R - 紅色(0-255)
-
G - 綠色(0-255)
-
B - 藍(lán)色(0-255)
-
A - alpha 通道(0-255;0 是透明的,255 是完全可見(jiàn)的)
color/alpha 以數(shù)組形式存在,并存儲(chǔ)于 ImageData 對(duì)象的data屬性中。
通過(guò)判斷像素點(diǎn)的 A 值是否為 0 來(lái)判斷已經(jīng)刮過(guò)的區(qū)域進(jìn)行計(jì)算,最終將計(jì)算出的區(qū)域面積與總面積進(jìn)行對(duì)比來(lái)設(shè)置刮除區(qū)域超過(guò)多少百分比時(shí)進(jìn)行清除整個(gè)區(qū)域。
通過(guò)調(diào)用 ctx.clearRect 方法來(lái)進(jìn)行整個(gè)區(qū)域的清除。
//計(jì)算已經(jīng)刮過(guò)的區(qū)域占整個(gè)區(qū)域的百分比
getFilledPercentage(){
letimgData=this.ctx.getImageData(0,0,this.mWidth,this.mHeight);
//imgData.data是個(gè)數(shù)組,存儲(chǔ)著指定區(qū)域每個(gè)像素點(diǎn)的信息,數(shù)組中4個(gè)元素表示一個(gè)像素點(diǎn)的rgba值
letpixels=imgData.data;
lettransPixels=[];
for(leti=0;i4){
//需要判斷像素點(diǎn)是否透明需要判斷該像素點(diǎn)的a值是否為0
if(pixels[i+3]==0){
transPixels.push(pixels[i+3])
}
}
return(transPixels.length/(pixels.length/4)*100).toFixed(2)+'%'
},
//設(shè)置閾值,去除灰色涂層
handleFilledPercentage(percentage){
percentage=percentage||0;
console.log('percentage='+percentage)
if(parseInt(percentage)>50){
//去除畫(huà)布方法一:直接將canvas涂層清除
this.ctx.clearRect(0,0,this.mWidth,this.mHeight)
console.log('清除畫(huà)布')
//方法2:將canvas涂層設(shè)置為透明
//this.ctx.fillStyle='rgba(255,255,255)';
//this.ctx.fillRect(0,0,this.mWidth,this.mHeight)
}
},
源碼地址:
https://gitee.com/chen-qi-7/demo-g
總結(jié)
以上就是制作一個(gè)刮刮樂(lè)的詳細(xì)過(guò)程了,最終效果與上面的效果一樣。其實(shí)是一個(gè)很簡(jiǎn)單的功能,利用了 canvas 的一些特性來(lái)進(jìn)行操作,后期還可以給其增加更多的功能,歡迎各位開(kāi)發(fā)者一起討論與研究,希望本次分享對(duì)大家的學(xué)習(xí)有所幫助。
原文標(biāo)題:HarmonyOS基于JSAPI實(shí)現(xiàn)刮刮樂(lè)效果
文章出處:【微信公眾號(hào):HarmonyOS技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
代碼
+關(guān)注
關(guān)注
30文章
4791瀏覽量
68694 -
HarmonyOS
+關(guān)注
關(guān)注
79文章
1977瀏覽量
30262
原文標(biāo)題:HarmonyOS基于JSAPI實(shí)現(xiàn)刮刮樂(lè)效果
文章出處:【微信號(hào):gh_834c4b3d87fe,微信公眾號(hào):OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論