HTML5 Canvas实战之刮奖效果

时间:2021-10-22 14:44:22
近年来由于移动设备对HTML5的较好支持,经常有活动用刮奖的效果,最近也在看H5方面的内容,就自己实现了一个,现分享出来跟大家交流。   1、效果     2、原理 原理很简单,就是在刮奖区添加两个canvas,第一个canvas用于显示刮开后显示的内容,可以是一张图片或一个字符串,第二个canvas用于显示涂层,可以用一张图片或用纯色填充,第二个canvas覆盖在第一个canvas上面。   当在第二个canvas上点击或涂抹(点击然后拖动鼠标)时,把点击区域变为透明,这样就可以看到第一个canvas上的内容,即实现了刮奖效果。   3、实现 (1)定义Lottery类 function Lottery(id, cover, coverType, width, height, drawPercentCallback) {     this.conId = id;     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 = drawPercentCallback; } 对参数解释一下:   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:absolute;left:0;top:0;' }); this.mask = this.mask || this.createElement('canvas', {     style: 'position:absolute;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.width;         _this.height = this.height;         _this.resizeCanvas(_this.background, this.width, this.height);         _this.backCtx.drawImage(this, 0, 0);     }     image.src = this.lottery; } else if (this.lotteryType == 'text') {     this.width = this.width;     this.height = this.height;     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();