图吉美食
您的当前位置:首页canvas模拟实现电子彩票刮刮乐的代码

canvas模拟实现电子彩票刮刮乐的代码

来源:图吉美食
 今天给大家带来一个刮刮乐的小例子~基于HTML5 canvas的,非常具有使用价值,有兴趣的可以了解一下。

今天给大家带来一个刮刮乐的小例子~基于HTML5 canvas的,有兴趣的可以改成Android版本的,或者其他的~

效果图:

贴一张我中500w的照片,咋办啊,怎么花呢~

好了,下面开始原理:

1、刮奖区域两个Canvas,一个是front , 一个back ,front遮盖住下面的canvas。

2、canvas默认填充了一个矩形,将下面canvas效果图遮盖,然后监听mouse事件,根据mousemove的x,y坐标,进行擦出front canvas上的矩形区域,然后显示出下面的canvas的效果图。

很简单把~嘿嘿~

1、HTML文件内容:

<!DOCTYPE html> 
<html> 
<head> 
 <title></title> 
 <meta charset="utf-8"> 
 
 <script type="text/javascript" src="../../jquery-1.8.3.js"></script> 
 <script type="text/javascript" src="canvas2d.js"></script> 
 
 <script type="text/javascript" src="GuaGuaLe2.js"></script> 
 
 <script type="text/javascript"> 
 
 $(function () 
 { 
 var guaguale = new GuaGuaLe("front", "back"); 
 guaguale.init({msg: "¥5000000.00"}); 
 }); 
 </script> 
 <style type="text/css"> 
 
 
 body 
 { 
 background: url("s_bd.jpg") repeat 0 0; 
 } 
 
 .container 
 { 
 position: relative; 
 width: 400px; 
 height: 160px; 
 margin: 100px auto 0; 
 background: url(s_title.png) no-repeat 0 0; 
 background-size: 100% 100%; 
 } 
 
 #front, #back 
 { 
 position: absolute; 
 width: 200px; 
 left: 50%; 
 top: 100%; 
 margin-left: -130px; 
 height: 80px; 
 border-radius: 5px; 
 border: 1px solid #444; 
 } 
 
 </style> 
 
</head> 
<body> 
 
<p class="container"> 
 <canvas id="back" width="200" height="80"></canvas> 
 <canvas id="front" width="200" height="80"></canvas> 
</p> 
 
 
</body> 
</html>

2、首先我利用了一个以前写的canvas辅助类,留下来今天要用的一些方法:

/** 
 * Created with JetBrains WebStorm. 
 * User: zhy 
 * Date: 13-12-17 
 * Time: 下午9:42 
 * To change this template use File | Settings | File Templates. 
 */ 
 
function Canvas2D($canvas) 
{ 
 var context = $canvas[0].getContext("2d"), 
 width = $canvas[0].width, 
 height = $canvas[0].height, 
 pageOffset = $canvas.offset(); 
 
 
 context.font = "24px Verdana, Geneva, sans-serif"; 
 context.textBaseline = "top"; 
 
 
 /** 
 * 绘制矩形 
 * @param start 
 * @param end 
 * @param isFill 
 */ 
 this.drawRect = function (start, end, isFill) 
 { 
 var w = end.x - start.x , h = end.y - start.y; 
 if (isFill) 
 { 
 context.fillRect(start.x, start.y, w, h); 
 } 
 else 
 { 
 context.strokeRect(start.x, start.y, w, h); 
 } 
 }; 
 
 /** 
 * 根据书写的文本,得到该文本在canvas上书写的中心位置的左上角坐标 
 * @param text 
 * @returns {{x: number, y: number}} 
 */ 
 this.caculateTextCenterPos = function (text) 
 { 
 var metrics = context.measureText(text); 
 console.log(metrics); 
// context.font = fontSize + "px Verdana, Geneva, sans-serif"; 
 var textWidth = metrics.width; 
 var textHeight = parseInt(context.font); 
 
 return { 
 x: width / 2 - textWidth / 2, 
 y: height / 2 - textHeight / 2 
 }; 
 } 
 this.width = function () 
 { 
 return width; 
 } 
 this.height = function () 
 { 
 return height; 
 } 
 this.resetOffset = function () 
 { 
 pageOffset = $canvas.offset(); 
 } 
 /** 
 * 当屏幕大小发生变化,重新计算offset 
 */ 
 $(window).resize(function () 
 { 
 pageOffset = $canvas.offset(); 
 }); 
 
 /** 
 * 将页面上的左边转化为canvas中的坐标 
 * @param pageX 
 * @param pageY 
 * @returns {{x: number, y: number}} 
 */ 
 this.getCanvasPoint = function (pageX, pageY) 
 { 
 return{ 
 x: pageX - pageOffset.left, 
 y: pageY - pageOffset.top 
 } 
 } 
 /** 
 * 清除区域,此用户鼠标擦出刮奖涂层 
 * @param start 
 * @returns {*} 
 */ 
 this.clearRect = function (start) 
 { 
 context.clearRect(start.x, start.y, 10, 10); 
 return this; 
 }; 
 
 /** 
 *将文本绘制到canvas的中间 
 * @param text 
 * @param fill 
 */ 
 this.drawTextInCenter = function (text, fill) 
 { 
 var point = this.caculateTextCenterPos(text); 
 if (fill) 
 { 
 context.fillText(text, point.x, point.y); 
 } 
 else 
 { 
 context.strokeText(text, point.x, point.y); 
 } 
 }; 
 /** 
 * 设置画笔宽度 
 * @param newWidth 
 * @returns {*} 
 */ 
 this.penWidth = function (newWidth) 
 { 
 if (arguments.length) 
 { 
 context.lineWidth = newWidth; 
 return this; 
 } 
 return context.lineWidth; 
 }; 
 
 /** 
 * 设置画笔颜色 
 * @param newColor 
 * @returns {*} 
 */ 
 this.penColor = function (newColor) 
 { 
 if (arguments.length) 
 { 
 context.strokeStyle = newColor; 
 context.fillStyle = newColor; 
 return this; 
 } 
 
 return context.strokeStyle; 
 }; 
 
 /** 
 * 设置字体大小 
 * @param fontSize 
 * @returns {*} 
 */ 
 this.fontSize = function (fontSize) 
 { 
 if (arguments.length) 
 { 
 context.font = fontSize + "px Verdana, Geneva, sans-serif"; 
 
 return this; 
 } 
 
 return context.fontSize; 
 } 
 
 
}

