vue实现刮奖
实现刮奖效果的基本思路
在Vue中实现刮奖效果可以通过HTML5的Canvas结合触摸事件完成。核心原理是监听用户手指或鼠标的移动轨迹,将划过区域的涂层擦除,露出底层的中奖信息。
基础代码结构
<template>
<div class="scratch-container">
<canvas
ref="canvas"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@mousedown="handleMouseDown"
@mousemove="handleMouseMove"
></canvas>
<div class="prize-info">{{ prizeText }}</div>
</div>
</template>
初始化Canvas
<script>
export default {
data() {
return {
isDrawing: false,
prizeText: "一等奖",
canvas: null,
ctx: null
}
},
mounted() {
this.initCanvas();
},
methods: {
initCanvas() {
this.canvas = this.$refs.canvas;
this.ctx = this.canvas.getContext('2d');
// 设置canvas尺寸与父容器一致
const container = this.canvas.parentElement;
this.canvas.width = container.offsetWidth;
this.canvas.height = container.offsetHeight;
// 绘制灰色涂层
this.ctx.fillStyle = '#999';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.globalCompositeOperation = 'destination-out';
}
}
}
</script>
处理触摸/鼠标事件
handleTouchStart(e) {
this.isDrawing = true;
this.handleDraw(e.touches[0].clientX, e.touches[0].clientY);
},
handleTouchMove(e) {
if (!this.isDrawing) return;
e.preventDefault();
this.handleDraw(e.touches[0].clientX, e.touches[0].clientY);
},
handleMouseDown(e) {
this.isDrawing = true;
this.handleDraw(e.clientX, e.clientY);
},
handleMouseMove(e) {
if (!this.isDrawing) return;
this.handleDraw(e.clientX, e.clientY);
},
handleDraw(x, y) {
const rect = this.canvas.getBoundingClientRect();
const drawX = x - rect.left;
const drawY = y - rect.top;
this.ctx.beginPath();
this.ctx.arc(drawX, drawY, 20, 0, Math.PI * 2);
this.ctx.fill();
}
样式设置
<style>
.scratch-container {
position: relative;
width: 300px;
height: 150px;
}
canvas {
position: absolute;
top: 0;
left: 0;
touch-action: none;
}
.prize-info {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
background: gold;
}
</style>
高级功能扩展
添加刮开比例检测功能,当刮开面积超过阈值时自动清除全部涂层:
checkScratchProgress() {
const imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
let transparentPixels = 0;
for (let i = 3; i < imageData.data.length; i += 4) {
if (imageData.data[i] === 0) transparentPixels++;
}
const scratchPercent = transparentPixels / (imageData.width * imageData.height);
if (scratchPercent > 0.6) {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
在handleDraw方法末尾调用此检测方法:
handleDraw(x, y) {
// ...原有绘制代码...
this.checkScratchProgress();
}
注意事项
- 移动端需要添加
touch-action: none样式防止页面滚动 - 考虑添加重置功能,允许用户重新刮奖
- 涂层颜色和擦除效果可以通过调整Canvas属性自定义
- 对于复杂场景,可以考虑使用第三方库如scratchcard.js







