移动端刮刮乐的实现方式(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 相关文章推荐
Jquery之Ajax运用 学习运用篇
Sep 26 Javascript
jQuery中$.get、$.post、$.getJSON和$.ajax的用法详解
Nov 19 Javascript
DOM基础教程之事件类型
Jan 20 Javascript
javascript制作sql转换为stringBuffer的小工具
Apr 03 Javascript
jQuery实现的分子运动小球碰撞效果
Jan 27 Javascript
JavaScript 对象字面量讲解
Jun 06 Javascript
运用js教你轻松制作html音乐播放器
Apr 17 Javascript
jQuery实现动态删除LI的方法
May 30 jQuery
JS中Swiper的使用和轮播图效果
Aug 11 Javascript
Vue实战教程之仿肯德基宅急送App
Jul 19 Javascript
vue-i18n实现中英文切换的方法
Jul 06 Javascript
Element图表初始大小及窗口自适应实现
Jul 10 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小技巧 把数组的键和值交换形成了新的数组,查找值取得键
2011/06/02 PHP
解析php中获取url与物理路径的总结
2013/06/21 PHP
浅谈PHP正则表达式中修饰符/i, /is, /s, /isU
2014/10/21 PHP
PHP中通过getopt解析GNU C风格命令行选项
2019/11/18 PHP
PHP unset函数原理及使用方法解析
2020/08/14 PHP
jquery 图片预加载 自动等比例缩放插件
2008/12/25 Javascript
jQuery 插件 将this下的div轮番显示
2009/04/09 Javascript
IE与FireFox中的childNodes区别
2011/10/20 Javascript
浅析JavaScript中的CSS属性及命名规范
2013/11/28 Javascript
聊一聊jQuery插件uploadify使用方法
2016/08/24 Javascript
ThinkPHP+jquery实现“加载更多”功能代码
2017/03/11 Javascript
微信小程序中form 表单提交和取值实例详解
2017/04/20 Javascript
分享19个JavaScript 有用的简写写法
2017/07/07 Javascript
Vue.js中extend选项和delimiters选项的比较
2017/07/17 Javascript
JavaScript实现重力下落与弹性效果的方法分析
2017/12/20 Javascript
使用express搭建一个简单的查询服务器的方法
2018/02/09 Javascript
React 组件渲染和更新的实现代码示例
2019/02/21 Javascript
非常漂亮的js烟花效果
2020/03/10 Javascript
详解vue v-model
2020/08/31 Javascript
vue 递归组件的简单使用示例
2021/01/14 Vue.js
python 通过xml获取测试节点和属性的实例
2018/03/31 Python
Pycharm 操作Django Model的简单运用方法
2018/05/23 Python
解决python "No module named pip" 的问题
2018/10/13 Python
python图形绘制奥运五环实例讲解
2019/09/14 Python
Python函数式编程指南:对生成器全面讲解
2019/11/19 Python
Pytorch模型转onnx模型实例
2020/01/15 Python
土耳其时尚购物网站:Morhipo
2017/09/04 全球购物
店长岗位的工作内容
2013/11/12 职场文书
工程总经理工作职责
2013/12/09 职场文书
纪念建党演讲稿范文
2014/01/13 职场文书
学生检讨书如何写
2014/10/30 职场文书
求职简历自我评价怎么写
2015/03/10 职场文书
防汛通知
2015/04/25 职场文书
2015年教师师德师风承诺书
2015/04/28 职场文书
《狼王梦》读后感:可怜天下父母心
2019/11/01 职场文书
Python+Selenium实现抖音、快手、B站、小红书、微视、百度好看视频、西瓜视频、微信视频号、搜狐视频、一点号、大风号、趣头条等短视频自动发布
2022/04/13 Python