当前位置:首页 > VUE

移动端vue实现刮刮卡

2026-01-22 17:48:09VUE

移动端 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;
}

优化移动端体验

为提升移动端体验,可以添加以下优化:

移动端vue实现刮刮卡

// 在 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项目中使用。

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

相关文章

vue实现中台

vue实现中台

Vue 实现中台系统的关键步骤 技术选型与基础搭建 使用 Vue 3(Composition API)或 Vue 2(Options API)作为前端框架,搭配 Vue Router 实现路由管理,V…

vue 实现tabs

vue 实现tabs

Vue 实现 Tabs 组件的方法 使用动态组件和 v-for 在 Vue 中实现 Tabs 可以通过动态组件和 v-for 指令结合完成。定义一个 tabs 数组,包含每个标签的标题和对应的组件。…

vue实现mui

vue实现mui

使用 Vue 实现 MUI(Material-UI)风格的界面 Vue 本身不直接提供 MUI(Material Design)组件,但可以通过集成第三方库或手动实现来达到类似效果。以下是几种常见方法…

vue拖动实现

vue拖动实现

实现 Vue 拖动功能的方法 使用 HTML5 拖放 API 在 Vue 中可以利用 HTML5 的原生拖放 API 实现拖动功能。通过 draggable 属性标记可拖动元素,结合 @dragsta…

vue实现按钮

vue实现按钮

Vue 实现按钮的方法 使用原生 HTML 按钮 在 Vue 模板中可以直接使用 HTML 的 <button> 元素,通过 v-on 或 @ 绑定点击事件。 <template&…

vue实现keepalive

vue实现keepalive

Vue 中实现 keep-alive 在 Vue 中,keep-alive 是一个内置组件,用于缓存动态组件或组件的状态,避免重复渲染和销毁。以下是实现 keep-alive 的几种方法: 基本用法…