vue实现刮奖
Vue 实现刮奖功能
刮奖功能通常涉及遮盖层的擦除效果,可以通过以下步骤实现:
准备画布和遮盖层 使用 HTML5 的 Canvas 元素作为刮奖区域,设置一个遮盖层覆盖在奖品上方。在 Vue 的模板中添加 Canvas 元素:
<template>
<div class="scratch-container">
<canvas ref="scratchCanvas" @mousedown="startScratch" @mousemove="scratch" @mouseup="endScratch"></canvas>
<div class="prize">恭喜中奖!</div>
</div>
</template>
初始化 Canvas
在 Vue 的 mounted 生命周期中初始化 Canvas,设置其大小和遮盖层:
mounted() {
const canvas = this.$refs.scratchCanvas;
canvas.width = 300;
canvas.height = 150;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#ccc';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'destination-out';
}
实现擦除逻辑 添加鼠标事件处理函数,实现擦除效果:

data() {
return {
isScratching: false,
lastX: 0,
lastY: 0
};
},
methods: {
startScratch(e) {
this.isScratching = true;
const rect = e.target.getBoundingClientRect();
this.lastX = e.clientX - rect.left;
this.lastY = e.clientY - rect.top;
},
scratch(e) {
if (!this.isScratching) return;
const canvas = this.$refs.scratchCanvas;
const rect = e.target.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(this.lastX, this.lastY);
ctx.lineTo(x, y);
ctx.strokeStyle = 'rgba(0, 0, 0, 1)';
ctx.lineWidth = 20;
ctx.lineCap = 'round';
ctx.stroke();
this.lastX = x;
this.lastY = y;
},
endScratch() {
this.isScratching = false;
}
}
样式设置 添加必要的 CSS 样式,确保 Canvas 和奖品正确显示:
.scratch-container {
position: relative;
width: 300px;
height: 150px;
}
.scratch-container canvas {
position: absolute;
top: 0;
left: 0;
}
.prize {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
}
移动端适配
对于移动设备,需要添加触摸事件支持:

<canvas
ref="scratchCanvas"
@mousedown="startScratch"
@mousemove="scratch"
@mouseup="endScratch"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="endScratch"
></canvas>
添加触摸事件处理方法:
handleTouchStart(e) {
e.preventDefault();
const touch = e.touches[0];
const canvas = e.target;
const rect = canvas.getBoundingClientRect();
this.startScratch({
target: canvas,
clientX: touch.clientX,
clientY: touch.clientY
});
},
handleTouchMove(e) {
e.preventDefault();
const touch = e.touches[0];
const canvas = e.target;
const rect = canvas.getBoundingClientRect();
this.scratch({
target: canvas,
clientX: touch.clientX,
clientY: touch.clientY
});
}
擦除比例检测
可以添加擦除比例检测,当擦除面积达到一定比例时自动清除全部遮盖层:
checkScratchProgress() {
const canvas = this.$refs.scratchCanvas;
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
let transparentPixels = 0;
for (let i = 3; i < imageData.data.length; i += 4) {
if (imageData.data[i] === 0) {
transparentPixels++;
}
}
const ratio = transparentPixels / (canvas.width * canvas.height);
if (ratio > 0.6) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}
在 scratch 方法末尾调用此方法:
scratch(e) {
// ...原有代码...
this.checkScratchProgress();
}
注意事项
- 确保 Canvas 尺寸与容器尺寸一致,避免拉伸变形
- 调整
lineWidth可以改变擦除痕迹的粗细 - 擦除比例阈值(如0.6)可以根据需求调整
- 对于复杂场景,可以考虑使用第三方库如
scratchcard-js






