代码直接复制拿去用,不会看注释.记得底部下载刷子图片.
<!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>
<style>
.card-body {
position: relative;
width: 340px;
height: 160px;
margin: 0 auto;
}
.canvas {
/* 利用绝对定位让灰色涂层与刮卡结果重叠 */
position: absolute;
top: 0;
left: 0;
z-index: 2;
width: 100%;
height: 100%;
}
.gift {
/* 利用绝对定位让灰色涂层与刮卡结果重叠 */
position: absolute;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 100%;
font-size: 32px;
text-align: center;
line-height: 160px;
background-color: #fcfcfc;
}
</style>
</head>
<body>
<div class="card-body">
<!-- 灰色涂层 -->
<canvas class="canvas">sorry, 浏览器不支持canvas</canvas>
<!-- 刮卡结果 -->
<div class="gift">谢谢参与</div>
</div>
<script>
// 设置是否擦除状态和刷子图片
var isErasering = false,
lastPoint,
brush = new Image();
brush.src = './shuazi.png';
// 获取canvas并设置其宽高
let canvas = document.querySelector('.canvas'),
card = document.querySelector('.card-body');
canvas.width = card.offsetWidth;
canvas.height = card.offsetHeight;
let ctx = canvas.getContext('2d');
// 绘制涂层
function drawCanvas() {
ctx.save();
ctx.beginPath();
ctx.fillStyle = '#e5e5e5';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'red';
ctx.font = '24px "微软雅黑"';
ctx.fillText(
'请开始刮奖',
canvas.width / 2 - 64,
canvas.height / 2 + 4
);
ctx.closePath();
ctx.restore();
}
// 获取鼠标或者手指当前点的位置
function getPointPosition(e, canvas) {
let mx,
my,
offsetX = 0,
offsetY = 0;
if (canvas.offsetParent !== null) {
// 由于canvas刚开始是绝对定位,其offsetLeft和offsetTop为0,需要不断向上寻找其父级,
// 计算父级的offsetLeft和offsetTop,直到向上寻找到body元素,因为body的offsetParent为null
do {
offsetX += canvas.offsetLeft;
offsetY += canvas.offsetTop;
} while ((canvas = canvas.offsetParent));
}
// 鼠标在页面中的坐标减去canvas在页面中的坐标就是鼠标在canvas中的坐标
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
return {
x: mx,
y: my,
};
}
// 计算从鼠标移动开始到结束时点之间的距离
function distance(point1, point2) {
return Math.sqrt(
Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2)
);
}
// 计算从鼠标移动开始到结束时两点之间与x轴的夹角、
function angle(point1, point2) {
return Math.atan2(point2.x - point1.x, point2.y - point1.y);
}
// 鼠标按下或手指触摸开始时事件
function moveStart(e) {
isErasering = true;
lastPoint = getPointPosition(e, canvas);
}
// 鼠标移动或手指滑动时事件
function move(e) {
if (!isErasering) {
return;
}
var currentPoint = getPointPosition(e, canvas);
// console.log(currentPoint)
var dist = distance(lastPoint, currentPoint);
var ang = angle(lastPoint, currentPoint);
var x;
var y;
// 计算并绘制鼠标或手指移动时的实时路径
for (var i = 0; i < dist; i++) {
x = lastPoint.x + Math.sin(ang) * i - 25;
y = lastPoint.y + Math.cos(ang) * i - 25;
// destination-out效果是将源图像(刷子图案)绘制到目标图像(灰色涂层)上,源图像是透明的
ctx.globalCompositeOperation = 'destination-out';
// 在鼠标或手指移动过的地方绘制刷子图案
// console.log(ctx.drawImage);
ctx.drawImage(brush, x, y);
}
lastPoint = currentPoint;
handleFilledPercentage(getFilledPercentage());
}
// 鼠标或手指松开时事件
function moveEnd(e) {
isErasering = false;
}
// 计算已经刮过的区域占整个区域的百分比
function getFilledPercentage() {
let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
// imgData.data是个数组,存储着指定区域每个像素点的信息,数组中4个元素表示一个像素点的rgba值
let pixels = imgData.data;
let transPixels = [];
for (let i = 0; i < pixels.length; i += 4) {
// 严格上来说,判断像素点是否透明需要判断该像素点的a值是否等于0,
// 为了提高计算效率,这儿设置当a值小于128,也就是半透明状态时就可以了
if (pixels[i + 3] < 128) {
transPixels.push(pixels[i + 3]);
}
}
return (
((transPixels.length / (pixels.length / 4)) * 100).toFixed(2) + '%'
);
}
// 设置阈值,去除灰色涂层
function handleFilledPercentage(percentage) {
percentage = percentage || 0;
if (parseInt(percentage) > 50) {
// 去除画布方法一:直接将canvas涂层删掉
// canvas.parentNode.removeChild(canvas);
// 去除画布方法二:将canvas涂层设置为透明
ctx.fillStyle = 'rgba(255, 255, 255)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}
// 监听鼠标和touch事件
canvas.addEventListener('mousedown', moveStart, false);
canvas.addEventListener('touchstart', moveStart, false);
canvas.addEventListener('mousemove', move, false);
canvas.addEventListener('touchmove', move, false);
canvas.addEventListener('mouseup', moveEnd, false);
canvas.addEventListener('touchend', moveEnd, false);
drawCanvas();
</script>
</body>
</html>