当前位置:首页 > VUE

vue实现抽奖

2026-02-10 07:40:45VUE

Vue 实现抽奖功能

基本抽奖逻辑

使用 Vue 的响应式特性管理抽奖状态和数据。定义一个奖品数组,通过随机数生成器选中奖品。

vue实现抽奖

data() {
  return {
    prizes: ['一等奖', '二等奖', '三等奖', '谢谢参与'],
    isRolling: false,
    result: ''
  }
},
methods: {
  startLottery() {
    if (this.isRolling) return
    this.isRolling = true

    // 模拟抽奖过程
    const rollInterval = setInterval(() => {
      this.result = this.prizes[Math.floor(Math.random() * this.prizes.length)]
    }, 100)

    // 3秒后停止
    setTimeout(() => {
      clearInterval(rollInterval)
      this.isRolling = false
      this.showResult()
    }, 3000)
  },
  showResult() {
    alert(`恭喜获得: ${this.result}`)
  }
}

转盘抽奖实现

使用 CSS 动画创建转盘效果,通过旋转角度决定中奖结果。

vue实现抽奖

<template>
  <div class="wheel-container">
    <div 
      class="wheel" 
      :style="{ transform: `rotate(${rotateDegree}deg)` }"
      @click="startSpin"
    ></div>
    <div class="pointer"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      sectors: [
        { text: '一等奖', color: '#FF0000', angle: 30 },
        { text: '二等奖', color: '#00FF00', angle: 90 },
        // 更多奖品...
      ],
      rotateDegree: 0,
      isSpinning: false
    }
  },
  methods: {
    startSpin() {
      if (this.isSpinning) return

      this.isSpinning = true
      const spinDuration = 3000 // 3秒
      const targetRotation = 360 * 5 + this.getRandomPrizeAngle()

      this.rotateDegree = 0
      const startTime = Date.now()

      const animate = () => {
        const elapsed = Date.now() - startTime
        const progress = Math.min(elapsed / spinDuration, 1)
        const easeProgress = this.easeOut(progress)

        this.rotateDegree = easeProgress * targetRotation

        if (progress < 1) {
          requestAnimationFrame(animate)
        } else {
          this.isSpinning = false
          this.showResult()
        }
      }

      animate()
    },
    getRandomPrizeAngle() {
      // 根据概率返回对应奖品角度
      return this.sectors[0].angle // 示例
    },
    easeOut(t) {
      return 1 - Math.pow(1 - t, 3)
    }
  }
}
</script>

<style>
.wheel-container {
  position: relative;
  width: 300px;
  height: 300px;
}
.wheel {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: conic-gradient(
    #FF0000 0 30deg, 
    #00FF00 30deg 120deg,
    /* 更多颜色... */
  );
  transition: transform 3s cubic-bezier(0.17, 0.67, 0.21, 0.99);
}
.pointer {
  position: absolute;
  top: -20px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
  border-top: 30px solid #000;
}
</style>

九宫格抽奖

实现常见的九宫格跑马灯效果抽奖。

data() {
  return {
    gridItems: [
      { id: 1, text: '奖品1', active: false },
      { id: 2, text: '奖品2', active: false },
      // 更多格子...
    ],
    currentIndex: 0,
    targetIndex: 5, // 中奖位置
    speed: 100,
    timer: null
  }
},
methods: {
  startGridLottery() {
    this.resetGrid()
    this.timer = setInterval(() => {
      this.gridItems[this.currentIndex].active = false
      this.currentIndex = (this.currentIndex + 1) % this.gridItems.length
      this.gridItems[this.currentIndex].active = true
    }, this.speed)

    setTimeout(() => {
      this.stopAtTarget()
    }, 2000)
  },
  stopAtTarget() {
    clearInterval(this.timer)
    let steps = 0
    const maxSteps = 8 // 最后跑几圈

    const slowDown = () => {
      steps++
      this.gridItems[this.currentIndex].active = false
      this.currentIndex = (this.currentIndex + 1) % this.gridItems.length
      this.gridItems[this.currentIndex].active = true

      if (steps < maxSteps) {
        this.speed += 50
        setTimeout(slowDown, this.speed)
      } else {
        this.finalizeResult()
      }
    }

    setTimeout(slowDown, this.speed)
  },
  finalizeResult() {
    // 高亮显示中奖格子
    this.gridItems.forEach(item => item.active = false)
    this.gridItems[this.targetIndex].active = true
  }
}

概率控制

为不同奖品设置不同的中奖概率。

getRandomPrize() {
  const probabilities = [
    { prize: '一等奖', chance: 0.01 },
    { prize: '二等奖', chance: 0.1 },
    { prize: '三等奖', chance: 0.2 },
    { prize: '谢谢参与', chance: 0.69 }
  ]

  const random = Math.random()
  let cumulative = 0

  for (const item of probabilities) {
    cumulative += item.chance
    if (random <= cumulative) {
      return item.prize
    }
  }

  return '谢谢参与'
}

注意事项

  1. 抽奖动画需要考虑性能,使用 requestAnimationFrame 替代 setTimeout
  2. 移动端需要添加触摸事件支持
  3. 中奖概率应该在后端计算,前端仅做展示
  4. 重要抽奖需要记录日志并验证结果
  5. 添加开始/结束按钮的状态管理,防止重复点击

标签: vue
分享给朋友:

相关文章

vue伪函数实现

vue伪函数实现

Vue 伪函数实现方法 伪函数(Mock Function)在 Vue 中常用于测试或模拟某些逻辑,以下是几种常见的实现方式: 使用 Jest 的 jest.fn() 在单元测试中,可以通过 Jes…

vue实现文章锚点定位

vue实现文章锚点定位

实现文章锚点定位的方法 在Vue中实现文章锚点定位可以通过多种方式完成,以下是几种常见的方法: 使用原生HTML锚点 通过HTML的id属性和<a>标签的href属性实现锚点跳转。在Vu…

vue实现iframe

vue实现iframe

Vue 中实现 iframe 的方法 在 Vue 项目中,可以通过多种方式实现 iframe 的嵌入。以下是几种常见的方法: 使用原生 HTML iframe 标签 直接在 Vue 组件的模板中使用…

vue实现导出

vue实现导出

Vue 实现导出功能的方法 在 Vue 项目中实现导出功能通常涉及将数据导出为 Excel、CSV 或其他格式。以下是几种常见的实现方式: 使用 xlsx 库导出 Excel 安装 xlsx 库:…

vue实现刷卡

vue实现刷卡

Vue 实现刷卡效果 在 Vue 中实现刷卡效果可以通过 CSS 动画和 Vue 的过渡系统结合完成。以下是一种常见的实现方式: 基础实现方法 安装 Vue 过渡依赖(如果尚未安装): npm i…

vue 实现长按

vue 实现长按

实现长按功能的基本思路 在Vue中实现长按功能,通常需要监听元素的mousedown或touchstart事件,启动一个计时器。当用户按住元素超过设定的时间阈值时,触发长按回调函数。如果在时间阈值内触…