HTML5+CSS3实例 :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> <div class="container"> <canvas id="back" width="200" height="80"></canvas> <canvas id="front" width="200" height="80"></canvas> </div> </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; } };
源码点击下载:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: 成功互联网运营营销五部曲