当前位置:首页 > VUE

vue 实现刮奖

2026-01-19 10:40:00VUE

vue 实现刮奖

vue 实现刮奖

Vue 实现刮奖功能

刮奖功能通常通过 Canvas 实现,结合触摸或鼠标事件来擦除涂层。以下是实现步骤和代码示例:

基础实现思路

  1. 使用 Canvas 绘制底层奖品和顶层覆盖层
  2. 监听触摸/鼠标事件,在移动时清除对应区域的像素
  3. 计算擦除面积比例判断是否完成刮奖

具体实现代码

<template>
  <div class="scratch-container">
    <canvas 
      ref="canvas"
      @mousedown="startScratch"
      @mousemove="scratching"
      @mouseup="endScratch"
      @touchstart="startScratch"
      @touchmove="scratching"
      @touchend="endScratch"
    ></canvas>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isDrawing: false,
      ctx: null,
      canvas: null
    }
  },
  mounted() {
    this.initCanvas()
  },
  methods: {
    initCanvas() {
      this.canvas = this.$refs.canvas
      this.ctx = this.canvas.getContext('2d')

      // 设置canvas尺寸
      this.canvas.width = 300
      this.canvas.height = 150

      // 绘制底层内容
      this.drawPrize()

      // 绘制覆盖层
      this.drawCover()
    },

    drawPrize() {
      this.ctx.fillStyle = '#f5f5f5'
      this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)
      this.ctx.font = '20px Arial'
      this.ctx.fillStyle = '#333'
      this.ctx.fillText('恭喜中奖!', 100, 80)
    },

    drawCover() {
      this.ctx.fillStyle = '#999'
      this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)
      this.ctx.globalCompositeOperation = 'destination-out'
    },

    startScratch(e) {
      this.isDrawing = true
      this.scratch(e)
    },

    scratching(e) {
      if (!this.isDrawing) return
      this.scratch(e)
    },

    endScratch() {
      this.isDrawing = false
      this.checkCompletion()
    },

    scratch(e) {
      const rect = this.canvas.getBoundingClientRect()
      const x = (e.clientX || e.touches[0].clientX) - rect.left
      const y = (e.clientY || e.touches[0].clientY) - rect.top

      this.ctx.beginPath()
      this.ctx.arc(x, y, 15, 0, Math.PI * 2)
      this.ctx.fill()
    },

    checkCompletion() {
      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 ratio = transparentPixels / (pixels.length / 4)
      if (ratio > 0.6) {
        this.$emit('completed')
      }
    }
  }
}
</script>

<style>
.scratch-container {
  display: inline-block;
  position: relative;
}

canvas {
  border: 1px solid #ddd;
  border-radius: 8px;
  touch-action: none;
}
</style>

进阶优化方向

  1. 性能优化:对于大尺寸canvas,可以采用分块检测擦除比例
  2. 视觉效果
    • 使用粒子效果增强刮擦感
    • 添加刮擦音效
  3. 响应式设计
    mounted() {
      window.addEventListener('resize', this.resizeCanvas)
      this.initCanvas()
    },
    methods: {
      resizeCanvas() {
        const container = this.$el.parentElement
        this.canvas.width = container.clientWidth
        this.canvas.height = container.clientHeight
        this.initCanvas()
      }
    }
  4. 奖品配置:通过props传入奖品信息,实现动态内容

移动端适配要点

  1. 必须添加touch-action: none样式防止页面滚动
  2. 处理touch事件时需要考虑多点触控情况
  3. 适当增大擦除半径以提高移动端体验

实现时可根据具体需求调整擦除灵敏度、动画效果等参数。核心原理是通过Canvas的绘图API和事件监听实现交互式擦除效果。

标签: vue
分享给朋友:

相关文章

vue实现右下角弹框

vue实现右下角弹框

实现右下角弹框的基本思路 在Vue中实现右下角弹框,通常需要结合CSS定位和Vue的组件化特性。弹框可以通过绝对定位固定在右下角,并通过Vue控制其显示与隐藏。 创建弹框组件 新建一个Vue组件(如…

vue alert实现

vue alert实现

使用 Vue 实现 Alert 组件 在 Vue 中实现 Alert 组件可以通过自定义组件或结合第三方库完成。以下是几种常见方法: 自定义 Alert 组件 创建一个可复用的 Alert 组件,通…

vue实现定时

vue实现定时

Vue 实现定时功能的方法 使用 setInterval 和 clearInterval 在 Vue 中可以通过 setInterval 和 clearInterval 实现定时功能。在组件的 mou…

vue实现mui

vue实现mui

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

vue实现答题

vue实现答题

Vue 实现答题功能 数据结构设计 使用 Vue 的响应式特性管理题目和答案数据。通常需要以下数据结构: data() { return { questions: [ {…

vue实现尺子

vue实现尺子

Vue 实现尺子组件 实现一个尺子组件可以通过 Canvas 或纯 CSS 完成。以下是两种常见实现方式: 使用 Canvas 绘制尺子 通过 Canvas 动态绘制刻度线和数字,适合需要高精度或动…