这个类也就对Canvas对象进行了简单的封装,设置参数,绘制图形什么的,比较简单,大家可以完善下这个类~

3、GuaGuaLe.js

/** 
 * Created with JetBrains WebStorm. 
 * User: zhy 
 * Date: 14-6-24 
 * Time: 上午11:36 
 * To change this template use File | Settings | File Templates. 
 */ 
function GuaGuaLe(idFront, idBack) 
{ 
 this.$eleBack = $("#" + idBack); 
 this.$eleFront = $("#" + idFront); 
 this.frontCanvas = new Canvas2D(this.$eleFront); 
 this.backCanvas = new Canvas2D(this.$eleBack); 
 
 this.isStart = false; 
 
} 
 
GuaGuaLe.prototype = { 
 constructor: GuaGuaLe, 
 /** 
 * 将用户的传入的参数和默认参数做合并 
 * @param desAttr 
 * @returns {{frontFillColor: string, backFillColor: string, backFontColor: string, backFontSize: number, msg: string}} 
 */ 
 mergeAttr: function (desAttr) 
 { 
 var defaultAttr = { 
 frontFillColor: "silver", 
 backFillColor: "gold", 
 backFontColor: "red", 
 backFontSize: 24, 
 msg: "谢谢惠顾" 
 }; 
 for (var p in desAttr) 
 { 
 defaultAttr[p] = desAttr[p]; 
 } 
 
 return defaultAttr; 
 
 }, 
 
 
 init: function (desAttr) 
 { 
 
 var attr = this.mergeAttr(desAttr); 
 
 //初始化canvas 
 this.backCanvas.penColor(attr.backFillColor); 
 this.backCanvas.fontSize(attr.backFontSize); 
 this.backCanvas.drawRect({x: 0, y: 0}, {x: this.backCanvas.width(), y: this.backCanvas.height()}, true); 
 this.backCanvas.penColor(attr.backFontColor); 
 this.backCanvas.drawTextInCenter(attr.msg, true); 
 //初始化canvas 
 this.frontCanvas.penColor(attr.frontFillColor); 
 this.frontCanvas.drawRect({x: 0, y: 0}, {x: this.frontCanvas.width(), y: this.frontCanvas.height()}, true); 
 
 var _this = this; 
 //设置事件 
 this.$eleFront.mousedown(function (event) 
 { 
 _this.mouseDown(event); 
 }).mousemove(function (event) 
 { 
 _this.mouseMove(event); 
 }).mouseup(function (event) 
 { 
 _this.mouseUp(event); 
 }); 
 }, 
 mouseDown: function (event) 
 { 
 this.isStart = true; 
 this.startPoint = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY); 
 }, 
 mouseMove: function (event) 
 { 
 if (!this.isStart)return; 
 var p = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY); 
 this.frontCanvas.clearRect(p); 
 }, 
 mouseUp: function (event) 
 { 
 this.isStart = false; 
 } 
};

