canvas实现刮刮奖效果
实现效果
常见活动页刮刮奖效果
思路
第一步:首先做好刮奖的内容html,然后使用canvas绘制一层蒙层覆盖在奖品内容上,可以在蒙层上使用canvas写3个字“刮一刮”,看起更有效果。
第二步:接下来使用鼠标(pc端),手指(wap端)按下蒙层区域,在以按下点的区域使用canvas画一个透明的圆圈,这时蒙层下的奖品文案就会显示出来。
第三步:判断刮开的区域占总canvas区域的80%(自定义)时,去除蒙层,需要在我们每次触碰到蒙层,也就是在刮的时候去计算面积。
实现
步骤一:做好奖品内容dom
这里样式我就不贴了,样式可以自己随意写
<div class="scrapeLottoBox"> <div class="scrapeLottoBox-btn">刮开优惠</div> <div class="scrapeLottoBox-price"><span>¥123</span>.00</div> </div> 复制代码
步骤二:使用canvas画出蒙层,覆盖住123。
<div class="scrapeLottoBox"> <div class="scrapeLottoBox-btn">刮开优惠</div> <div class="scrapeLottoBox-price"><span>¥123</span>.00</div> <!-- 蒙层 --> <canvas id="scrapeLottoCanvas" width="150" height="70"></canvas> </div> let myCanvas = document.getElementById("scrapeLottoCanvas"); // 搭建环境,填充蒙层色 let cxt = myCanvas.getContext("2d"); // 创建画布 cxt.globalAlpha = 1; // 设置透明度 cxt.fillStyle = "#ccc"; // 设置背景灰色 cxt.fillRect(0, 0, 300, 140); // 绘制填充矩形 300 140为宽高 // 绘制文本“刮一刮” cxt.fillStyle = "#000"; cxt.font = "18px 微软雅黑"; cxt.textAlign = "center"; cxt.textBaseline = "middle"; cxt.fillText('刮一刮', 73, 35, 100); 复制代码
效果:
步骤三:当点击或者按下移动时,canvas画出透明小圆圈
let flag = false; // pc端事件监听 myCanvas.addEventListener('mousedown', function (e) { flag = true; drawArc(e) // 绘制 }) myCanvas.addEventListener('mousemove', function (e) { if (flag == true) { drawArc(e) // 绘制 } }) // wap端事件监听 myCanvas.addEventListener('touchstart', function (e) { flag = true; drawArc(e) // 绘制 }) myCanvas.addEventListener('touchmove', function (e) { if (flag == true) { drawArc(e) // 绘制 } }) // 绘画区域 function drawArc(e) { var canvasPos = myCanvas.getBoundingClientRect(); // 获取矩形canvas在页面中的绝对位置 var pageScrollTop = document.documentElement.scrollTop || document.body.scrollTop; // 获取页面滚动的高度(处理页面下滑后才出现刮奖,计算坐标点) var pageScrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; // 同理 var mouseX = (e.pageX || e.targetTouches[0].pageX) - canvasPos.left - pageScrollLeft; // 点击点坐标的X轴距离 - 矩形左上角X轴距离 - 页面卷出去的X距离 var mouseY = (e.pageY || e.targetTouches[0].pageY) - canvasPos.top - pageScrollTop; // 同理 cxt.globalCompositeOperation = "destination-out"; // 相交部分不显示 cxt.beginPath(); // 开始一条路径 cxt.fillStyle = "white"; // 白色 cxt.moveTo(mouseX, mouseY); // 移动到位置 mouseX,mouseY cxt.arc(mouseX, mouseY, 6, 0, 2 * Math.PI); // 画一个圆 半径为6 cxt.fill(); // 填充 } 复制代码
效果:
步骤四:当鼠标或手指抬起时,计算已刮开的区域
// pc端事件监听 myCanvas.addEventListener('mouseup', function () { flag = false; calcArea(); // 计算 }) // wap端事件监听 myCanvas.addEventListener('touchend', function () { flag = false; calcArea(); // 计算 }) // 计算区域 function calcArea() { // 获取像素点的数据 var myImg = cxt.getImageData(0, 0, myCanvas.width, myCanvas.height); var num = 0; var max = myImg.data.length / 4; // 取1/4计算区域比例即可,节省计算开销 for (var i = 0; i < myImg.data.length; i += 4) { if (myImg.data[i + 3] == 0) { num++; } } // 0 - 1 为区域百分比,此时80%时清空全部蒙层 if (num >= max * 0.8) { myCanvas.remove() } } 复制代码
完成!
贴上完整代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <style> /** * 刮刮奖 */ .scrapeLottoBox{ width: 285px; height: 120px; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; background: url('https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6ace29d7c26e4e88a51ec638111d0a3f~tplv-k3u1fbpfcp-watermark.image') center/100% no-repeat; } .scrapeLottoBox-btn{ font-size: 20px; color: #fff; width: 50px; position: absolute; right: 25px; top: 30px; text-align: center; } .scrapeLottoBox-price{ color: #f51e55; width: 150px; text-align: center; position: absolute; left: 30px; top: 25px; font-size: 16px; } .scrapeLottoBox-price>span{ font-size: 40px; line-height: 67px; font-weight: 700; } .scrapeLottoBox>#scrapeLottoCanvas{ position: absolute; left: 30px; top: 25px; } </style> </head> <body> <div> <div>刮开优惠</div> <div><span>¥123</span>.00</div> <!-- 蒙层 --> <canvas id="scrapeLottoCanvas" width="150" height="70"></canvas> </div> <script> /** * 创建刮刮奖 */ createScrapeLotto() function createScrapeLotto() { let myCanvas = document.getElementById("scrapeLottoCanvas"); // 搭建环境 let cxt = myCanvas.getContext("2d"); cxt.globalAlpha = 1; cxt.fillStyle = "#ccc"; cxt.fillRect(0, 0, 300, 140); // 文本 cxt.fillStyle = "#000"; cxt.font = "18px 微软雅黑"; cxt.textAlign = "center"; cxt.textBaseline = "middle"; cxt.fillText('刮一刮', 73, 35, 100); // pc let flag = false; myCanvas.addEventListener('mousedown', function (e) { flag = true; drawArc(e) }) myCanvas.addEventListener('mousemove', function (e) { if (flag == true) { drawArc(e) } }) myCanvas.addEventListener('mouseup', function () { flag = false; calcArea(); }) // wap myCanvas.addEventListener('touchstart', function (e) { flag = true; drawArc(e) }) myCanvas.addEventListener('touchmove', function (e) { if (flag == true) { drawArc(e) } }) myCanvas.addEventListener('touchend', function () { flag = false; calcArea(); }) // 绘画区域 function drawArc(e) { var canvasPos = myCanvas.getBoundingClientRect(); var pageScrollTop = document.documentElement.scrollTop || document.body.scrollTop; var pageScrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; var mouseX = (e.pageX || e.targetTouches[0].pageX) - canvasPos.left - pageScrollLeft; var mouseY = (e.pageY || e.targetTouches[0].pageY) - canvasPos.top - pageScrollTop; cxt.globalCompositeOperation = "destination-out"; cxt.beginPath(); cxt.fillStyle = "white"; cxt.moveTo(mouseX, mouseY); cxt.arc(mouseX, mouseY, 6, 0, 2 * Math.PI); cxt.fill(); } // 计算区域 function calcArea() { var myImg = cxt.getImageData(0, 0, myCanvas.width, myCanvas.height); var num = 0; var max = myImg.data.length / 4; for (var i = 0; i < myImg.data.length; i += 4) { if (myImg.data[i + 3] == 0) { num++; } } if (num >= max * 0.4) { myCanvas.remove() } } } </script> </body> </html> 复制代码
总结
勤于动手实践见真知!
伪原创工具 SEO网站优化 https://www.237it.com/
作者:熊猫爱吃笋
链接:https://juejin.cn/post/7036160268937723917