当前位置:首页 > VUE

vue实现刮奖

2026-02-17 18:31:10VUE

实现刮奖效果的基本思路

在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();
}

注意事项

  1. 移动端需要添加touch-action: none样式防止页面滚动
  2. 考虑添加重置功能,允许用户重新刮奖
  3. 涂层颜色和擦除效果可以通过调整Canvas属性自定义
  4. 对于复杂场景,可以考虑使用第三方库如scratchcard.js

vue实现刮奖

标签: vue
分享给朋友:

相关文章

vue实现文件下载

vue实现文件下载

使用 a 标签下载文件 通过动态创建 a 标签并触发点击事件实现文件下载。适用于直接下载服务器上的静态文件或 Blob 数据。 downloadFile(url, fileName) { c…

vue实现签名

vue实现签名

实现Vue签名功能的步骤 安装签名库 使用vue-signature库可以快速实现签名功能。通过npm或yarn安装: npm install vue-signature --save # 或 ya…

vue无限菜单怎么实现

vue无限菜单怎么实现

实现 Vue 无限菜单的方法 递归组件实现嵌套菜单 使用 Vue 的递归组件特性可以轻松实现无限级嵌套菜单。通过组件调用自身的方式处理嵌套数据。 <template> <ul…

vue实现效果

vue实现效果

以下是Vue实现常见效果的几种典型方法,分为不同场景说明: 数据绑定与响应式更新 使用v-model实现表单双向绑定: <template> <input v-model="…

vue 实现列表

vue 实现列表

Vue 实现列表的方法 在 Vue 中实现列表通常使用 v-for 指令,结合数组或对象数据渲染动态列表。以下是几种常见的实现方式: 基础列表渲染 使用 v-for 指令遍历数组,渲染列表项。ite…

实现vue框架

实现vue框架

Vue框架的基本实现 Vue是一个渐进式JavaScript框架,用于构建用户界面。以下是实现Vue框架的基本步骤: 安装Vue 通过CDN引入Vue是最简单的方式: <script s…