vue实现转盘抽奖
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 属性,通过 rotate 和 skewY 组合实现扇形效果。每个扇形的角度由奖品数量决定。

旋转动画控制
通过 Vue 的响应式数据 rotation 控制旋转角度,结合 CSS 的 transition 实现平滑动画。使用 cubic-bezier 函数实现缓动效果。
中奖逻辑
随机选择奖品后,计算需要旋转的总角度(包含多圈旋转和目标位置)。通过 setTimeout 在动画结束后显示中奖结果。
性能优化
使用 requestAnimationFrame 实现更流畅的动画效果,避免直接修改 CSS 属性导致的性能问题。

扩展功能
-
自定义奖品数量 修改
prizes数组即可调整奖品数量和样式,无需修改其他代码。 -
中奖概率控制 可以为每个奖品添加
probability属性,修改随机选择逻辑实现不同中奖概率。 -
API 接口 抽奖结果可以通过 API 提交到后端,实现完整的抽奖系统。
-
移动端适配 通过媒体查询调整转盘大小,确保在移动设备上正常显示。
通过以上方法,可以快速实现一个基于 Vue 的转盘抽奖组件,并根据实际需求进行功能扩展。






