刮一刮效果
2017-02-23 17:47:13 0 举报仅支持查看
AI智能生成
新版思维导图是一种创新的思维工具,它以直观、清晰的图形化方式展示信息,帮助用户更好地理解和记忆复杂的知识结构。新版思维导图采用先进的算法和设计,使得节点和分支可以自由移动和调整,更加灵活地适应用户的需求。同时,它还支持多种颜色、形状和样式的自定义,使得每个思维导图都能反映出用户独特的思维方式。此外,新版思维导图还具有强大的协作功能,用户可以与他人共享和编辑思维导图,实现知识的共享和创新。总的来说,新版思维导图是一种高效、便捷的思维工具,能够帮助用户提升思维能力,提高工作和学习效率。
canvas刮一刮笔记
模版推荐
作者其他创作
大纲/内容
功能
1、定义一个Lotty的类和所需的变量
2、需要在原型链上面创建容器,两个canvas容器,并获取2d上下文内容
3、绘制第一个canvas,两种类型image/text/html,如果是图片直接用canvas的drawImage就可以了,如果是string,要先用白色填充,然后在上下左右居中的地方绘制字符串,
4、绘制第二个canvas,通3一样两种类型,并且需要重点处理如何把鼠标点击区域变成透明的呢?答案在这里:https://developer.mozilla.org/en/docs/Web/Guide/HTML/Canvas_tutorial/Compositing<div>即我们要把 maskCtx的 globalCompositeOperation 设置为 destination-out ,详细的用法请参考上面给出的链接。 这里resizeCanvas是改变canvas大小的工具方法。<br></div>
5、绑定事件<div> 绘制完成后,要给第二个canvas绑定事件。这里分了移动设备和PC-WEB两处情况。移动设备是 touchstart 和 touchmove 事件,对应的PC-WEB是keydown 和 mousemove事件,另外PC-WEB方式下,要给document绑定一个mouseup事件,用来判断鼠标是否按下</div>
6、绘制点击和涂抹区域 这里用到了canvas的径向渐变,在鼠标从标处绘制一个圆形,
7、涂抹区域百分比<div> 在很多时候,我们还需要知道用户涂抹了多少然后进行下一步交互,如当用户涂抹了80%后,才允许下一张显示。</div><div><br></div><div> 这个百分比如何计算呢?其实很简单,我们可以用getImageData方法到画布上指定矩形的像素数据,由于每个像素都是用rgba表示的,而涂抹过的区域是透明的,所以我们只需要判断alpha通道的值就可以知道是否透明。</div>
8、调用入口init<div><br></div><div> 最后再提供一个入口用来进行绘制和重置</div>
需要扩建功能
1、canvas的类型支持HTML格式
2、百分比大于60,涂层全部清除
3、--
高效的组织结构图
概念图
支持移动端
源码js
<div>/***</div><div> *1、</div><div> *id:刮奖容器的id</div><div> cover:涂层内容,可以为图片地址或颜色值,可空,默认为 #ccc</div><div> coverType:涂层类型,值为 image 或 color,可空,默认为 color</div><div> width:刮奖区域宽度,默认为300px,可空</div><div> height:刮奖区域高度,默认为100px,可空</div><div> drawPercentCallback:刮开的区域百分比回调,可空</div><div> 然后还定义了几个需要用到的变量:</div><div><br></div><div> background:第一个canvas元素</div><div> backCtx:background元素的2d上下文(context)</div><div> mask:第二个canvas元素</div><div> maskCtx:mask元素的2d上下文(context)</div><div> lottery:刮开后显示的内容,可以为图片地址或字符串</div><div> lotteryType:刮开后显示的内容类型,值为 image 或 text,要跟lottery匹配</div><div> clientRect:用于记录mask元素的 getBoundingClientRect() 值</div><div><br></div><div> *</div><div> * ***/</div><div>function Lottery(id, cover, coverType, width, height, drawPercentCallback) {</div><div> this.conId = id;</div><div> this.conNode = document.getElementById(this.conId);</div><div> this.cover = cover;</div><div> this.coverType = coverType;</div><div> this.background = null;</div><div> this.backCtx = null;</div><div> this.mask = null;</div><div> this.maskCtx = null;</div><div> this.lottery = null;</div><div> this.lotteryType = 'image';</div><div> this.width = width || 300;</div><div> this.height = height || 100;</div><div> this.clientRect = null;</div><div> this.drawPercentCallback = drawPercentCallback;</div><div> this.htmlObj = null;</div><div>}</div><div><br></div><div>Lottery.prototype = {</div><div> setHtmlObj: function (obj){</div><div> this.htmlObj = obj;</div><div> },</div><div> createElement: function (tagName, attributes) {</div><div> var ele = document.createElement(tagName);</div><div> for (var key in attributes) {</div><div> ele.setAttribute(key, attributes[key]);</div><div> }</div><div> return ele;</div><div> },</div><div> cleanMask: function (){</div><div> this.maskCtx.clearRect(0, 0, this.width, this.height);</div><div> },</div><div> /**</div><div> * (7)涂抹区域百分比</div><div> * 在很多时候,我们还需要知道用户涂抹了多少然后进行下一步交互,如当用户涂抹了80%后,才允许下一张显示。</div><div><br></div><div> 这个百分比如何计算呢?其实很简单,我们可以用getImageData方法到画布上指定矩形的像素数据,由于每个像素都是用rgba表示的,而涂抹过的区域是透明的,所以我们只需要判断alpha通道的值就可以知道是否透明。</div><div> *</div><div> * ***/</div><div> getTransparentPercent: function(ctx, width, height) {</div><div> var imgData = ctx.getImageData(0, 0, width, height),</div><div> pixles = imgData.data,</div><div> transPixs = [];</div><div> for (var i = 0, j = pixles.length; i < j; i += 4) {</div><div> var a = pixles[i + 3];</div><div> if (a < 128) {</div><div> transPixs.push(i);</div><div> }</div><div> }</div><div> return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);</div><div> },</div><div> resizeCanvas: function (canvas, width, height) {</div><div> canvas.width = width;</div><div> canvas.height = height;</div><div> canvas.getContext('2d').clearRect(0, 0, width, height);</div><div> },</div><div> /**(6)</div><div> * 绘制点击和涂抹区域 这里用到了canvas的径向渐变,在鼠标从标处绘制一个圆形,</div><div> * ***/</div><div> drawPoint: function (x, y) {</div><div> this.maskCtx.beginPath();</div><div> var radgrad = this.maskCtx.createRadialGradient(x, y, 0, x, y, 30);</div><div> radgrad.addColorStop(0, 'rgba(0,0,0,0.6)');</div><div> radgrad.addColorStop(1, 'rgba(255, 255, 255, 0)');</div><div> this.maskCtx.fillStyle = radgrad;</div><div> this.maskCtx.arc(x, y, 30, 0, Math.PI * 2, true);</div><div> this.maskCtx.fill();</div><div> if (this.drawPercentCallback) {</div><div> this.drawPercentCallback.call(null, this.getTransparentPercent(this.maskCtx, this.width, this.height));</div><div> }</div><div> },</div><div> /**(5)</div><div> * 绑定事件</div><div> * 绘制完成后,要给第二个canvas绑定事件。这里分了移动设备和PC-WEB两处情况。移动设备是 touchstart 和 touchmove 事件,对应的PC-WEB是keydown 和 mousemove事件,另外PC-WEB方式下,要给document绑定一个mouseup事件,用来判断鼠标是否按下</div><div> * **/</div><div> bindEvent: function () {</div><div> var _this = this;</div><div> var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));</div><div> var clickEvtName = device ? 'touchstart' : 'mousedown';</div><div> var moveEvtName = device? 'touchmove': 'mousemove';</div><div> if (!device) {</div><div> var isMouseDown = false;</div><div> document.addEventListener('mouseup', function(e) {</div><div> isMouseDown = false;</div><div> }, false);</div><div> } else {</div><div> document.addEventListener("touchmove", function(e) {</div><div> if (isMouseDown) {</div><div> e.preventDefault();</div><div> }</div><div> }, false);</div><div> document.addEventListener('touchend', function(e) {</div><div> isMouseDown = false;</div><div> }, false);</div><div> }</div><div> this.mask.addEventListener(clickEvtName, function (e) {</div><div> isMouseDown = true;</div><div> var docEle = document.documentElement;</div><div> if (!_this.clientRect) {</div><div> _this.clientRect = {</div><div> left: 0,</div><div> top:0</div><div> };</div><div> }</div><div> var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientLeft;</div><div> var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientTop;</div><div> _this.drawPoint(x, y);</div><div> }, false);</div><div><br></div><div> this.mask.addEventListener(moveEvtName, function (e) {</div><div> if (!device && !isMouseDown) {</div><div> return false;</div><div> }</div><div> var docEle = document.documentElement;</div><div> if (!_this.clientRect) {</div><div> _this.clientRect = {</div><div> left: 0,</div><div> top:0</div><div> };</div><div> }</div><div> var x = (device ? e.touches[0].clientX : e.clientX) - _this.clientRect.left + docEle.scrollLeft - docEle.clientLeft;</div><div> var y = (device ? e.touches[0].clientY : e.clientY) - _this.clientRect.top + docEle.scrollTop - docEle.clientTop;</div><div> _this.drawPoint(x, y);</div><div> }, false);</div><div> },</div><div>// (2)添加二个canvas到刮奖容器,并获取2d上下文 这里用于了createElement工具方法,另外还绑定了事件,后面介绍。</div><div> drawLottery: function () {</div><div> this.background = this.background || this.createElement('canvas', {</div><div> style: 'width:100%;height:auto;margin:0;padding:0;display:block;position:absolute;left:0;top:0; background-clip: padding-box;background-size: 100% 100%;'</div><div> });</div><div> this.mask = this.mask || this.createElement('canvas', {</div><div> style: 'width:100%;height:auto;margin:0;padding:0;display:block;position:absolute;left:0;top:0; background-clip: padding-box;background-size: 100% 100%;'</div><div> });</div><div><br></div><div> if (!this.conNode.innerHTML.replace(/[\w\W]| /g, '')) {</div><div> this.conNode.appendChild(this.background);</div><div> this.conNode.appendChild(this.mask);</div><div> this.clientRect = this.conNode ? this.conNode.getBoundingClientRect() : null;</div><div> this.bindEvent();</div><div> }</div><div><br></div><div> this.backCtx = this.backCtx || this.background.getContext('2d');</div><div> this.maskCtx = this.maskCtx || this.mask.getContext('2d');</div><div><br></div><div>// (3) 绘制第一个canvas 第一个canvas分两种类型,image 和 string,如果是图片直接用canvas的drawImage就可以了,如果是string,要先用白色填充,然后在上下左右居中的地方绘制字符串,</div><div> if (this.lotteryType == 'image') {</div><div> var image = new Image(),</div><div> _this = this;</div><div> image.onload = function () {</div><div> this.width = 290;</div><div> this.height = 173;</div><div> _this.width = this.width;</div><div> _this.height = this.height;</div><div> _this.resizeCanvas(_this.background, this.width, this.height);</div><div> _this.backCtx.drawImage(this, 0, 0);</div><div> _this.drawMask();</div><div> }</div><div> image.src = this.lottery;</div><div> } else if (this.lotteryType == 'text') {</div><div> this.width = this.width;</div><div> this.height = this.height;</div><div> this.resizeCanvas(this.background, this.width, this.height);</div><div> this.backCtx.save();</div><div> this.backCtx.fillStyle = '#FFF';</div><div> this.backCtx.fillRect(0, 0, this.width, this.height);</div><div> this.backCtx.restore();</div><div> this.backCtx.save();</div><div> var fontSize = 30;</div><div> this.backCtx.font = 'Bold ' + fontSize + 'px Arial';</div><div> this.backCtx.textAlign = 'center';</div><div> this.backCtx.fillStyle = '#F60';</div><div> this.backCtx.fillText(this.lottery, this.width / 2, this.height / 2 + fontSize / 2);</div><div> this.backCtx.restore();</div><div> this.drawMask();</div><div> } else if(this.lotteryType == "html"){</div><div> this.width = this.width;</div><div> this.height = this.height;</div><div> this.resizeCanvas(this.background, this.width, this.height);</div><div> //画张图 ST</div><div> _this = this;</div><div> var image1 = new Image();</div><div> image1.onload = function () {</div><div> this.width = 290;</div><div> this.height = 173;</div><div> _this.width = this.width;</div><div> _this.height = this.height;</div><div> _this.resizeCanvas(_this.background, this.width, this.height);</div><div> _this.backCtx.drawImage(this, 0, 0);</div><div><br></div><div> //1</div><div> _this.backCtx.save();</div><div> _this.backCtx.fillStyle = '#FFF';</div><div> // _this.backCtx.fillRect(0, 0, _this.width, _this.height); //矩形</div><div> // _this.backCtx.restore();//返回之前保存过的路径状态和属性</div><div> // _this.backCtx.save();//保存当前环境的状态</div><div> var fontSize = 21;</div><div> _this.backCtx.font = 'Bold ' + fontSize + 'px Arial';</div><div> _this.backCtx.textAlign = 'center';</div><div> _this.backCtx.fillStyle = "#fb0c0c";</div><div> _this.backCtx.fillText(_this.htmlObj.str1, _this.width / 2, 30);</div><div> _this.backCtx.font = 'Bold 18px Arial';</div><div> _this.backCtx.fillText(_this.htmlObj.str2, _this.width / 2, 80);</div><div> _this.backCtx.font = 'Bold 13px Arial';</div><div> _this.backCtx.fillText(_this.htmlObj.str3, _this.width / 2 , 120);</div><div> _this.backCtx.fillText(_this.htmlObj.str4, _this.width / 2 - 15 , 150);</div><div> _this.backCtx.restore();</div><div> _this.drawMask();</div><div> //2</div><div><br></div><div> // _this.drawMask();</div><div> }</div><div> image1.src = this.htmlObj.img;</div><div> //画张图 ENDe</div><div> }</div><div> },</div><div> /**(4)</div><div> * 第二个canvas也分 image 或 color 填充两种情况。</div><div><br></div><div> 这里有一个难点,就是如何把鼠标点击区域变成透明的呢?答案在这里:https://developer.mozilla.org/en/docs/Web/Guide/HTML/Canvas_tutorial/Compositing</div><div><br></div><div> 即我们要把 maskCtx的 globalCompositeOperation 设置为 destination-out ,详细的用法请参考上面给出的链接。 这里resizeCanvas是改变canvas大小的工具方法。</div><div> * */</div><div> drawMask: function() {</div><div> this.resizeCanvas(this.mask, this.width, this.height);</div><div> if (this.coverType == 'color') {</div><div> this.maskCtx.fillStyle = this.cover;</div><div> this.maskCtx.fillRect(0, 0, this.width, this.height);</div><div> this.maskCtx.globalCompositeOperation = 'destination-out';</div><div> } else if (this.coverType == 'image'){</div><div> var image = new Image(),</div><div> _this = this;</div><div> image.onload = function () {</div><div> _this.maskCtx.drawImage(this, 0, 0);</div><div> _this.maskCtx.globalCompositeOperation = 'destination-out';</div><div> }</div><div> image.src = this.cover;</div><div> }</div><div> },</div><div><br></div><div> /** 8.调用入口init</div><div><br></div><div> 最后再提供一个入口用来进行绘制和重置,**/</div><div> init: function (lottery, lotteryType) {</div><div> this.lottery = lottery;</div><div> this.lotteryType = lotteryType || 'html';</div><div> this.drawLottery();</div><div> }</div><div>};</div><div><br></div><div>// window.onload = function () {</div><div>// var lottery = new Lottery('lotteryContainer', '#CCC', 'color', 290, 173, drawPercent);</div><div>// lottery.init('http://www.baidu.com/img/bdlogo.gif', 'image');</div><div>// // lottery.init('images/btnBg.png', 'image'); //底部照片</div><div>//</div><div>// document.getElementById('freshBtn').onclick = function() {</div><div>// drawPercentNode.innerHTML = '0%';</div><div>// lottery.init(getRandomStr(10), 'text');</div><div>// }</div><div>//</div><div>// var drawPercentNode = document.getElementById('drawPercent');</div><div>//</div><div>// function drawPercent(percent) {</div><div>// drawPercentNode.innerHTML = percent + '%';</div><div>// // if(percent > 10){</div><div>// // lottery.resizeCanvas(drawPercentNode,290,173);</div><div>// // }</div><div>// }</div><div>// }</div><div><br></div><div>function getRandomStr(len) {</div><div> var text = "";</div><div> var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";</div><div> for( var i=0; i < len; i++ )</div><div> text += possible.charAt(Math.floor(Math.random() * possible.length));</div><div> return text;</div><div>}</div>
js调用 lottery = new Lottery('lotteryContainer', '#CCC', 'color', 290, 173, drawPercent);<div> // lottery.init('http://www.baidu.com/img/bdlogo.gif', 'image');</div><div> lottery.init('images/btnBg2.png', 'image'); //底部照片</div><div><br></div><div> //刷新放结果</div><div> document.getElementById('gjBtn').onclick = function() {</div><div> getlottery();</div><div> };</div><div> //刮奖百分比</div><div> function drawPercent(percent) {</div><div> if(percent > 60){</div><div> lottery.cleanMask();</div><div> }</div><div> $("#gjBtn").removeClass("btngray").addClass("btnlight");</div><div> $("#modalContent").hide();</div><div> }</div>
<div> function getlottery() {</div><div> mobile=$("#mobile").val();</div><div> var params={
</div><div> url:"/activity/wechat/lottery",
</div><div> mobile:mobile,</div><div> activityId:activeid</div><div> };</div><div> $.ajax({</div><div> type: "POST",</div><div> url: path_api + "/util/httpcomm.do",</div><div> data: params,</div><div> dataType: 'json',</div><div> success: function (result) {</div><div> console.log(result);</div><div> if (result.status == 70023) {//status== 70023 活动不存在
</div><div> $("#login").hide();</div><div> $("#modal,#modalContent").show();</div><div> $("#modalContent .content").html("活动不存在");</div><div><br></div><div> } else if (result.status == 70024) {//status==70024 抽检机会为零
</div><div> $("#login,#freshBtn,#lotteryContainer,#gj").hide();</div><div> $("#modal,#modalContent").show();</div><div> $("#modalContent .content").html("抽奖次数已用完").show();</div><div> $("#gjBtn,#modalContent2").hide();</div><div><br></div><div> } else if (result.status == 70025) {//您已中奖
</div><div> alert(result.msg);</div><div> $("#login").hide();</div><div> $("#modal,#modalContent").show();</div><div> $("#modalContent .content").html("您已中奖");</div><div> } else if(result.status == 0){//</div><div> var name = result.data.prize.name;</div><div> var bingo = result.data.bingo;</div><div> var remainLotteryCnt = result.data.remainLotteryCnt;</div><div> $("#cs").html( remainLotteryCnt + "次");</div><div> $("#login").hide();</div><div> $("#lotteryContainer,#gjBtn,#drawPercent").show();</div><div> $(".content").hide();</div><div><br></div><div> if(bingo == 0){//未中奖</div><div> lottery.init("谢谢参与", 'text');</div><div><br></div><div> }else if(bingo == 1){//中奖</div><div> lottery.setHtmlObj({</div><div> str1:"恭喜您中奖了!",</div><div> str2:"IMAX电影兑换券!",</div><div> str3:"奖品已放入"+ mobile +"账号中,请登录,",</div><div> str4:"万达 电影APP- 我的钱包查看使用。",</div><div> img:"images/bntbg2.png"</div><div> })</div><div> lottery.init("恭喜您中奖了", 'html');</div><div> }</div><div><br></div><div> } else if (result.status == 13010) {//没有登录
</div><div> $.Confirm({</div><div> html: "亲,您尚未登录!只有登录后才能执行此操作!", buttons: {"确定": function () {}}</div><div> });</div><div> } else if( result.status == 19999){</div><div> $.Confirm({</div><div> html: "系统繁忙,请稍后再试,谢谢!", buttons: {"确定": function () {}}</div><div> });</div><div> }</div><div> },</div><div> error:function (XMLHttpRequest) {</div><div> }</div><div> });</div><div><br></div><div> }</div>
评论
0 条评论
下一页