移动端刮刮乐的实现方式(js+HTML5)
程序员有一种惯性思维,就是看见一些会动的东西(带点科技含量的,猫啊,狗啊就算了),总要先想一遍,这玩意用代码是怎么控制的。比如电梯,路边的霓虹灯,遥控器,小孩子的玩具等,都统统被程序员“意淫”过。
有时候还会感觉程序员看世界会看的透彻一点.............
想必大家都玩过刮刮乐,下面就介绍一种刮刮乐的移动端实现方式!用到canvas
1、用html 5 canvas globalcompositeoperation 属性实现刮刮乐
思路:
(1)首先需要一个盒子定位,确定刮刮乐区域想要放在哪里
(2)定位盒子里有个放内容的盒子,也就是放奖品的
(3)用一个画布(canvas)把上面的盒子盖住
(4)当手触摸移动的时候,可以擦除部分画布,露出奖品区
(5)当擦除足够多(3/4)的时候,可以选择让画布自动消失,慢慢淡出(这个效果选做)
主要是第四步,如何擦除?
这里选用 globalcompositeoperation,即canvas中的合成操作。简单来说,composite(组合),就是对你在绘图中,后绘制的图形与先绘制的图形之间的组合显示效果,比如在国画中,你先画一笔红色,再来一笔绿色,相交的部分是一种混色,而在油画中,绿色就会覆盖掉相交部分的红色,这在程序绘图中的处理就是composite,canvas api中对应的函数就是globalcompositeoperation。
globalcompositeoperation中有个属性值是“destination-out",也就是当绘画重叠时显示透明。刚好用到这里,我们就可以在画布上乱画,画过的地方就是重叠的地方,就会变成透明,然后露出画布下的东西,也就是我们想要的效果。
html 代码如下:
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title></title> <link rel="stylesheet" type="text/css" href="css/guaguale.css" rel="external nofollow" /> </head> <body> <!-- 大的背景盒子--> <div id="main"> <!-- 定位的盒子--> <div class="canvasbox"> <!-- 放内容的盒子--> <span id="prize"> 恭喜发财,红包拿来 </span> <!-- 蒙版画布--> <canvas id="canvas"></canvas> </div> </div> </body> <script type="text/javascript"> var canvas = document.getelementbyid("canvas"); var ctx = canvas.getcontext('2d'); /* 画布偏移量,下面用到的时候再介绍*/ var arr = getoffset(canvas); var oleft = arr[0]; var otop = arr[1]; /* 初始化画布*/ ctx.beginpath(); ctx.fillstyle = '#ccc'; ctx.fillrect(0,0,canvas.width,canvas.height); ctx.closepath(); /* 增加触摸监听*/ document.addeventlistener("touchstart",function(){ /* 初始化画笔*/ ctx.beginpath(); /* 画笔粗细*/ ctx.linewidth = 30; /* 设置组合效果*/ ctx.globalcompositeoperation = 'destination-out'; /* 移动画笔原点*/ ctx.moveto(event.touches[0].pagex-oleft,event.touches[0].pagey-otop); },false) document.addeventlistener("touchmove",function(){ /* 根据手指移动画线,使之变透明*/ ctx.lineto(event.touches[0].pagex-oleft,event.touches[0].pagey-otop); /* 填充*/ ctx.stroke(); }) /* 之所以会用到下面的那个函数getoffset(obj) * 是因为event.touches[0].pagex、pagey获取的是相对于可视窗口的距离 * 而lineto画笔的定位是根据画布位置定位的 * 所以就要先获取到画布(canvas)相对于可视窗口的距离,然后计算得出触摸点相对于画布的距离 * */ /* 获取该元素到可视窗口的距离*/ function getoffset(obj){ var valleft = 0,valtop = 0; function get(obj){ valleft += obj.offsetleft; valtop += obj.offsettop; /* 不到最外层就一直调用,直到offsetparent为body*/ if (obj.offsetparent.tagname!='body') { get(obj.offsetparent); } return [valleft,valtop]; } return get(obj); } </script> </html>
css代码如下:
*{ margin: 0; padding: 0; } #main{ width: 100%; padding: 20px 0; background-color: red; } .canvasbox{ width: 78%; height: 160px; border-radius: 10px; background-color: #fff; margin-left: 11%; line-height: 160px; text-align: center; position: relative; } #canvas{ width: 96%; height: 96%; position: absolute; left: 2%; top: 2%; background-color: transparent; }
第五步要用到canvas像素点的获取(这块注意,像素级操作,要在服务器环境下打开)
getimagedata(int x,int y,int width,int height):该方法获取canvas上从(x,y)点开始,宽为width、高为height的图片区域的数据,该方法返回的是一个canvaspixelarray对象,该对象具有width、height、data等属性。data属性为一个数组,该数组每4个元素对应一个像素点。
(对图片的反相操作也可以这样做,改变rgba值)
getimagedata(int x,int y,int width,int height)返回的对象,data里面存储的是像素点信息
我们再打印data,data属性为一个数组,每4个元素对应一个像素点(以rgba的形式保存每一个像素点的信息)。
所以我们就可以根据像素点的opcity值来判断这个像素点是不是透明,是不是等于0?
透明的像素点数量/总像素点数量 = 擦除比例
js代码:
document.addeventlistener("touchend",function(){ /* 获取imagedata对象*/ var imagedate = ctx.getimagedata(0,0,canvas.width,canvas.height); /* */ var allpx = imagedate.width * imagedate.height; var inum = 0;//记录刮开的像素点个数 for(var i=0;i<allpx;i++){ if(imagedate.data[i*4+3] == 0){ inum++; } } if(inum >= allpx*3/4){ // disappear里面写了缓慢清除的css3动画效果 canvas.setattribute('class','disappear'); } },false)
" .disappear " 的css样式,css3消失动画
.disappear{ -webkit-animation: disa 2s 1; animation: disa 2s 1; -webkit-animation-fill-mode: forwards; -moz-animation-fill-mode: forwards; -o-animation-fill-mode: forwards; animation-fill-mode: forwards; } @keyframes disa{ 0%{opacity:1;} 100%{opacity: 0;} }
相对比网上的其他一些实现方式,这种还是比较简单的一种,大家相互学习。有什么其他的办法可以留言相互学习
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
上一篇: 气候对王朝的兴衰有何影响?为何气候的变化会引发农民起义?
下一篇: 晒红薯干的方法有什么呢