vue实现刮刮乐
实现刮刮乐效果的基本思路
在Vue中实现刮刮乐效果,可以通过HTML5的Canvas元素结合触摸或鼠标事件来完成。核心原理是利用Canvas绘制蒙层,当用户滑动时擦除部分蒙层,露出底层内容。

创建Vue组件结构
<template>
<div class="scratch-container">
<canvas
ref="canvas"
@mousedown="startScratch"
@mousemove="scratch"
@mouseup="endScratch"
@touchstart="startScratch"
@touchmove="scratch"
@touchend="endScratch"
></canvas>
<div class="prize-content">
<!-- 这里放置被刮开后的内容 -->
<p>恭喜中奖!</p>
</div>
</div>
</template>
初始化Canvas
<script>
export default {
data() {
return {
isDrawing: false,
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 = '#ccc';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.globalCompositeOperation = 'destination-out';
}
}
}
</script>
实现刮擦交互
methods: {
startScratch(e) {
this.isDrawing = true;
this.scratch(e);
},
scratch(e) {
if (!this.isDrawing) return;
const rect = this.canvas.getBoundingClientRect();
let x, y;
if (e.type.includes('touch')) {
x = e.touches[0].clientX - rect.left;
y = e.touches[0].clientY - rect.top;
} else {
x = e.clientX - rect.left;
y = e.clientY - rect.top;
}
// 绘制擦除圆形
this.ctx.beginPath();
this.ctx.arc(x, y, 20, 0, Math.PI * 2);
this.ctx.fill();
},
endScratch() {
this.isDrawing = false;
}
}
添加样式
<style scoped>
.scratch-container {
position: relative;
width: 300px;
height: 150px;
}
canvas {
position: absolute;
top: 0;
left: 0;
touch-action: none; /* 防止触摸滚动 */
}
.prize-content {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #ffeb3b;
}
</style>
高级优化建议
添加擦除比例计算功能,当擦除面积达到一定比例时自动清除剩余蒙层:
methods: {
checkScratchedPercentage() {
const imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
const pixels = imageData.data;
let transparentPixels = 0;
for (let i = 3; i < pixels.length; i += 4) {
if (pixels[i] === 0) transparentPixels++;
}
const percentage = (transparentPixels / (this.canvas.width * this.canvas.height)) * 100;
if (percentage > 60) {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
}
在scratch方法末尾调用该方法:
scratch(e) {
// ...原有代码
this.checkScratchedPercentage();
}
移动端适配要点
- 添加
@touch事件监听器 - 设置CSS属性
touch-action: none防止页面滚动 - 考虑使用
passive: false提高触摸事件响应速度 - 针对高DPI屏幕调整canvas尺寸:
initCanvas() {
// ...原有代码
const dpr = window.devicePixelRatio || 1;
this.canvas.width = container.offsetWidth * dpr;
this.canvas.height = container.offsetHeight * dpr;
this.canvas.style.width = `${container.offsetWidth}px`;
this.canvas.style.height = `${container.offsetHeight}px`;
this.ctx.scale(dpr, dpr);
}
以上实现方案提供了完整的Vue刮刮乐组件,可根据实际需求调整擦除灵敏度、蒙层颜色和底层内容。







