Canvas 刮刮乐

2024-06-11 17:18
文章标签 canvas 刮乐

本文主要是介绍Canvas 刮刮乐,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

demo1手机端  demo2手机+PC
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=640,user-scalable=no,target-densitydpi=device-dpi" /><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-status-bar-style" content="black"/><meta name="format-detection" content="telephone=no"/><style>*{margin:0;padding:0;}body{max-width:640px;width:100%;margin:0 auto;height:100%;position:absolute;}.txt{width:100%;height:100%;max-width:640px;}.txt img{width:100%;max-width:640px;height:100%;}.can{position: absolute;top:0;left:0;width:100%;}#Mycanvas{opacity: 1;-webkit-transition: opacity .5s;-ms-transition: opacity .5s;-moz-transition: opacity .5s;}.Mycanvas{opacity:0!important;}</style></head><body><section class="bg"><div class="txt"><img src="images/2.jpg" alt="" /></div><div class="can"><canvas id="Mycanvas"></canvas></div></section></body><script>!(function(doc){var MyCanvas=doc.querySelector("#Mycanvas"),cont=MyCanvas.getContext("2d"),dataArr=[],a=false,stop=startx=starty=movex=movey=timer=null,disyance=30,hastouch = "ontouchstart" in window?true:false,tapstart=hastouch?"touchstart":"mousedown",tapmove=hastouch?"touchmove":"mousemove",tapend=hastouch?"touchend":"mouseup";MyCanvas.width=window.innerWidth;MyCanvas.height=853;/*** *兼容动画函数* @param  {Function} callback [description]* @return {[type]}            [description]*/// window.requestAnimFrame = (function(callback) {//     return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||//     function(callback) {//       window.setTimeout(callback, 1000 / 60);//     };//   })(); // var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;/*** *引入图片 转化成Canvas* @return {[type]} [description]*/function cvsToImg(){var img=new Image();img.src="images/1.jpg";// img.crossOrigin = "Anonymous";img.οnlοad=function(){cont.drawImage(img,0,0);//文章的核心 设置源和目标的重叠区域为透明cont.globalCompositeOperation="destination-out";}      }cvsToImg();  /*** *触摸事件绑定*/MyCanvas.addEventListener(tapstart,start,false);/*** *开始挂* @param  {[type]} event [description]* @return {[type]}       [description]*/function start(event){/**清楚像素值计算计时器**/clearTimeout(timer);var touch=hastouch?event.targetTouches[0]:null;//获取初始坐标startx=hastouch?touch.pageX-getPos(MyCanvas).x1:event.clientX-getPos(MyCanvas).x1;starty=hastouch?touch.pageY-getPos(MyCanvas).y1:event.clientY-getPos(MyCanvas).y1;/**事件绑定**/MyCanvas.addEventListener(tapmove,move,false);MyCanvas.addEventListener(tapend,end,false);event.preventDefault();}    function move(event){//清楚计算透明度计时器clearTimeout(timer);var touch=hastouch?event.targetTouches[0]:null;//移动的坐标movex=hastouch?touch.pageX-getPos(MyCanvas).x1:event.clientX-getPos(MyCanvas).x1;movey=hastouch?touch.pageY-getPos(MyCanvas).y1:event.clientY-getPos(MyCanvas).y1;cont.beginPath();cont.strokeStyle="rgba(255,255,255,1)";cont.lineWidth=60;cont.lineCap="round";  //设置线条两端为圆弧cont.lineJoin="round";cont.moveTo(startx,starty);cont.lineTo(movex,movey);cont.stroke();cont.closePath();//设置线条转折为圆弧startx=movex;starty=movey;event.preventDefault();}function end(event){timer=setTimeout(function(){var imgData=cont.getImageData(0,0,window.innerWidth,853);dataSize=imgData.data.length,count=0;for (var x =0; x<imgData.width; x+=disyance) {for (var y = 0; y < imgData.height; y+=disyance) {var i=(y*imgData.width+x)*4;if(imgData.data[i+3]==0)count++;};};if(count/(imgData.width*imgData.height/(disyance*disyance))>0.6&&!a){MyCanvas.className="Mycanvas";a=true;}},100)MyCanvas.removeEventListener(tapmove,move,false);event.preventDefault();}/*** *获取离文档的编剧* @param  {[type]} elm [description]* @return {[type]}     [description]*/function getPos(elm){var tops=elm.getBoundingClientRect().top+(document.body.scrollTop||document.documentElement.scrollTop), //获取上边距和左边距lefts=elm.getBoundingClientRect().left+(document.body.scrollLeft||document.documentElement.scrollLeft);return {"x1":lefts,"y1":tops};}/*** *随机生成中奖下标* @param  {[type]} num [description]* @return {[type]}     [description]*/// function randomInRange(num){//     var ranDom=Math.floor(Math.random()*num);//     console.log(ranDom);//     return txtArr[ranDom];// }/*** 计算颜色个数* @param  {[type]} child     [description]* @param  {[type]} parentArr [description]* @return {[type]}           [description]*/// function perCent(child,parentArr){//     var count=0;//     for (var i = 0; i < parentArr.length; i++) {//         if(parentArr[i]==child)count++;//     };//     return count;// }// function drwas(gloBal){//     cont.globalAlpha=gloBal/100;//       console.log(cont.globalAlpha);// } // function upData(){//     gloBa-=globalSpeed;//       if(gloBa<0){//         gloBa=0;//         cancelAnimationFrame(stop);//         console.log(gloBa);//         console.log(stop);//         }else{//         stop=requestAnimationFrame(upData);//         }//     // drwas(gloBa); //     MyCanvas.style.opacity=gloBa/100;     // }})(document)</script>
</html>


