标签:
下班后,闲着无事,刚好近期在学习画布相关知识,就写了个demo练一下手。高手路过,多多指点!
简单介绍一下页面整体结构:
1 <div class="wrap"> 2 <canvas class="page can" id="can" width="640" height="1136"></canvas> 3 <div class="page index"><img src="images/1.jpg" /></div> 4 </div>
样式:
1 html,body { margin: 0; height: 100%; } 2 .wrap { width: 640px; height: 100%; margin: 0 auto; position: relative; overflow: hidden; } 3 .page { width: 100%; height: 100%; position: absolute; top: 0; left: 0;} 4 .can { z-index: 3; } 5 .index img { width: 100%; height: 100%; }
引用JS:
<script src="js/jquery-2.1.3.min.js"></script>
<script src="js/scratch.js"></script>
下面, 详细介绍一下关于scratch.js的具体实现思路与方法:
通过JS闭包引用:
;(function($){
//主体代码
//...
})(jQuery);
首页,定义默认参数:
1 //默认参数 2 var defaults = { 3 lineWidth: 50, //笔触宽度 4 percent: ‘0.6‘, //刮开范围 5 slideImg: ‘images/2.jpg‘, //封面图 6 callback: function(){ //刮开后回调函数 7 alert(‘你太棒了,么么哒!‘) 8 } 9 };
核心逻辑:
说明:刮刮卡效果是借助canvas自身的属性来编写的,所以需要先获取页面中canvas对象,并创建2d绘图环境。
var can = ths.get(0).getContext(‘2d‘);
然后,创建image对象,img加载成功后,调用canvas的drawImage方法,绘制封面图,并设置绘制的属性,注意下文标部分代码:
1 var img = new Image(); 2 img.src = slideImg; 3 img.onload = function(){ 4 can.drawImage(img, (640-wid)/2, 0, wid, hei); 5 can.strokeStyle = ‘gray‘; 6 can.lineWidth = lineWidth; 7 can.lineCap = ‘round‘; 8 can.globalCompositeOperation = ‘destination-out‘; 9 //绘制完成,调用刮卡事件 10 slide(ths, can); 11 } 12
下面是slide方法,主要判断手势与绘制路径。当touchend时,计算划开像素点,目标设置为刮开60%时,封面图自动消失。注意下面标注部分代码:
1 function slide(o,c){ 2 o.on(‘touchstart‘, function(e){ 3 var e = e||e.event; 4 var tou = e.originalEvent.changedTouches[0]; 5 var x = tou.pageX - $(this).offset().left; 6 var y = tou.pageY - $(this).offset().top; 7 8 if(flag){ 9 flag = false; 10 c.moveTo(x, y); 11 c.lineTo(x+1, y+1); 12 }else{ 13 c.lineTo(x+1, y+1); 14 } 15 c.stroke(); 16 17 o.on(‘touchmove.mo‘, function(e){ 18 var e = e||e.event; 19 var tou = e.originalEvent.changedTouches[0]; 20 var x = tou.pageX - $(this).offset().left; 21 var y = tou.pageY - $(this).offset().top; 22 23 c.lineTo(x+1, y+1); 24 c.stroke(); 25 }) 26 27 o.on(‘touchend.mo‘, function(e){ 28 var imgData = c.getImageData(0, 0, 640, hei); 29 var aPx = imgData.width * imgData.height; 30 var num = 0; 31 for(var i=0; i<aPx; i++){ 32 if(imgData.data[4*i+3] == 0){ 33 num++; 34 } 35 } 36 37 if(num>aPx*percent){ 38 o.animate({opacity: 0}, 1000, function(){ 39 $(this).remove(); 40 41 callback(); 42 }) 43 } 44 45 o.off(‘.mo‘); 46 }) 47 48 }) 49 50 }
至此,核心部分基本描述完了,本人讲解能力不行,如有问题还请见谅!
最后,附上scratch.js源码:
1 /* 2 * @ Name: 刮刮卡-h5 3 * @ Author: 繁花落尽 4 * @ Time: 2015/9/06 5 * @ Email: 863139978@qq.com 6 7 基础方法: 8 $(‘#can‘).scratch(); //$(‘#can‘)为当前can对象 9 10 自定义调用: 11 $(‘#can‘).scratch({ 12 lineWidth: 50, //笔触宽度 13 percent: ‘0.6‘, //刮开范围 14 slideImg: ‘images/2.jpg‘, //封面图 15 callback: function(){} //刮开后回调 16 }); 17 */ 18 19 ;(function($){ 20 //默认参数 21 var defaults = { 22 lineWidth: 50, 23 percent: ‘0.6‘, 24 slideImg: ‘images/2.jpg‘, 25 callback: function(){ 26 alert(‘你太棒了,么么哒!‘) 27 } 28 }; 29 30 $.fn.extend({ 31 "scratch": function (options) { 32 var opts = $.extend({}, defaults, options); //使用jQuery.extend 覆盖插件默认参数 33 var lineWidth = opts.lineWidth || 50; 34 var percent = opts.percent || 0.8; 35 var slideImg = opts.slideImg || ‘http://peugeot.guoxinad.com.cn/pg_compete/images/bg2.jpg‘; 36 var callback = opts.callback || {}; 37 var flag = true; 38 39 $(document).on(‘touchmove‘,function(e){ 40 var e = e||window.event; 41 e.preventDefault(); 42 }); 43 44 return this.each(function(){ 45 var ths = $(this); 46 var hei = $(window).height(); 47 var wid = getWid(); 48 49 $(‘.wrap‘).height(hei); 50 51 var can = ths.get(0).getContext(‘2d‘); 52 ths.height(hei); 53 54 var img = new Image(); 55 img.src = slideImg; 56 img.onload = function(){ 57 can.drawImage(img, (640-wid)/2, 0, wid, hei); 58 can.strokeStyle = ‘gray‘; 59 can.lineWidth = lineWidth; 60 can.lineCap = ‘round‘; 61 can.globalCompositeOperation = ‘destination-out‘; 62 //绘制完成,调用刮卡事件 63 slide(ths, can); 64 } 65 66 67 68 function slide(o,c){ 69 o.on(‘touchstart‘, function(e){ 70 var e = e||e.event; 71 var tou = e.originalEvent.changedTouches[0]; 72 var x = tou.pageX - $(this).offset().left; 73 var y = tou.pageY - $(this).offset().top; 74 75 if(flag){ 76 flag = false; 77 c.moveTo(x, y); 78 c.lineTo(x+1, y+1); 79 }else{ 80 c.lineTo(x+1, y+1); 81 } 82 c.stroke(); 83 84 o.on(‘touchmove.mo‘, function(e){ 85 var e = e||e.event; 86 var tou = e.originalEvent.changedTouches[0]; 87 var x = tou.pageX - $(this).offset().left; 88 var y = tou.pageY - $(this).offset().top; 89 90 c.lineTo(x+1, y+1); 91 c.stroke(); 92 }) 93 94 o.on(‘touchend.mo‘, function(e){ 95 var imgData = c.getImageData(0, 0, 640, hei); 96 var aPx = imgData.width * imgData.height; 97 var num = 0; 98 for(var i=0; i<aPx; i++){ 99 if(imgData.data[4*i+3] == 0){ 100 num++; 101 } 102 } 103 104 if(num>aPx*percent){ 105 o.animate({opacity: 0}, 1000, function(){ 106 $(this).remove(); 107 108 callback(); 109 }) 110 } 111 112 o.off(‘.mo‘); 113 }) 114 115 }) 116 117 } 118 119 120 function getWid(){ 121 var w = 640*hei/960; 122 w = w>640?w: 640; 123 return w; 124 } 125 126 }) 127 128 } 129 }); 130 })(jQuery);
标签:
原文地址:http://www.cnblogs.com/front-end/p/4787108.html