js实现转盘

实现转盘的基本思路
使用HTML5的Canvas或CSS3的旋转动画结合JavaScript实现转盘效果。核心是通过旋转角度计算奖品位置,并添加动画过渡效果。
HTML结构
<div class="wheel-container">
<canvas id="wheel" width="400" height="400"></canvas>
<button id="spin-btn">开始抽奖</button>
</div>
CSS样式
.wheel-container {
position: relative;
width: 400px;
margin: 0 auto;
}
#wheel {
display: block;
margin: 0 auto;
border-radius: 50%;
box-shadow: 0 0 10px rgba(0,0,0,0.2);
}
#spin-btn {
display: block;
margin: 20px auto;
padding: 10px 20px;
background: #ff4757;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
JavaScript实现
const canvas = document.getElementById('wheel');
const ctx = canvas.getContext('2d');
const spinBtn = document.getElementById('spin-btn');
const prizes = ['奖品1', '奖品2', '奖品3', '奖品4', '奖品5', '奖品6'];
const colors = ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF', '#FF9F40'];
let currentAngle = 0;
let spinning = false;
function drawWheel() {
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const radius = Math.min(centerX, centerY) - 10;
const arcAngle = (2 * Math.PI) / prizes.length;
prizes.forEach((prize, index) => {
const startAngle = index * arcAngle;
const endAngle = (index + 1) * arcAngle;
ctx.beginPath();
ctx.moveTo(centerX, centerY);
ctx.arc(centerX, centerY, radius, startAngle, endAngle);
ctx.fillStyle = colors[index];
ctx.fill();
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate(startAngle + arcAngle / 2);
ctx.textAlign = 'right';
ctx.fillStyle = '#fff';
ctx.font = '16px Arial';
ctx.fillText(prize, radius - 20, 5);
ctx.restore();
});
}
function spin() {
if (spinning) return;
spinning = true;
const spinDuration = 3000; // 3秒
const startTime = Date.now();
const startAngle = currentAngle;
const spinAngle = 360 * 5 + Math.random() * 360; // 至少5圈+随机角度
function animate() {
const currentTime = Date.now();
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / spinDuration, 1);
const easeProgress = easeOut(progress);
currentAngle = startAngle + easeProgress * spinAngle;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(currentAngle * Math.PI / 180);
ctx.translate(-canvas.width / 2, -canvas.height / 2);
drawWheel();
ctx.restore();
if (progress < 1) {
requestAnimationFrame(animate);
} else {
spinning = false;
const prizeIndex = Math.floor(((360 - currentAngle % 360) / 360) * prizes.length) % prizes.length;
alert(`恭喜获得: ${prizes[prizeIndex]}`);
}
}
animate();
}
function easeOut(t) {
return 1 - Math.pow(1 - t, 3);
}
drawWheel();
spinBtn.addEventListener('click', spin);
实现要点
- Canvas绘图:使用Canvas API绘制扇形区域和文字,每个扇形代表一个奖品
- 旋转动画:通过
requestAnimationFrame实现平滑旋转动画 - 缓动函数:
easeOut使旋转动画有自然减速效果 - 奖品计算:根据最终停止角度计算中奖奖品
- 防止重复点击:
spinning标志防止动画期间重复触发
扩展功能
- 自定义奖品:修改
prizes数组可添加更多奖品 - 自定义样式:修改
colors数组可改变扇形颜色 - 调整速度:修改
spinDuration和spinAngle可控制旋转时间和圈数 - 添加指针:可在CSS中添加固定指针元素增强视觉效果
这个实现提供了基础的转盘功能,可根据需要进一步扩展动画效果或奖品逻辑。






