HTML5 CSS3 诱人的实例 :canvas 模拟实现电子彩票刮刮乐
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/34089553
今天给大家带来一个刮刮乐的小例子~基于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;
}
};
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/34089553
好了,收工吃饭~
版权声明:本文为博主原创文章,未经博主允许不得转载。
HTML5 CSS3 诱人的实例 :canvas 模拟实现电子彩票刮刮乐的更多相关文章
- HTML5 CSS3 诱人的实例 :模仿优酷视频截图功能
一般的视频网站对于用户上传的视频,在用户上传完成后,可以对播放的视频进行截图,然后作为视频的展示图.项目中也可以引入这样的功能给用户一种不错的体验,而不是让用户额外上传一张展示图. 效果图: 看起来还 ...
- HTML5 CSS3 诱人的实例 : 网页载入进度条的实现,下载进度条等
今天给大家带来一个比較炫的进度条,进度条在一耗时操作上给用户一个比較好的体验,不会让用户认为在盲目等待,对于没有进度条的长时间等待,用户会任务死机了,毫不犹豫的关掉应用:一般用于下载任务,删除大量任务 ...
- HTML5 CSS3 诱人的实例 : 网页加载进度条的实现,下载进度条等
今天给大家带来一个比较炫的进度条,进度条在一耗时操作上给用户一个比较好的体验,不会让用户觉得在盲目等待,对于没有进度条的长时间等待,用户会任务死机了,毫不犹豫的关掉应用:一般用于下载任务,删除大量任务 ...
- HTML5 CSS3 诱人的实例: 3D立方体旋转动画
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/34120047 创意来自:http://www.html5tricks.com/d ...
- HTML5 & CSS3 初学者指南(4) – Canvas使用
介绍 传统的HTML主要用于文本的创建,可以通过<img>标签插入图像,动画的实现则需要第三方插件.在这方面,传统的HTML极其缺乏满足现代网页多媒体需求的能力.HTML5的到来,带来了新 ...
- HTML5 & CSS3初学者指南(4) – Canvas使用
介绍 传统的HTML主要用于文本的创建,可以通过<img>标签插入图像,动画的实现则需要第三方插件.在这方面,传统的HTML极其缺乏满足现代网页多媒体需求的能力.HTML5的到来,带来了新 ...
- html5,css3炫酷实例-元素
自动完成输入框下拉列表 使用的插件:jquery-ui 使用数据源实现文本框的自动完成功能 <link href="https://cdn.bootcss.com/jqueryui/1 ...
- 分享10款激发灵感的最新HTML5/CSS3应用
1.HTML5/CSS3实现iOS Path菜单 菜单动画很酷 Path菜单相信大家都不陌生吧,它在iOS中非常流行,今天我们要分享的菜单就是利用HTML5和CSS3技术来模拟实现这款iOS Path ...
- 8款给力HTML5/CSS3应用插件 可爱的HTML5笑脸
1.HTML5/CSS3实现笑脸动画 非常可爱 今天我们要分享一款基于纯CSS3实现的笑脸动画,我们只要在面部滑动鼠标,即可让人物的眼睛嘴巴动起来,实现微笑的效果,还挺可爱的. 在线演示 源码下载 2 ...
随机推荐
- iPhone开发初探
本文是作者从一无所知到入门的知识学习过程,并结合自己在嵌入式开发的经验所写的技术总结文章,以供后来者学习. 苹果公司的iphone平台采用Object-c做为native language的开发,Ob ...
- obj-c编程10:Foundation库中类的使用(6)[线程和操作队列]
任何语言都不能避而不谈线程这个东东,虽然他是和平台相关的鸟,虽说unix哲学比较讨厌线程的说...线程不是万能灵药,但有些场合还是需要的.谈到线程就不得不考虑同步和死锁问题,见如下代码: #impor ...
- 微信小程序弹出和隐藏遮罩层动画以及五星评分
参考源码: http://www.see-source.com/weixinwidget/detail.html?wid=82 https://blog.csdn.net/pcaxb/article/ ...
- ffmpeg 在windows 上编译
我在网上看到了一些资料,但是很多都不怎么全,而且 总会碰到这样或那样的问题,下面是我的一些经验,分享一下,当然也参考了大侠们的东西呵呵! 环境: OS:windows mingw +yasm+fmpe ...
- TypeScript 的声明文件的使用与编写
https://fenying.net/2016/09/19/typings-for-typescript/ TypeScript 是 JavaScript 的超集,相比 JavaScript,其最关 ...
- IOS Swift语言开发 tableView的重用以及自cell的自适应高度
http://www.aichengxu.com/iOS/11143168.htm 一.准备数据 (这是一个元组,第一个元素为英雄的名字;第二个元素为英雄头像图片的名字,格式为.PNG,如果为其他的格 ...
- Android Studio 插件开发详解一:入门练手
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78112003 本文出自[赵彦军的博客] 一:概述 相信大家在使用Android S ...
- 黄文俊:Serverless小程序后端技术分享
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 黄文俊,现任腾讯云SCF无服务器云函数高级产品经理,多年企业级系统开发和架构工作经验,对企业级存储.容器平台.微服务架构.无服务器计算等领域 ...
- 关于前端本地压缩图片,兼容IOS/Android/PC且自动按需加载文件之lrz.bundle.js
一.介绍说明主要特点: ①在前端压缩好要上传的图片可以更快的发送给后端,因此也特别适合在移动设备上使用. ②兼容IOS/Android,修复了IOS/Android某些版本已知的BUG. ③按需加载文 ...
- MySQL的变量分类总结
在MySQL中,my.cnf是参数文件(Option Files),类似于ORACLE数据库中的spfile.pfile参数文件,照理说,参数文件my.cnf中的都是系统参数(这种称呼比较符合思维习惯 ...