移动端刮刮乐的实现方式(js+HTML5)


Posted in Javascript onMarch 23, 2017

程序员有一种惯性思维,就是看见一些会动的东西(带点科技含量的,猫啊,狗啊就算了),总要先想一遍,这玩意用代码是怎么控制的。比如电梯,路边的霓虹灯,遥控器,小孩子的玩具等,都统统被程序员“意淫”过。

有时候还会感觉程序员看世界会看的透彻一点.............

想必大家都玩过刮刮乐,下面就介绍一种刮刮乐的移动端实现方式!用到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里面存储的是像素点信息

移动端刮刮乐的实现方式(js+HTML5)

我们再打印data,data属性为一个数组,每4个元素对应一个像素点(以rgba的形式保存每一个像素点的信息)。

移动端刮刮乐的实现方式(js+HTML5)

所以我们就可以根据像素点的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;}
}

相对比网上的其他一些实现方式,这种还是比较简单的一种,大家相互学习。有什么其他的办法可以留言相互学习

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
Javascript 学习书 推荐
Jun 13 Javascript
jquery 插件开发方法小结
Oct 23 Javascript
一个js控制的导航菜单实例代码
Dec 03 Javascript
JS将数字转换成三位逗号分隔的样式(示例代码)
Feb 19 Javascript
javascript 实现map集合
Apr 03 Javascript
AngularJS ng-bind 指令简单实现
Jul 30 Javascript
微信小程序 参数传递详解
Oct 24 Javascript
轻松学习Javascript闭包
Mar 01 Javascript
微信小程序商品详情页规格属性选择示例代码
Oct 30 Javascript
JS匿名函数和匿名自执行函数概念与用法分析
Mar 16 Javascript
echarts饼图各个板块之间的空隙如何实现
Dec 01 Javascript
JS实现页面侧边栏效果探究
Jan 08 Javascript
BootStrap+Mybatis框架下实现表单提交数据重复验证
Mar 23 #Javascript
jquery实现全选、全不选以及单选功能
Mar 23 #jQuery
jQuery插件FusionCharts实现的MSBar3D图效果示例【附demo源码】
Mar 23 #jQuery
纯jQuery实现前端分页功能
Mar 23 #jQuery
vue双向绑定简要分析
Mar 23 #Javascript
Javascript面试经典套路reduce函数查重
Mar 23 #Javascript
JQuery 进入页面默认给已赋值的复选框打钩
Mar 23 #jQuery
You might like
PHP设计聊天室步步通
2006/10/09 PHP
php生成图片验证码
2015/06/09 PHP
php 判断页面或图片是否经过gzip压缩的方法
2017/04/05 PHP
VBScript版代码高亮
2006/06/26 Javascript
JavaScript 特殊字符
2007/04/05 Javascript
jqeury eval将字符串转换json的方法
2011/01/20 Javascript
javascript中AJAX用法实例分析
2015/01/30 Javascript
javascript适合移动端的日期时间拾取器
2015/11/10 Javascript
jQuery插件imgPreviewQs实现上传图片预览
2016/01/15 Javascript
使用jQuery给input标签设置默认值
2016/06/20 Javascript
jquery siblings获取同辈元素用法实例分析
2016/07/25 Javascript
JavaScript中绑定事件的三种方式及去除绑定
2016/11/05 Javascript
使用JavaScript实现alert的实例代码
2017/07/06 Javascript
jQuery实现的粘性滚动导航栏效果实例【附源码下载】
2017/10/19 jQuery
JS动画定时器知识总结
2018/03/23 Javascript
VUE2.0+ElementUI2.0表格el-table实现表头扩展el-tooltip
2018/11/30 Javascript
jQuery实现侧边栏隐藏与显示的方法详解
2018/12/22 jQuery
解决Layui中templet中a的onclick参数传递的问题
2019/09/20 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
2020/05/30 jQuery
Python2.x和3.x下maketrans与translate函数使用上的不同
2015/04/13 Python
简单的Apache+FastCGI+Django配置指南
2015/07/22 Python
使用 Python 实现微信群友统计器的思路详解
2018/09/26 Python
Pandas读取并修改excel的示例代码
2019/02/17 Python
在django中使用apscheduler 执行计划任务的实现方法
2020/02/11 Python
CSS3中线性颜色渐变的一些实现方法
2015/07/14 HTML / CSS
马来西亚银饰品牌:JEOEL
2017/12/15 全球购物
Myprotein比利时官方网站:欧洲第一运动营养品牌
2020/10/04 全球购物
nohup的用法
2012/11/26 面试题
保安员岗位职责
2013/11/17 职场文书
2013年学期结束动员演讲稿
2014/01/07 职场文书
《小猫刮胡子》教学反思
2014/02/21 职场文书
材料物理专业求职信
2014/09/01 职场文书
2014年保育员工作总结
2014/12/02 职场文书
给老婆的道歉信
2015/01/20 职场文书
论文答辩开场白大全
2015/05/27 职场文书
八年级作文之友情
2019/11/25 职场文书