当前位置:首页 > 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>

高级优化建议

添加擦除比例计算功能,当擦除面积达到一定比例时自动清除剩余蒙层:

vue实现刮刮乐

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 页签实现

Vue 页签实现方法 在 Vue 中实现页签功能通常涉及动态组件、路由或状态管理。以下是几种常见的实现方式: 使用动态组件 通过 Vue 的 <component> 动态组件结合 v-f…

vue实现计时

vue实现计时

Vue 实现计时功能 在 Vue 中实现计时功能可以通过多种方式完成,以下是几种常见的方法: 使用 setInterval 实现基础计时器 通过 setInterval 和 clearInterva…

实现vue组件

实现vue组件

Vue 组件的基本实现 Vue 组件是 Vue.js 的核心特性之一,允许将 UI 拆分为独立、可复用的模块。以下是实现 Vue 组件的几种方式: 单文件组件 (SFC) 使用 .vue 文件格式,…

vue实现拍照

vue实现拍照

Vue实现拍照功能 在Vue中实现拍照功能通常需要结合浏览器的MediaDevices API和Canvas元素。以下是具体实现方法: 安装依赖(可选) 如果需要更简单的封装,可以安装vue-web…

vue实现接口

vue实现接口

在 Vue 中实现接口请求 Vue 本身不直接提供 HTTP 请求功能,通常需要借助第三方库如 axios 或 fetch 来实现接口请求。以下是几种常见方法: 使用 axios 发送请求 安装 a…

vue实现list

vue实现list

Vue 实现列表渲染 在 Vue 中,可以使用 v-for 指令来渲染列表。v-for 指令基于一个数组或对象来渲染一个列表,可以遍历数组或对象的属性。 基本列表渲染 <template>…