Skip to main content

刮刮卡

实现步骤

  1. 创建 canvas 蒙层,监听鼠标和触屏事件
  2. 定义擦除事件,做下节流
  3. 判断刮刮卡完成

核心代码

擦除的关键是 globalCompositeOperation = "destination-out",让绘制的笔触「擦掉」已有像素(变透明),露出下层奖品:

const ctx = canvas.getContext("2d");
// 1. 铺一层灰色蒙层
ctx.fillStyle = "#c0c0c0";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 2. 设置为擦除模式
ctx.globalCompositeOperation = "destination-out";

let isDrawing = false;
function scratch(x, y) {
ctx.beginPath();
ctx.arc(x, y, 20, 0, Math.PI * 2); // 笔触半径 20
ctx.fill();
}

canvas.addEventListener("mousedown", () => (isDrawing = true));
canvas.addEventListener("mouseup", () => (isDrawing = false));
canvas.addEventListener("mousemove", (e) => {
if (!isDrawing) return;
const rect = canvas.getBoundingClientRect();
scratch(e.clientX - rect.left, e.clientY - rect.top); // 注意坐标换算
});

判断刮开完成

getImageData 统计透明像素(alpha = 0)占比,超过阈值(如 50%)就视为刮完,可直接清空整个蒙层:

function getClearPercent() {
const { data } = ctx.getImageData(0, 0, canvas.width, canvas.height);
let cleared = 0;
for (let i = 3; i < data.length; i += 4) {
if (data[i] === 0) cleared++; // alpha 通道
}
return cleared / (data.length / 4);
}

统计像素较耗时,应在 mouseup 时或节流后再算,不要每次 move 都算。

功能要点

  • 画布操作:刮刮卡通常是通过在画布上涂抹来实现效果的。在实现刮刮卡功能时,需要处理画布的绘制、涂抹操作以及刮开后的效果展示。
  • 性能优化:涂抹的效果需要有流畅的交互体验,这就需要考虑到性能优化的问题,尤其是针对移动设备的性能优化。
  • 响应式设计:刮刮卡功能需要能够适配不同屏幕尺寸和设备类型,因此需要考虑响应式设计和移动端适配的问题。
  • 安全性:在刮刮卡中,需要确保用户无法通过非正常手段提前看到刮开后的内容,这需要在实现上考虑安全性。
  • 用户体验:良好的用户体验是实现刮刮卡功能的关键,需要考虑动画效果、触摸交互、反馈等方面,以提供令人满意的体验。

总的来说,实现刮刮卡功能需要综合考虑到画布操作、性能优化、响应式设计、安全性和用户体验等多个方面的技术挑战