- 一个美观的转盘,分为多个奖品区域。
- 一个“开始抽奖”按钮。
- 点击按钮后,转盘开始旋转,并随机停在某个奖品上。
- 旋转结束后,弹出提示,告知用户中奖结果。
- 重要:抽奖过程中,按钮应被禁用,防止用户重复点击。
最终效果预览
第一步:HTML 结构
我们创建转盘的基本结构,转盘本身是一个圆形,被分割成多个扇形区域,我们还需要一个指针来指示中奖位置。

(图片来源网络,侵删)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">jQuery 转盘抽奖</title>
<!-- 引入 jQuery 库 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- 引入我们的 CSS 和 JS 文件 -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>幸运大转盘</h1>
<!-- 转盘容器 -->
<div class="wheel-wrapper">
<!-- 指针 -->
<div class="wheel-pointer"></div>
<!-- 转盘主体 -->
<div class="wheel" id="wheel">
<!-- 奖品区域,使用 span 标签,通过 CSS 定位 -->
<span class="wheel-item" data-prize="0">谢谢参与</span>
<span class="wheel-item" data-prize="1">一等奖</span>
<span class="wheel-item" data-prize="2">二等奖</span>
<span class="wheel-item" data-prize="3">三等奖</span>
<span class="wheel-item" data-prize="4">四等奖</span>
<span class="wheel-item" data-prize="5">五等奖</span>
<span class="wheel-item" data-prize="6">六等奖</span>
<span class="wheel-item" data-prize="7">七等奖</span>
</div>
</div>
<!-- 抽奖按钮 -->
<button id="start-btn" class="start-btn">开始抽奖</button>
</div>
<!-- 中奖结果弹窗 -->
<div id="result-modal" class="modal">
<div class="modal-content">
<span class="close-btn">×</span>
<p>恭喜您!</p>
<h2 id="prize-text"></h2>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
代码解释:
.wheel-wrapper: 转盘和指针的容器,用于相对定位。.wheel-pointer: 指针样式,绝对定位在转盘上方。.wheel: 转盘主体,是一个圆形,我们将通过 CSS 对其内部的.wheel-item进行旋转和定位。.wheel-item: 每个奖品区域。data-prize属性非常重要,它存储了每个奖品的索引,方便 JavaScript 识别。#start-btn: 触发抽奖的按钮。#result-modal: 用于显示中奖结果的一个模态框(弹窗)。
第二步:CSS 样式
样式负责将 HTML 元素美化成我们看到的转盘效果,关键在于使用 transform: rotate() 来旋转每个奖品扇形和整个转盘。
/* style.css */
body {
font-family: 'Arial', sans-serif;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
text-align: center;
}
h1 {
color: #333;
margin-bottom: 30px;
}
/* 转盘外层容器,用于定位指针 */
.wheel-wrapper {
position: relative;
width: 400px;
height: 400px;
margin: 0 auto;
}
/* 转盘主体 */
.wheel {
width: 100%;
height: 100%;
border-radius: 50%;
position: relative;
overflow: hidden;
border: 10px solid #333;
background-color: #fff;
transition: transform 4s cubic-bezier(0.17, 0.67, 0.12, 0.99); /* 平滑的缓动效果 */
}
/* 奖品扇形区域 */
.wheel-item {
position: absolute;
width: 50%;
height: 50%;
transform-origin: right bottom; /* 关键:设置旋转原点为转盘中心 */
text-align: center;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
color: white;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
/* 为每个扇形设置不同的背景色和旋转角度 */
.wheel-item:nth-child(1) { background-color: #FF6B6B; transform: rotate(0deg); }
.wheel-item:nth-child(2) { background-color: #4ECDC4; transform: rotate(45deg); }
.wheel-item:nth-child(3) { background-color: #45B7D1; transform: rotate(90deg); }
.wheel-item:nth-child(4) { background-color: #96CEB4; transform: rotate(135deg); }
.wheel-item:nth-child(5) { background-color: #FECA57; transform: rotate(180deg); }
.wheel-item:nth-child(6) { background-color: #FF9FF3; transform: rotate(225deg); }
.wheel-item:nth-child(7) { background-color: #54A0FF; transform: rotate(270deg); }
.wheel-item:nth-child(8) { background-color: #48DBFB; transform: rotate(315deg); }
/* 指针样式 */
.wheel-pointer {
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 40px solid #e74c3c;
z-index: 10;
}
/* 开始按钮 */
.start-btn {
margin-top: 30px;
padding: 15px 40px;
font-size: 18px;
font-weight: bold;
color: white;
background-color: #e74c3c;
border: none;
border-radius: 50px;
cursor: pointer;
transition: background-color 0.3s, transform 0.2s;
}
.start-btn:hover {
background-color: #c0392b;
}
.start-btn:disabled {
background-color: #95a5a6;
cursor: not-allowed;
}
/* 模态框样式 */
.modal {
display: none; /* 默认隐藏 */
position: fixed;
z-index: 100;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 300px;
text-align: center;
border-radius: 10px;
position: relative;
}
.close-btn {
position: absolute;
right: 15px;
top: 10px;
font-size: 24px;
cursor: pointer;
color: #aaa;
}
.close-btn:hover {
color: black;
}
#prize-text {
color: #e74c3c;
margin-top: 10px;
}
CSS 核心技巧:
.wheel-item的定位: 每个扇形都是position: absolute,我们将其宽高设为 50%,然后通过transform-origin: right bottom;将其旋转的原点设置到转盘的圆心(因为父容器.wheel是relative,right: 0; bottom: 0;就是圆心)。- 扇形旋转: 每个扇形依次旋转
45deg(360° / 8个奖品),第一个奖品rotate(0deg),第二个rotate(45deg),以此类推。 - 转盘旋转: 整个
.wheel元素的旋转将通过 jQuery 的animate或css方法来控制,CSS 中的transition属性确保了旋转过程是平滑的。
第三步:jQuery 逻辑
这是整个抽奖功能的核心,逻辑包括:点击事件、随机生成奖品、计算旋转角度、执行旋转动画、显示结果。

(图片来源网络,侵删)
// script.js
$(document).ready(function() {
// 转盘和按钮的 jQuery 对象
const $wheel = $('#wheel');
const $startBtn = $('#start-btn');
const $modal = $('#result-modal');
const $closeBtn = $('.close-btn');
const $prizeText = $('#prize-text');
// 奖品列表
const prizes = [
'谢谢参与', '一等奖', '二等奖', '三等奖',
'四等奖', '五等奖', '六等奖', '七等奖'
];
// 是否正在旋转中,用于防止重复点击
let isSpinning = false;
// 点击开始按钮
$startBtn.on('click', function() {
// 如果正在旋转,则直接返回
if (isSpinning) {
return;
}
// 标记为旋转中
isSpinning = true;
// 禁用按钮
$startBtn.prop('disabled', true);
// 隐藏上一次的结果弹窗(如果存在)
$modal.hide();
// 1. 随机生成一个奖品索引 (0-7)
const randomPrizeIndex = Math.floor(Math.random() * prizes.length);
// 2. 计算旋转角度
// 基础圈数(至少转3圈)
const baseRotations = 3;
// 每个奖品占据的角度 (360 / 8 = 45度)
const anglePerPrize = 360 / prizes.length;
// 指针指向扇形的中间位置,需要偏移半个扇形的角度 (45 / 2 = 22.5度)
const prizeOffset = anglePerPrize / 2;
// 计算最终旋转角度
// 公式:总圈数 * 360 + (目标奖品索引 * 每个奖品角度) + 偏移角度
// 注意:因为 CSS 的 transform 是顺时针为正,但我们的奖品是逆时针排列的,
// 所以用 360 减去计算出的角度,使其顺时针旋转到正确位置。
let finalAngle = baseRotations * 360 + (randomPrizeIndex * anglePerPrize) + prizeOffset;
finalAngle = 360 - finalAngle; // 调整为顺时针旋转
// 3. 执行旋转动画
// 使用 .css() 直接设置 transform 属性,并利用 CSS transition 实现动画
$wheel.css('transform', `rotate(${finalAngle}deg)`);
// 4. 动画结束后,显示中奖结果
// 4秒后执行(与 CSS 中的 transition 时间一致)
setTimeout(function() {
// 显示中奖信息
$prizeText.text(prizes[randomPrizeIndex]);
$modal.fadeIn(300); // 使用 fadeIn 让弹窗平滑显示
// 重置状态,允许下一次抽奖
isSpinning = false;
$startBtn.prop('disabled', false);
}, 4000); // 4000毫秒 = 4秒
});
// 点击弹窗的关闭按钮或背景,关闭弹窗
$closeBtn.on('click', function() {
$modal.fadeOut(300);
});
// 点击弹窗背景,关闭弹窗
$modal.on('click', function(e) {
// 如果点击的是背景(而不是内容区域),则关闭
if (e.target === this) {
$modal.fadeOut(300);
}
});
});
jQuery 逻辑详解:
-
状态控制 (
isSpinning): 这是一个非常重要的变量,用来防止用户在转盘旋转过程中再次点击按钮,导致逻辑混乱,点击开始后设为true,动画结束后设为false。 -
随机数生成:
Math.random() * prizes.length生成一个 0 到 7 之间的随机浮点数,Math.floor()将其向下取整,得到一个随机的奖品索引。 -
角度计算 (最关键的一步):
(图片来源网络,侵删)baseRotations: 让转盘至少转几圈,增加视觉效果和悬念感。anglePerPrize: 计算每个奖品扇形所占的角度(这里是 45°)。prizeOffset: 指针指向的是扇形的中间,而不是扇形的起始边,所以需要额外加上半个扇形的角度(22.5°),才能让指针准确指向奖品名称。finalAngle: 这是最终的旋转角度,公式是总圈数 * 360 + (目标奖品索引 * 每个奖品角度) + 偏移角度,由于我们设计的 CSS 布局是奖品逆时针排列,而transform: rotate()是顺时针为正,所以我们需要用360 - finalAngle来调整,确保最终停在正确的位置。
-
执行动画:
$wheel.css('transform', 'rotate(...)')直接修改 CSS 属性,由于我们在 CSS 中已经为.wheel设置了transition: transform 4s ...,所以这个改变会自动产生一个持续 4 秒的平滑过渡动画。 -
处理结果:
setTimeout函数在 4 秒后执行,此时旋转动画刚好结束,我们显示中奖弹窗,并将isSpinning重置为false,startBtn重新启用,为下一次抽奖做准备。 -
弹窗交互: 为弹窗的关闭按钮和背景添加了点击事件,让用户可以关闭弹窗。
如何运行
- 将上面的 HTML、CSS、JavaScript 代码分别保存为
index.html、style.css和script.js三个文件。 - 将这三个文件放在同一个文件夹下。
- 用浏览器打开
index.html文件,你就可以看到一个功能完整的转盘抽奖页面了。
你可以根据需要修改奖品列表、颜色、转盘大小等,这个框架为你提供了一个非常灵活和可扩展的基础。
