当前位置:首页 > VUE

vue实现转盘抽奖

2026-01-08 05:33:42VUE

Vue 实现转盘抽奖

基本思路

转盘抽奖的核心是通过 CSS 动画实现旋转效果,Vue 负责控制旋转逻辑和数据绑定。关键点包括转盘扇形区域的绘制、旋转动画的触发与停止、中奖结果的判定。

实现步骤

HTML 结构

<template>
  <div class="wheel-container">
    <div class="wheel" :style="wheelStyle" ref="wheel">
      <div class="wheel-item" v-for="(item, index) in prizes" :key="index" :style="getItemStyle(index)">
        {{ item.name }}
      </div>
    </div>
    <button @click="startRotate" :disabled="isRotating">开始抽奖</button>
  </div>
</template>

CSS 样式

.wheel-container {
  position: relative;
  width: 300px;
  height: 300px;
  margin: 0 auto;
}

.wheel {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  position: relative;
  overflow: hidden;
  transition: transform 4s cubic-bezier(0.17, 0.67, 0.12, 0.99);
}

.wheel-item {
  position: absolute;
  width: 50%;
  height: 50%;
  transform-origin: 100% 100%;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

JavaScript 逻辑

<script>
export default {
  data() {
    return {
      prizes: [
        { name: '奖品1', color: '#FF5252' },
        { name: '奖品2', color: '#FF4081' },
        { name: '奖品3', color: '#E040FB' },
        { name: '奖品4', color: '#7C4DFF' },
        { name: '奖品5', color: '#536DFE' },
        { name: '奖品6', color: '#448AFF' }
      ],
      isRotating: false,
      rotation: 0,
      targetRotation: 0
    }
  },
  computed: {
    wheelStyle() {
      return {
        transform: `rotate(${this.rotation}deg)`
      }
    }
  },
  methods: {
    getItemStyle(index) {
      const angle = 360 / this.prizes.length
      return {
        backgroundColor: this.prizes[index].color,
        transform: `rotate(${angle * index}deg) skewY(${90 - angle}deg)`
      }
    },
    startRotate() {
      if (this.isRotating) return
      this.isRotating = true

      // 随机选择中奖索引
      const prizeIndex = Math.floor(Math.random() * this.prizes.length)
      const anglePerItem = 360 / this.prizes.length

      // 计算目标旋转角度(多转几圈后停在目标位置)
      this.targetRotation = this.rotation + 360 * 5 + (360 - prizeIndex * anglePerItem)

      // 开始动画
      this.animateRotation()

      // 动画结束后处理
      setTimeout(() => {
        this.isRotating = false
        alert(`恭喜获得: ${this.prizes[prizeIndex].name}`)
      }, 4000)
    },
    animateRotation() {
      const startTime = Date.now()
      const duration = 4000

      const animate = () => {
        const now = Date.now()
        const progress = Math.min((now - startTime) / duration, 1)
        const easeProgress = this.easeOut(progress)
        this.rotation = this.rotation + (this.targetRotation - this.rotation) * easeProgress

        if (progress < 1) {
          requestAnimationFrame(animate)
        }
      }

      animate()
    },
    easeOut(t) {
      return 1 - Math.pow(1 - t, 3)
    }
  }
}
</script>

关键点说明

扇形区域绘制 使用 CSS 的 transform 属性,通过 rotateskewY 组合实现扇形效果。每个扇形的角度由奖品数量决定。

旋转动画控制 通过 Vue 的响应式数据 rotation 控制旋转角度,结合 CSS 的 transition 实现平滑动画。使用 cubic-bezier 函数实现缓动效果。

中奖逻辑 随机选择奖品后,计算需要旋转的总角度(包含多圈旋转和目标位置)。通过 setTimeout 在动画结束后显示中奖结果。

性能优化 使用 requestAnimationFrame 实现更流畅的动画效果,避免直接修改 CSS 属性导致的性能问题。

扩展功能

  1. 自定义奖品数量 修改 prizes 数组即可调整奖品数量和样式,无需修改其他代码。

  2. 中奖概率控制 可以为每个奖品添加 probability 属性,修改随机选择逻辑实现不同中奖概率。

  3. API 接口 抽奖结果可以通过 API 提交到后端,实现完整的抽奖系统。

  4. 移动端适配 通过媒体查询调整转盘大小,确保在移动设备上正常显示。

通过以上方法,可以快速实现一个基于 Vue 的转盘抽奖组件,并根据实际需求进行功能扩展。

vue实现转盘抽奖

标签: 转盘vue
分享给朋友:

相关文章

vue登录业务的实现

vue登录业务的实现

实现登录业务的基本流程 在Vue中实现登录业务通常涉及前端界面设计、表单验证、API请求交互、状态管理以及路由控制等环节。以下是核心实现步骤: 登录表单设计与验证 创建包含用户名和密码输入框的登录组…

vue实现cs

vue实现cs

Vue 实现 CS(Client-Side)渲染的常见方法 Vue.js 是一个用于构建用户界面的渐进式框架,默认采用客户端渲染(CSR)。以下是几种常见的实现方式: 使用 Vue CLI 创建项目…

vue实现active

vue实现active

Vue 实现 active 状态的方法 在 Vue 中实现 active 状态可以通过以下几种方式实现,具体取决于使用场景和需求。 使用 v-bind:class 动态绑定类名 通过 v-bind…

vue实现海报

vue实现海报

Vue 实现海报生成方案 使用 html2canvas 库 html2canvas 是一个将 HTML 元素转换为 Canvas 的库,适合将 Vue 组件渲染为海报图片 安装依赖: npm in…

实现vue table

实现vue table

Vue 表格实现方法 基础表格实现 使用 Vue 的 v-for 指令可以快速渲染表格数据。在模板中定义表格结构,通过数据绑定动态生成行和列。 <template> <tabl…

vue翻页实现

vue翻页实现

Vue翻页实现方法 基础分页组件实现 使用v-for和计算属性实现基础分页逻辑: <template> <div> <ul> <li…