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文件内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <!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辅助类,留下来今天要用的一些方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | /** * 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | /** * 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,然后生成一个对象,进行初始化操作,设置事件。当然了也提供用户设置可选的参数,各种颜色,已经刮开后显示的信息等,通过
1 2 3 4 5 6 7 | { frontFillColor: "silver" , backFillColor: "gold" , backFontColor: "red" , backFontSize: 24, msg: "谢谢惠顾" }; |
传给init方法进行设置。
好了,然后就基本完工了,测试一下:
基本实现了刮开图层,但是存在一个小问题,就是当用户滑动特别快时,会出现一些断点,当然也可以忽略,不过我们准备提供一下解决方案:
产生原因:由于鼠标移动速度过快,产生的断点;解决方案:将mousemove中两次的鼠标左边,进行拆分成多个断点坐标:
如上图,把两点之间进行连线,根据斜率,然后分成多个小段,分别获得线段上的坐标(有四种可能,有兴趣可以画画图,计算下,代码如下):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | /** * 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 ; } }; |
源码点击下载:demo
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
html5 canvas实现的可用于手机端手指滑动刮刮乐效果源码
这是一款基于html5 canvas实现的可用于手机端手指滑动刮刮乐效果源码。通过按下鼠标左键并拖动即可实现刮刮卡效果的刮去表面遮罩层,同时显示底部女神图片的功能。该源码还2016-07-20- 这篇文章主要介绍了Html5 Canvas 实现一个“刮刮乐”游戏,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2019-09-05
最新评论