通过用户传入的两个canvas的id,然后生成一个对象,进行初始化操作,设置事件。当然了也提供用户设置可选的参数,各种颜色,已经刮开后显示的信息等,通过

{
 frontFillColor: "silver",
 backFillColor: "gold",
 backFontColor: "red",
 backFontSize: 24,
 msg: "谢谢惠顾"
 };

传给init方法进行设置。

好了,然后就基本完工了,测试一下:

基本实现了刮开图层,但是存在一个小问题,就是当用户滑动特别快时,会出现一些断点,当然也可以忽略,不过我们准备提供一下解决方案:

产生原因:由于鼠标移动速度过快,产生的断点;解决方案:将mousemove中两次的鼠标左边,进行拆分成多个断点坐标:

如上图,把两点之间进行连线,根据斜率,然后分成多个小段,分别获得线段上的坐标(有四种可能,有兴趣可以画画图,计算下,代码如下):

var k; 
 if (p.x > this.startPoint.x) 
 { 
 k = (p.y - this.startPoint.y) / (p.x - this.startPoint.x); 
 for (var i = this.startPoint.x; i < p.x; i += 5) 
 { 
 this.frontCanvas.clearRect({x: i, y: (this.startPoint.y + (i - this.startPoint.x) * k)}); 
 } 
 } else 
 { 
 k = (p.y - this.startPoint.y) / (p.x - this.startPoint.x); 
 for (var i = this.startPoint.x; i > p.x; i -= 5) 
 { 
 this.frontCanvas.clearRect({x: i, y: (this.startPoint.y + ( i - this.startPoint.x ) * k)}); 
 } 
 } 
 this.startPoint = p;

4、最后贴一下完整的GuaGuaLe.js

/** 
 * Created with JetBrains WebStorm. 
 * User: zhy 
 * Date: 14-6-24 
 * Time: 上午11:36 
 * To change this template use File | Settings | File Templates. 
 */ 
function GuaGuaLe(idFront, idBack) 
{ 
 this.$eleBack = $("#" + idBack); 
 this.$eleFront = $("#" + idFront); 
 this.frontCanvas = new Canvas2D(this.$eleFront); 
 this.backCanvas = new Canvas2D(this.$eleBack); 
 
 this.isStart = false; 
 
} 
 
GuaGuaLe.prototype = { 
 constructor: GuaGuaLe, 
 /** 
 * 将用户的传入的参数和默认参数做合并 
 * @param desAttr 
 * @returns {{frontFillColor: string, backFillColor: string, backFontColor: string, backFontSize: number, msg: string}} 
 */ 
 mergeAttr: function (desAttr) 
 { 
 var defaultAttr = { 
 frontFillColor: "silver", 
 backFillColor: "gold", 
 backFontColor: "red", 
 backFontSize: 24, 
 msg: "谢谢惠顾" 
 }; 
 for (var p in desAttr) 
 { 
 defaultAttr[p] = desAttr[p]; 
 } 
 
 return defaultAttr; 
 
 }, 
 
 
 init: function (desAttr) 
 { 
 
 var attr = this.mergeAttr(desAttr); 
 
 //初始化canvas 
 this.backCanvas.penColor(attr.backFillColor); 
 this.backCanvas.fontSize(attr.backFontSize); 
 this.backCanvas.drawRect({x: 0, y: 0}, {x: this.backCanvas.width(), y: this.backCanvas.height()}, true); 
 this.backCanvas.penColor(attr.backFontColor); 
 this.backCanvas.drawTextInCenter(attr.msg, true); 
 //初始化canvas 
 this.frontCanvas.penColor(attr.frontFillColor); 
 this.frontCanvas.drawRect({x: 0, y: 0}, {x: this.frontCanvas.width(), y: this.frontCanvas.height()}, true); 
 
 var _this = this; 
 //设置事件 
 this.$eleFront.mousedown(function (event) 
 { 
 _this.mouseDown(event); 
 }).mousemove(function (event) 
 { 
 _this.mouseMove(event); 
 }).mouseup(function (event) 
 { 
 _this.mouseUp(event); 
 }); 
 }, 
 mouseDown: function (event) 
 { 
 this.isStart = true; 
 this.startPoint = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY); 
 }, 
 mouseMove: function (event) 
 { 
 if (!this.isStart)return; 
 var p = this.frontCanvas.getCanvasPoint(event.pageX, event.pageY); 
 this.frontCanvas.clearRect(p); 
 }, 
 mouseUp: function (event) 
 { 
 this.isStart = false; 
 } 
};
显示全文