js实现转盘抽奖
实现思路
使用HTML、CSS和JavaScript创建一个转盘抽奖功能。核心是通过CSS动画实现转盘旋转,JavaScript控制旋转时间和停止位置。
HTML结构
<div class="wheel-container">
<div class="wheel"></div>
<button id="spin-btn">开始抽奖</button>
</div>
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);
transform: rotate(0deg);
}
/* 添加奖品扇形区域 */
.wheel::before {
content: '';
position: absolute;
width: 50%;
height: 50%;
background: conic-gradient(
#ff0000 0deg 60deg,
#00ff00 60deg 120deg,
#0000ff 120deg 180deg,
#ffff00 180deg 240deg,
#ff00ff 240deg 300deg,
#00ffff 300deg 360deg
);
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
border-radius: 50%;
}
#spin-btn {
display: block;
margin: 20px auto;
padding: 10px 20px;
background: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
JavaScript逻辑
const wheel = document.querySelector('.wheel');
const spinBtn = document.getElementById('spin-btn');
let canSpin = true;
// 奖品配置
const prizes = ['一等奖', '二等奖', '三等奖', '四等奖', '五等奖', '六等奖'];
const prizeAngles = [30, 90, 150, 210, 270, 330]; // 每个奖品的中心角度
spinBtn.addEventListener('click', () => {
if (!canSpin) return;
canSpin = false;
const randomIndex = Math.floor(Math.random() * prizes.length);
const targetAngle = 360 * 5 + prizeAngles[randomIndex]; // 旋转5圈后停在目标位置
wheel.style.transform = `rotate(${-targetAngle}deg)`;
setTimeout(() => {
alert(`恭喜获得: ${prizes[randomIndex]}`);
canSpin = true;
}, 4000);
});
实现说明
- 使用CSS的conic-gradient创建彩色扇形转盘
- 通过transform和transition实现平滑旋转动画
- 计算随机停止位置时添加多圈旋转效果
- 使用标志位防止重复点击
- 旋转结束后显示中奖信息
扩展功能
如果需要更精确控制,可以改用requestAnimationFrame实现动画:
let startTime;
let startAngle = 0;
const duration = 4000; // 动画持续时间
function spinWheel(targetAngle) {
startTime = null;
startAngle = 0;
function animate(timestamp) {
if (!startTime) startTime = timestamp;
const progress = Math.min((timestamp - startTime) / duration, 1);
const currentAngle = easeOut(progress) * targetAngle;
wheel.style.transform = `rotate(${-currentAngle}deg)`;
if (progress < 1) {
requestAnimationFrame(animate);
} else {
const prizeIndex = Math.floor(((targetAngle % 360) / 360) * prizes.length);
alert(`恭喜获得: ${prizes[prizeIndex]}`);
canSpin = true;
}
}
requestAnimationFrame(animate);
}
function easeOut(t) {
return 1 - Math.pow(1 - t, 3);
}
注意事项
- 确保奖品角度与奖品数量匹配
- 旋转时间不宜过短或过长
- 移动端需要考虑触摸事件
- 可以添加音效增强体验







