「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」
实现效果
常见活动页刮刮奖效果
思路
第一步:首先做好刮奖的内容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(); // 填充
}
复制代码
效果:
步骤四:当鼠标或手指抬起时,计算已刮开的区域
扫描二维码关注公众号,回复:
13469623 查看本文章

// 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 lang="en">
<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 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>
<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>
复制代码
总结
勤于动手实践见真知!