当前位置:首页 > 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 实现递归组件的方法 在 Vue 中实现递归组件通常用于处理树形结构数据(如菜单、评论列表、文件目录等)。以下是具体实现方法: 定义递归组件 通过 name 选项让组件可以递归调用自身:…

vue课程实现

vue课程实现

Vue 课程实现方案 课程内容设计 Vue课程应从基础到高级逐步展开,涵盖Vue核心概念、组件化开发、状态管理、路由、构建工具等。基础部分包括Vue实例、模板语法、计算属性和侦听器。中级部分深入组件通…

vue实现幻灯

vue实现幻灯

Vue实现幻灯片的基础方法 使用Vue实现幻灯片功能可以通过多种方式完成,以下是几种常见方案: 方案一:基于Vue的过渡动画 通过Vue的<transition>或<transit…

vue实现权限

vue实现权限

Vue 实现权限管理的方法 在 Vue 项目中实现权限管理通常涉及路由控制、按钮权限和接口权限。以下是几种常见的实现方式: 路由权限控制 通过动态路由的方式,根据用户权限加载不同的路由配置。可以使用…

vue实现梯形

vue实现梯形

在Vue中实现梯形效果,可以通过CSS的transform属性或clip-path属性来实现。以下是几种常见的实现方法: 使用CSS transform实现梯形 通过CSS的transform: s…

vue实现指引

vue实现指引

Vue 实现指引功能 Vue 中实现指引功能可以通过多种方式完成,常见的有使用第三方库或自定义实现。以下是几种常见方法: 使用第三方库(如 driver.js) 安装 driver.js: np…