uniapp+vue2 大转盘如何实现
在uniapp+vue2项目中,想实现一个大转盘抽奖功能,但不太清楚具体怎么操作。请问如何用canvas或CSS3实现转盘的旋转动画?需要哪些关键步骤?怎么控制转盘停止在指定奖品位置?求一个完整的实现思路或示例代码。
2 回复
使用uni-app + Vue2实现大转盘:
- 使用canvas绘制转盘和指针
- 定义奖品数组,计算每个奖品角度
- 使用CSS3动画实现旋转效果
- 通过Math.random()随机生成中奖结果
- 监听touchstart/touchend事件控制开始/停止
- 使用uni.createAnimation()实现平滑停止动画
核心代码:
rotate() {
this.animation.rotate(3600).step()
this.animationData = this.animation.export()
}
在 UniApp + Vue2 中实现大转盘功能,可以通过以下步骤完成:
1. 页面布局
使用 view 和 CSS 绘制转盘和指针,奖品区域用圆形分割。
<template>
<view class="wheel-container">
<!-- 转盘 -->
<view class="wheel" :style="wheelStyle" @click="startRotate">
<!-- 奖品区块 -->
<view v-for="(item, index) in prizes" :key="index" class="prize-item" :style="getItemStyle(index)">
{{ item.name }}
</view>
</view>
<!-- 指针 -->
<view class="pointer"></view>
</view>
</template>
2. 数据与样式
定义奖品数据和转盘样式,计算每个奖品区块的旋转角度。
export default {
data() {
return {
prizes: [
{ name: '奖品1' },
{ name: '奖品2' },
{ name: '奖品3' },
{ name: '奖品4' },
{ name: '奖品5' },
{ name: '奖品6' }
],
rotating: false,
resultIndex: 0 // 指定停止的奖品索引
}
},
computed: {
wheelStyle() {
return {
transform: `rotate(${this.rotateDeg}deg)`,
transition: `transform ${this.duration}s ease-out`
}
}
},
methods: {
getItemStyle(index) {
const angle = 360 / this.prizes.length;
return {
transform: `rotate(${angle * index}deg)`,
'transform-origin': 'center center'
}
}
}
}
3. 旋转动画
通过改变 rotateDeg 触发 CSS 过渡动画,计算停止角度。
methods: {
startRotate() {
if (this.rotating) return;
this.rotating = true;
// 随机选择奖品(或根据后端结果)
this.resultIndex = Math.floor(Math.random() * this.prizes.length);
// 计算旋转角度(多转几圈增加效果)
const anglePerItem = 360 / this.prizes.length;
const stopAngle = 3600 - (anglePerItem * this.resultIndex); // 基础圈数 + 停止位置
this.rotateDeg = stopAngle;
this.duration = 5; // 动画持续时间
// 动画结束后重置状态
setTimeout(() => {
this.rotating = false;
uni.showToast({
title: `恭喜获得:${this.prizes[this.resultIndex].name}`,
icon: 'none'
});
}, this.duration * 1000);
}
}
4. CSS 样式
.wheel-container {
position: relative;
width: 300px;
height: 300px;
margin: 50px auto;
}
.wheel {
width: 100%;
height: 100%;
border-radius: 50%;
background: conic-gradient(
red, yellow, green, blue, purple, orange
);
position: relative;
overflow: hidden;
}
.prize-item {
position: absolute;
width: 50%;
height: 50%;
left: 50%;
top: 0;
transform-origin: left bottom;
text-align: center;
line-height: 150px;
}
.pointer {
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 20px solid #000;
}
关键点说明:
- 转盘绘制:使用
conic-gradient背景或绝对定位元素实现扇形分割 - 动画控制:通过改变
transform: rotate()并设置transition实现平滑旋转 - 停止位置:通过计算目标奖品对应的角度确定停止位置
- 交互限制:旋转过程中禁用点击防止重复触发
实际项目中需要根据奖品数量调整角度计算,并可以接入后端 API 获取抽奖结果。