定义两个结构 一个底图,一个Canvas 

本文章的核心是讲 cont.globalCompositeOperation="destination-out"; 这个属性,目标与源的重叠是透明的 这样我们就思路出来了,把要掩盖的图片引入进Canvas里面,就是要擦掉的图片,在手机或者电脑上手指移动 的时候我们再画布目标上不断画一个源出来,这样不就是目标和源重叠了吗,重叠的地方透明了,被掩盖的底图就出来了。

hastouch = "ontouchstart" in window?true:false,
tapstart=hastouch?"touchstart":"mousedown",
tapmove=hastouch?"touchmove":"mousemove",
tapend=hastouch?"touchend":"mouseup";

首先我看实在移动端还是在PC端 

ontouchstart in window 来判断,后面三个start move end 就可以决定是用touch 还是mouse ;

cont.drawImage(img,0,0);

引入要被擦得图片进去Canvas  

接着start事件包含move和end连个事件 开始进行绘制 end事件触发的时候记得解绑move以免重复绑定。

if(count/(imgData.width*imgData.height/(disyance*disyance))>0.6&&!a){MyCanvas.className="Mycanvas";a=true;}
关于这个0.6是什么,就是当你绘制的图形大于整个画布部分的60%; 然后canvas就自动消失,显示底部,一般我们刮刮乐的时候,不会全部挂完就显示出来,就是这个效果。


                     timer=setTimeout(function(){var imgData=cont.getImageData(0,0,window.innerWidth,853);dataSize=imgData.data.length,count=0;for (var x =0; x<imgData.width; x+=disyance) {for (var y = 0; y < imgData.height; y+=disyance) {var i=(y*imgData.width+x)*4;if(imgData.data[i+3]==0)count++;};};if(count/(imgData.width*imgData.height/(disyance*disyance))>0.6&&!a){MyCanvas.className="Mycanvas";a=true;}},100
手指一离开的时候,利用getImageData()方法返回的data属性来获取整个画布的像素值rgba 四个点的值,但是一个画布很大,我们不可能每个点都去采集获取,那样性能就很低了,会很卡,利用采样的方法进行

disyance=30
这个30代表了我没30*30像素我取一个像素点来获取rgba中的a值,既然cont.globalCompositeOperation="destination-out"; 那透明每个像素点的a值都是0 取每30*30像素的第一个像素中的a,(小图的话 采样的宽和高可以小一点),如果的等于a==0 我的计数器count++;count必须定义在end方法里面。每次都要清空不能定义全局对象.

count/(imgData.width*imgData.height/(disyance*disyance))>0.6

技术除以采样范围就可以得到百分比了,这样我们不要全部擦完就可以得到底图。

最后说一下

setTimeout
我再end里面定义了一个定时器,意思就是离开之后不马上计算,隔一会儿,但是更重要的原因就是性能,离开之后又触发start事件 我就清楚这个计算进程,不占用浏览器的计算线程,这样就不会重复绘制计算像素比例了.

这篇关于Canvas 刮刮乐的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1051797

相关文章

影响画布微信小程序canvas及skyline和webview用户界面布局的关键流程

影响微信小程序画布canvas及skyline和webview用户界面布局的关键流程 目录 影响微信小程序画布canvas及skyline和webview用户界面布局的关键流程 一、微信小程序canvas开发流程 1.1、官方指南 1.2、客制化开发 第一步:在 WXML 中添加 canvas 组件 第二步:获取 Canvas 对象和渲染上下文 第三步 画布#ID选择器执行回调——

Android canvas save restore saveLayer的异同点

一、基础操作 drawText、drawRect、drawColor等 对于这些基础操作,相信每一个安卓开发者都能说上个一二点出来,这些就不多做介绍,api 工程师必备技能之一。 在进阶之前,先回答这个问题:    问:canvas既然大家都理解为画布,那如果先在画布上绘制了某些内容,然后再canvas.rotate旋转了画布,为什么这些已经绘制在画布上的内容不会跟随着旋转?    答:由此可

自定义View-Canvas

转载自:https://www.jianshu.com/p/f69873371763 Android Canvas 方法总结 简介 在自定义 View的时候,我们经常需要绘制一些自己想要的效果。 这里就需要使用Canvas对象。 下面将Canvas对象常用方法做个笔记,方便记忆。 对Canvas进行操作 对Canvas的一系列操作,是指对Canvas进行旋转、平移、缩放等操作。 这些操作可以

canvas-实现放大镜效果

canvas-实现放大镜效果 目录 文章目录 前言推荐阅读代码展示结果展示 前言 本文为canvas实现放大镜逻辑简单,适合作为基础项目练手 推荐阅读 《H5 canvas核心技术》 代码展示 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Comp

canvas-原生js实现时钟绘图效果

canvas-原生js实现时钟绘图效果 目录 文章目录 前言代码效果查看 前言 本文为canvas实现时钟效果可直接复制使用 代码 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta n

js-基于AudioContext在canvas上显示声音波形

js-基于AudioContext在canvas上显示声音波形 目录 文章目录 前言效果展示代码展示`index.html``Aud.js` 前言 从ES7后开始启用AudioContex常用API是:createScriptProcessor, onaudioprocess, getChannelData注意:onaudioprocess已经废弃,开始改用Analyse

【Canvas与纹饰】环形小蜜蜂纹饰

【成图】 【代码】 <!DOCTYPE html><html lang="utf-8"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><head><title>环形小蜜蜂纹饰</title><style type="text/css">.centerlize{margin:0 auto;

Web前端 lucky-canvas【大转盘 九宫格 老虎机】抽奖插件(适用JS/TS、Vue、React、微信小程序、Uniapp和Taro)

Web前端 lucky-canvas 抽奖插件(JS/TS、Vue、React、微信小程序、Uniapp和Taro) 基于 JS + Canvas 实现的【大转盘 & 九宫格 & 老虎机】抽奖,致力于为 WEB 前端提供一个功能强大且专业可靠的营销组件,只需要通过简单配置即可实现自由化定制,帮助你快速的完成产品需求 自由配置 奖品 / 文字 / 图片 / 颜色 / 按钮均可自由配置;支持同步

Canvas加动画,实现火柴人跳绳效果

效果 涉及到的知识 1、canvas 2、path和二阶贝塞尔曲线 3、bitmap绘制 canvas 先引用google官方: The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas t

html5学习canvas实例之时钟

<html><head><title>html5-01</title><meta http-equiv="content-type" content="text/html" charset="utf-8"><script language="javascript">window.οnlοad=function (){var canvas=document.getElementById("canva