移动端vue实现刮刮卡
移动端 Vue 实现刮刮卡效果
在移动端实现刮刮卡效果需要结合 Canvas 绘图和触摸事件监听。以下是一个完整的实现方案:
创建 Vue 组件结构
<template>
<div class="scratch-container">
<canvas
ref="canvas"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
></canvas>
<div class="prize-content">{{ prizeText }}</div>
</div>
</template>
初始化 Canvas 和绘图
export default {
data() {
return {
isDrawing: false,
ctx: null,
canvas: null,
prizeText: "恭喜中奖!",
canvasSize: { width: 300, height: 150 }
}
},
mounted() {
this.initCanvas();
},
methods: {
initCanvas() {
this.canvas = this.$refs.canvas;
this.ctx = this.canvas.getContext('2d');
this.canvas.width = this.canvasSize.width;
this.canvas.height = this.canvasSize.height;
// 绘制覆盖层
this.ctx.fillStyle = '#999';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.globalCompositeOperation = 'destination-out';
}
}
}
处理触摸事件
methods: {
handleTouchStart(e) {
e.preventDefault();
this.isDrawing = true;
const pos = this.getTouchPos(e);
this.ctx.beginPath();
this.ctx.moveTo(pos.x, pos.y);
},
handleTouchMove(e) {
if (!this.isDrawing) return;
e.preventDefault();
const pos = this.getTouchPos(e);
this.ctx.lineTo(pos.x, pos.y);
this.ctx.lineWidth = 20;
this.ctx.lineCap = 'round';
this.ctx.lineJoin = 'round';
this.ctx.stroke();
},
handleTouchEnd() {
this.isDrawing = false;
this.checkScratchCompletion();
},
getTouchPos(e) {
const rect = this.canvas.getBoundingClientRect();
return {
x: e.touches[0].clientX - rect.left,
y: e.touches[0].clientY - rect.top
};
}
}
检查刮卡完成度
methods: {
checkScratchCompletion() {
const imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
const pixels = imageData.data;
let transparentPixels = 0;
for (let i = 0; i < pixels.length; i += 4) {
if (pixels[i + 3] === 0) {
transparentPixels++;
}
}
const transparentRatio = transparentPixels / (pixels.length / 4);
if (transparentRatio > 0.6) {
this.$emit('completed');
}
}
}
添加样式
.scratch-container {
position: relative;
width: 300px;
height: 150px;
margin: 0 auto;
}
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: #fff8e1;
font-size: 18px;
color: #ff6d00;
}
优化移动端体验
为提升移动端体验,可以添加以下优化:
// 在 mounted 中添加
document.addEventListener('touchmove', this.preventScroll, { passive: false });
// 在 methods 中添加
preventScroll(e) {
if (this.isDrawing) {
e.preventDefault();
}
},
// 在 beforeDestroy 中移除
beforeDestroy() {
document.removeEventListener('touchmove', this.preventScroll);
}
组件使用示例
<template>
<div>
<h3>刮刮卡</h3>
<scratch-card @completed="handleComplete" />
</div>
</template>
<script>
import ScratchCard from './ScratchCard.vue';
export default {
components: { ScratchCard },
methods: {
handleComplete() {
alert('刮卡完成!');
}
}
}
</script>
这个实现方案包含了完整的移动端触摸事件处理、Canvas绘图逻辑和刮卡完成度检测,可以直接在Vue项目中使用。







