HTML5 canvas标签实现刮刮卡效果
作者:佚名
字体:[ ] 来源:互联网 时间:04-24 17:10:52
这篇文章主要介绍了HTML5 canvas标签实现刮刮卡效果,本文给出了运行效果、HTML代码和JS代码,并给出了完整源码下载,需要的朋友可以参考下
你玩过刮刮卡么?一不小心可以中奖的那种。今天我给大家分享一个基于HTML5技术实现的刮刮卡效果,在PC上只需按住鼠标,在手机上你只需按住指头,轻轻刮去图层就可以模拟真实的刮奖效果。
源码下载:
我们利用HTML5的画布Canvas,结合其提供的API,在Canvas元素上绘制一个灰色蒙层,然后通过检测用户鼠标移到和手势来绘制一个透明的图形,这样就能看到Canvas背景下的真实图片,就达到刮刮卡效果。
我们只需要在页面中加入canvas标签元素,其他的就看javascript的了。注意canvas元素是HTML5才有的元素,运行在支持HTML5的现代浏览器上。代码如下:&canvas&&/canvas& Javascript
首先,我们要禁用页面的鼠标选中拖动的事件,就是不运行执行选中操作。代码如下:var bodyStyle = document.body. bodyStyle.mozUserSelect = 'none'; bodyStyle.webkitUserSelect = 'none'; 接着我们定义图片类,获取canvas元素,并设置背景和位置属性。我们在本例中用到两张随机照片,每次刷新随机一张图片作为背景。代码如下:var img = new Image(); var canvas = document.querySelector('canvas'); canvas.style.backgroundColor='transparent'; canvas.style.position = 'absolute'; var imgs = ['p_0.jpg','p_1.jpg']; var num = Math.floor(Math.random()*2); img.src = imgs[num]; 然后进入主体,当检测到图片加载完的时候,首先定义一些属性和函数,函数layer()用来绘制一个灰色的正方形,eventDown()定义了按下事件eventUp()定义了松开事件,eventMove()定义了移动事件,其中当按下时,获取坐标位移,并通过arc(x, y, 10, 0, Math.PI * 2)来绘制小圆点。代码如下:img.addEventListener('load', function(e) {
var w = img.width,
var offsetX = canvas.offsetLeft,
offsetY = canvas.offsetT
var mousedown =
function layer(ctx) {
ctx.fillStyle = 'gray';
ctx.fillRect(0, 0, w, h);
function eventDown(e){
e.preventDefault();
mousedown=
function eventUp(e){
e.preventDefault();
mousedown=
function eventMove(e){
e.preventDefault();
if(mousedown) {
if(e.changedTouches){
e=e.changedTouches[e.changedTouches.length-1];
var x = (e.clientX + document.body.scrollLeft || e.pageX) - offsetX || 0,
y = (e.clientY + document.body.scrollTop || e.pageY) - offsetY || 0;
with(ctx) {
beginPath()
arc(x, y, 10, 0, Math.PI * 2);//绘制圆点
//... }); 最后,通过canvas调用以上函数,绘制图形,并且侦听触控及鼠标事件,调用相应的函数,请看代码:代码如下:img.addEventListener('load', function(e) {
//..接上段代码
canvas.width=w;
canvas.height=h;
canvas.style.backgroundImage='url('+img.src+')';
ctx=canvas.getContext('2d');
ctx.fillStyle='transparent';
ctx.fillRect(0, 0, w, h);//绘制矩形
layer(ctx);
ctx.globalCompositeOperation = 'destination-out';
canvas.addEventListener('touchstart', eventDown);
canvas.addEventListener('touchend', eventUp);
canvas.addEventListener('touchmove', eventMove);
canvas.addEventListener('mousedown', eventDown);
canvas.addEventListener('mouseup', eventUp);
canvas.addEventListener('mousemove', eventMove); 你可以下载DEMO中的完整的代码,你可以根据实际需求,结合后台程序与数据库,完成一个真正的刮刮卡程序。
大家感兴趣的内容
12345678910
最近更新的内容刮刮卡印刷多少钱|佳汇印刷|南京刮刮卡印刷
印刷技术的出现对人类的发展有什么影响文字产生后,人类传播有了一种崭新的方式,但文字的记录也自然成为一个亟待解决的难题。最初人们将文字刻在兽甲和龟壳上,后来有发明了类如笺竹这样的物品记录文字,随后蔡伦发明造纸术,人类文字传播逐渐过渡到以纸为凭借的阶段。纸张轻便,易于携带,南京刮刮卡印刷,而且造价比较低,这种方式被越来越多人所接受。然而,手抄毕竟是一项费时费力的工程,而且由于手抄借助人力,不可避免会产生一定的缺漏。为了解决这些问题,我们的先人充分发挥自己的智慧,刮刮卡印刷价格,刮刮卡印刷术的发明并且完善使得人类传播精1确快捷,刮刮卡印刷厂家,它的对外传播更使全世界受益匪浅。 印刷术的起源1、拓片是印刷技术产生的重要条件之一。古人发现在石碑上盖一张微微湿润的纸,刮刮卡印刷多少钱,用软槌轻打,使纸陷入碑面文字凹下处,待纸干后再用布包上棉花,蘸上墨汁,在纸上轻轻拍打,纸面上就会留下黑地白字跟石碑一模一样的字迹。这样的方法比手抄简便、可靠。于是拓印就出现了。2、唐朝(7世纪左右)发明雕版印刷术,并在唐朝中后期普遍使用。 早期刮刮卡印刷活动主要在民间进行,多用于印刷佛像、经咒、发愿文以及历书等。唐初,玄奘曾用回锋纸印普贤像,施给僧尼信众。3、北宋时期(11世纪左右),毕升发明活字印刷术,但没有普遍使用,而是仍然普遍使用雕版印刷术。
刮刮卡印刷多少钱|佳汇印刷|南京刮刮卡印刷由南京佳汇印刷有限公司提供。刮刮卡印刷多少钱|佳汇印刷|南京刮刮卡印刷是南京佳汇印刷有限公司()今年全新升级推出的,以上图片仅供参考,请您拨打本页面或图片上的联系***,索取新的信息,联系人:潘经理。
发布人信息
久久信息推荐
Inc. All Rights Reserved. 久久信息网 版权所有近年来由于移动设备对HTML5的较好支持,经常有活动用刮奖的效果,最近也在看H5方面的内容,就自己实现了一个,现分享出来跟大家交流。
原理很简单,就是在刮奖区添加两个canvas,第一个canvas用于显示刮开后显示的内容,可以是一张图片或一个字符串,第二个canvas用于显示涂层,可以用一张图片或用纯色填充,第二个canvas覆盖在第一个canvas上面。
当在第二个canvas上点击或涂抹(点击然后拖动鼠标)时,把点击区域变为透明,这样就可以看到第一个canvas上的内容,即实现了刮奖效果。
(1)定义Lottery类
function Lottery(id, cover, coverType, width, height, drawPercentCallback) {
this.conId =
this.conNode = document.getElementById(this.conId);
this.cover = cover || '#CCC';
this.coverType = coverType || 'color';
this.background = null;
this.backCtx = null;
this.mask = null;
this.maskCtx = null;
this.lottery = null;
this.lotteryType = 'image';
this.width = width || 300;
this.height = height || 100;
this.clientRect = null;
this.drawPercentCallback = drawPercentC
对参数解释一下:
id:刮奖容器的id
cover:涂层内容,可以为图片地址或颜色值,可空,默认为 #ccc
coverType:涂层类型,值为 image 或 color,可空,默认为 color
width:刮奖区域宽度,默认为300px,可空
height:刮奖区域高度,默认为100px,可空
drawPercentCallback:刮开的区域百分比回调,可空
然后还定义了几个需要用到的变量:
background:第一个canvas元素
backCtx:background元素的2d上下文(context)
mask:第二个canvas元素
maskCtx:mask元素的2d上下文(context)
lottery:刮开后显示的内容,可以为图片地址或字符串
lotteryType:刮开后显示的内容类型,值为 image 或 text,要跟lottery匹配
clientRect:用于记录mask元素的&getBoundingClientRect() 值
(2)添加二个canvas到刮奖容器,并获取2d上下文
this.background = this.background || this.createElement('canvas', {
style: 'position:left:0;top:0;'
this.mask = this.mask || this.createElement('canvas', {
style: 'position:left:0;top:0;'
if (!this.conNode.innerHTML.replace(/[\w\W]| /g, '')) {
this.conNode.appendChild(this.background);
this.conNode.appendChild(this.mask);
this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null;
this.bindEvent();
this.backCtx = this.backCtx || this.background.getContext('2d');
this.maskCtx = this.maskCtx || this.mask.getContext('2d');
这里用于了createElement工具方法,另外还绑定了事件,后面介绍。
(3)绘制第一个canvas
第一个canvas分两种类型,image 和 string,如果是图片直接用canvas的drawImage就可以了,如果是string,要先用白色填充,然后在上下左右居中的地方绘制字符串,代码如下:
if (this.lotteryType == 'image') {
var image = new Image(),
_this = this;
image.onload = function () {
_this.width = this.
_this.height = this.
_this.resizeCanvas(_this.background, this.width, this.height);
_this.backCtx.drawImage(this, 0, 0);
image.src = this.
} else if (this.lotteryType == 'text') {
this.width = this.
this.height = this.
this.resizeCanvas(this.background, this.width, this.height);
this.backCtx.save();
this.backCtx.fillStyle = '#FFF';
this.backCtx.fillRect(0, 0, this.width, this.height);
this.backCtx.restore();
this.backCtx.save();
var fontSize = 30;
this.backCtx.font = 'Bold ' + fontSize + 'px Arial';
this.backCtx.textAlign = 'center';
this.backCtx.fillStyle = '#F60';
this.backCtx.fillText(this.lottery, this.width / 2, this.height / 2 + fontSize / 2);
this.backCtx.restore();
(4)绘制第二个canvas
第二个canvas也分 image 或 color 填充两种情况。
这里有一个难点,就是如何把鼠标点击区域变成透明的呢?***在这里:
即我们要把 maskCtx的&globalCompositeOperation 设置为&destination-out ,详细的用法请参考上面给出的链接。
因此,绘制第二个canvas的代码如下:
this.resizeCanvas(this.mask, this.width, this.height);
if (this.coverType == 'color') {
this.maskCtx.fillStyle = this.
this.maskCtx.fillRect(0, 0, this.width, this.height);
this.maskCtx.globalCompositeOperation = 'destination-out';
} else if (this.coverType == 'image'){
var image = new Image(),
_this = this;
image.onload = function () {
_this.maskCtx.drawImage(this, 0, 0);
_this.maskCtx.globalCompositeOperation = 'destination-out';
image.src = this.
这里resizeCanvas是改变canvas大小的工具方法。
(5)绑定事件
绘制完成后,要给第二个canvas绑定事件。这里分了移动设备和PC-WEB两处情况。移动设备是 touchstart 和 touchmove 事件,对应的PC-WEB是keydown 和 mousemove事件,另外PC-WEB方式下,要给document绑定一个mouseup事件,用来判断鼠标是否按下。代码如下:
bindEvent: function () {
var _this = this;
var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
var clickEvtName = device ? 'touchstart' : 'mousedown';
var moveEvtName = device? 'touchmove': 'mousemove';
if (!device) {
var isMouseDown = false;
document.addEventListener('mouseup', function(e) {
isMouseDown = false;
}, false);
this.mask.addEventListener(clickEvtName, function (e) {
isMouseDown = true;
var docEle = document.documentE
if (!_this.clientRect) {
_this.clientRect = {
var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientL
var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientT
_this.drawPoint(x, y);
}, false);
this.mask.addEventListener(moveEvtName, function (e) {
if (!device && !isMouseDown) {
return false;
var docEle = document.documentE
if (!_this.clientRect) {
_this.clientRect = {
var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientL
var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientT
_this.drawPoint(x, y);
}, false);
这里在事件中取出了鼠标坐标,调用了drawPoint进行了绘制,下面会讲到。
(6)绘制点击和涂抹区域
这里用到了canvas的径向渐变,在鼠标从标处绘制一个圆形,代码如下:
drawPoint: function (x, y) {
this.maskCtx.beginPath();
var radgrad = this.maskCtx.createRadialGradient(x, y, 0, x, y, 30);
radgrad.addColorStop(0, 'rgba(0,0,0,0.6)');
radgrad.addColorStop(1, 'rgba(255, 255, 255, 0)');
this.maskCtx.fillStyle =
this.maskCtx.arc(x, y, 30, 0, Math.PI * 2, true);
this.maskCtx.fill();
if (this.drawPercentCallback) {
this.drawPercentCallback.call(null, this.getTransparentPercent(this.maskCtx, this.width, this.height));
(7)涂抹区域百分比
在很多时候,我们还需要知道用户涂抹了多少然后进行下一步交互,如当用户涂抹了80%后,才允许下一张显示。
这个百分比如何计算呢?其实很简单,我们可以用getImageData方法到画布上指定矩形的像素数据,由于每个像素都是用rgba表示的,而涂抹过的区域是透明的,所以我们只需要判断alpha通道的值就可以知道是否透明。代码如下:
getTransparentPercent: function(ctx, width, height) {
var imgData = ctx.getImageData(0, 0, width, height),
pixles = imgData.data,
transPixs = [];
for (var i = 0, j = pixles. i & i += 4) {
var a = pixles[i + 3];
if (a & 128) {
transPixs.push(i);
return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
(8)调用入口init
最后再提供一个入口用来进行绘制和重置,代码如下:
init: function (lottery, lotteryType) {
this.lottery =
this.lotteryType = lotteryType || 'image';
this.drawLottery();
至此,关键代码全部讲解完了。
(9)完整代码
完整代码及DEMO可看这里:
欢迎大家留言讨论,如有bug请在github上或本文后面留言。
阅读(...) 评论()