当前位置:首页 > 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实现转盘抽奖

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

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

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

vue实现转盘抽奖

扩展功能

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

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

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

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

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

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

相关文章

vue实现图片搜索

vue实现图片搜索

Vue实现图片搜索功能 使用HTML5的File API获取图片 通过<input type="file">元素让用户选择图片文件,使用FileReader对象读取图片数据。 <…

vue实现aop切面

vue实现aop切面

Vue 实现 AOP 切面编程的方法 在 Vue 中实现 AOP(面向切面编程)可以通过多种方式,以下是几种常见的实现方法: 使用 Vue 混入(Mixins) Vue 的混入机制可以用于实现横切…

vue实现多层评论回复

vue实现多层评论回复

Vue 实现多层评论回复 数据结构设计 多层评论通常采用嵌套结构,每个评论对象包含子评论数组。示例数据结构如下: comments: [ { id: 1, content: '父…

vue实现横向导航

vue实现横向导航

vue实现横向导航的方法 使用Flex布局实现横向导航 在Vue中可以通过Flex布局快速实现横向导航。创建一个组件,使用display: flex和flex-direction: row属性使导航项…

vue实现点击页面切换

vue实现点击页面切换

实现点击页面切换功能 在Vue中实现点击页面切换功能,可以通过路由跳转或组件动态渲染两种方式完成。以下是具体实现方法: 使用Vue Router实现页面跳转 安装Vue Router后,在项目中…

vue实现滚动截屏

vue实现滚动截屏

实现滚动截屏的基本思路 滚动截屏通常指对超出可视区域的长页面进行完整截图。在Vue中,可以通过结合DOM操作、Canvas绘制及第三方库实现。以下是具体方法: 使用html2canvas库实现 安装…