js实现大转盘
实现大转盘的基本思路
大转盘是一种常见的抽奖交互形式,核心是通过旋转动画随机停止在某个奖品区域。JavaScript实现需结合CSS动画和随机数生成逻辑。
HTML结构设计
<div class="wheel">
<div class="wheel-items">
<div class="item" data-angle="0">奖品1</div>
<div class="item" data-angle="60">奖品2</div>
<div class="item" data-angle="120">奖品3</div>
<div class="item" data-angle="180">奖品4</div>
<div class="item" data-angle="240">奖品5</div>
<div class="item" data-angle="300">奖品6</div>
</div>
<div class="pointer"></div>
</div>
<button id="spin">开始抽奖</button>
CSS样式设置
.wheel {
position: relative;
width: 300px;
height: 300px;
border-radius: 50%;
overflow: hidden;
}
.wheel-items {
width: 100%;
height: 100%;
position: relative;
transition: transform 4s cubic-bezier(0.17, 0.67, 0.12, 0.99);
}
.item {
position: absolute;
width: 50%;
height: 50%;
left: 50%;
top: 0;
transform-origin: 0 100%;
text-align: center;
padding-top: 20px;
box-sizing: border-box;
}
.pointer {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
background: red;
border-radius: 50%;
z-index: 10;
}
JavaScript核心逻辑
const wheel = document.querySelector('.wheel-items');
const spinBtn = document.getElementById('spin');
const items = document.querySelectorAll('.item');
// 奖品角度配置
const prizes = [
{ angle: 0, name: '奖品1' },
{ angle: 60, name: '奖品2' },
{ angle: 120, name: '奖品3' },
{ angle: 180, name: '奖品4' },
{ angle: 240, name: '奖品5' },
{ angle: 300, name: '奖品6' }
];
spinBtn.addEventListener('click', () => {
// 禁用按钮防止重复点击
spinBtn.disabled = true;
// 随机选择奖品索引
const prizeIndex = Math.floor(Math.random() * prizes.length);
const selectedPrize = prizes[prizeIndex];
// 计算旋转角度(多转几圈后停在目标位置)
const currentRotation = getCurrentRotation();
const targetRotation = 360 * 5 + selectedPrize.angle;
// 设置旋转动画
wheel.style.transform = `rotate(${-targetRotation}deg)`;
// 动画结束后处理
wheel.addEventListener('transitionend', () => {
alert(`恭喜获得: ${selectedPrize.name}`);
spinBtn.disabled = false;
}, { once: true });
});
// 获取当前旋转角度
function getCurrentRotation() {
const style = window.getComputedStyle(wheel);
const matrix = style.transform.match(/^matrix\((.+)\)$/);
if (matrix) {
const values = matrix[1].split(', ');
const a = values[0];
const b = values[1];
return Math.round(Math.atan2(b, a) * (180/Math.PI));
}
return 0;
}
实现要点说明
旋转动画使用CSS的transition属性实现平滑效果,cubic-bezier函数控制缓动曲线使转动更自然。
角度计算需要考虑多圈旋转(如360*5)来增强视觉效果,最终停在目标奖品对应的角度。
transitionend事件监听确保动画完成后执行回调,注意使用{ once: true }参数避免重复绑定。
进阶优化方向
添加音效增强交互体验,中奖概率可配置化,支持动态奖品数据加载。

响应式设计适配不同屏幕尺寸,性能优化避免动画卡顿,增加开始/停止缓冲动画。






