当前位置:首页 > VUE

vue实现刮刮乐

2026-01-22 16:19:08VUE

实现刮刮乐效果的基本思路

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

vue实现刮刮乐

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

移动端适配要点

  1. 添加@touch事件监听器
  2. 设置CSS属性touch-action: none防止页面滚动
  3. 考虑使用passive: false提高触摸事件响应速度
  4. 针对高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刮刮乐组件,可根据实际需求调整擦除灵敏度、蒙层颜色和底层内容。

vue实现刮刮乐

标签: vue刮刮乐
分享给朋友:

相关文章

vue实现多个tab

vue实现多个tab

Vue 实现多个 Tab 的方法 使用动态组件切换 在 Vue 中可以通过动态组件 <component :is="currentTab"> 结合 v-for 和 v-bind 实现多个…

vue里实现增删改查

vue里实现增删改查

在Vue中实现增删改查 数据初始化 在Vue组件的data中定义初始数据和表单绑定的变量: data() { return { items: [ { id: 1, name:…

vue实现星星

vue实现星星

实现星星评分的Vue组件 使用Vue实现星星评分功能可以通过组件化方式完成,以下是一个完整的实现方案: 模板部分 <template> <div class="star-ra…

vue全选实现

vue全选实现

Vue 全选实现方法 在 Vue 中实现全选功能通常涉及数据绑定和事件处理。以下是几种常见的实现方式: 基础实现方式 <template> <div> <i…

vue实现旋转

vue实现旋转

Vue 实现旋转效果的方法 在 Vue 中实现旋转效果可以通过多种方式完成,以下是几种常见的方法: 使用 CSS 动画 通过 Vue 的 :class 或 :style 绑定 CSS 动画实现旋转效…

django vue实现

django vue实现

Django与Vue.js整合实现方案 Django作为后端框架与Vue.js作为前端框架的整合,可以通过以下方式实现: 分离式开发 前后端完全分离,Django仅提供API接口,Vue.js通过a…