纯原生html js实现幸运转盘功能-奖项不重复(javascript小案例)


崧峻
原创
发布时间: 2025-11-08 11:35:41 | 阅读数 0收藏数 0评论数 0
封面
本篇文章介绍如何仅使用 HTML、CSS 和原生 JavaScript,实现一个无需任何框架或第三方库的 网页幸运转盘功能。 转盘采用 九宫格布局,中间为“开始抽奖”按钮,周围八格代表不同奖项。用户点击按钮后,系统会随机选择一个奖项并通过动态高亮动画展示抽奖过程,最终在中奖格上停下。如需要完整代码看本文最后一步
1

创建项目

如果只需要源码可以直接跳转到最后一步

如图1所示创建一个基本html项目,创建好之后如图2所示

2

九宫格效果

  1. 我们先来实现九宫格的效果吧,有两种一种是按照顺序的九宫格如图1所示,一种是一圈的效果如图2所示,我们本期以第一种九宫格为案例进行实现


html部分代码

<body>
<div id="turntable-box">
<div>一等奖</div>
<div>二等奖</div>
<div>三等奖</div>
<div>四等奖</div>
<div id="startBtn">参与游戏<br />赢得大奖</div>
<div>五等奖</div>
<div>六等奖</div>
<div>七等奖</div>
<div>八等奖</div>
</div>
</body>


css部分代码样式


<style type="text/css">

/* 转盘的外层边框 */
#turntable-box {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 15px;
border-radius: 15px;
background-color: #922a21;
position: relative;
width: 510px;
height: 420px;
margin: 0 auto;
padding: 20px;
}

/* 转盘下面的每个模块样式 */
#turntable-box > div {
display: flex;
align-items: center;
justify-content: center;
border-radius: 25px;
width: 160px;
background-color: #f8e7c1;
height: 130px;
text-align: center;
font-size: 25px;
}
</style>


这个就是很简单的一个换行排序 flex布局


如果大家想要一圈形式的布局代码参考如下 其实就是利用了定位让他形成了一圈

#turntable-box .reward:nth-child(1) {
top: 10px;
left: 10px;
}

#turntable-box .reward:nth-child(2) {
top: 10px;
left: 175px;
}

#turntable-box .reward:nth-child(3) {
top: 10px;
left: 340px;
}

#turntable-box .reward:nth-child(4) {
left: 340px;
top: 145px;
}

#turntable-box .reward:nth-child(5) {
left: 340px;
top: 280px;
}

#turntable-box .reward:nth-child(6) {
top: 280px;
left: 175px;
}

#turntable-box .reward:nth-child(7) {
left: 10px;
top: 280px;
}

#turntable-box .reward:nth-child(8) {
left: 10px;
top: 145px;
}
3

美化样式

  1. 图片文件在附件中大家自取,然后把图片放到img目录下
  2. 然后我们把背景图片添加上还有奖项的样式区分开 大标题等等,完整结构代码如图下 效果如图2所示

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>幸运转盘</title>
<style type="text/css">
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
overflow: hidden;
width: 100vw;
height: 100vh;
background: url('img/background.jpg');
/* 背景图片居中 */
background-position: center;
/* 背景图片不重复 */
background-repeat: no-repeat;
}

/* 幸运抽奖的标题图片 */
.draw-title {
z-index: 10;
width: 300px;
transform: translateY(10px);
}

/* 转盘的外层边框 */
#turntable-content {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 5px;
border-radius: 15px;
background-color: #922a21;
position: relative;
width: 510px;
height: 410px;
margin: 0 auto;
padding: 10px;
}

/* 转盘下面的每个模块样式 */
#turntable-content>div {
display: flex;
align-items: center;
justify-content: center;
border-radius: 25px;
width: 160px;
height: 130px;
text-align: center;
font-size: 25px;
}



/* 幸运转盘最外层 */
.draw-turntable-box {
display: flex;
align-items: center;
justify-content: center;
border-radius: 5%;
background: #de4b3f;
height: 500px;
width: 600px;
}

/* 开始抽奖按钮 */
#startBtn {
cursor: pointer;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
white-space: normal;
background-color: #eb5e4a;
color: white;
}
/* 奖项 */
.unselected {
background-color: #f8e7c1;
}
#selected {
background-color: #ee7c45;
}
</style>
</head>
<body>
<img src="./img/draw.jpg" alt="抽奖标题" class="draw-title" />
<div class="draw-turntable-box">
<div id="turntable-content">
<div class="award unselected">一等奖</div>
<div class="award unselected">二等奖</div>
<div class="award unselected">三等奖</div>
<div class="award unselected">四等奖</div>
<div id="startBtn">参与游戏<br />赢得大奖</div>
<div class="award unselected">五等奖</div>
<div class="award unselected">六等奖</div>
<div class="award unselected">七等奖</div>
<div class="award unselected">八等奖</div>
</div>
</div>
</body>
</html>
JPG
background.jpg
115.65KB
JPG
draw.jpg
210.45KB
4

js代码实现-抽奖不重复

实现原理是给开始按钮绑定一个点击事件,然后进行依次变色,最后随机一个没有抽到过的数,然后抽奖成功后把这个数放到一个变量中存储进行去重,完整js代码如下 如图所示

<script type="text/javascript">
// 奖项元素列表
var award = document.getElementsByClassName("award");
// 已经拿到的奖励序号
const lucks = [];
// 是否正在抽奖
let running = false;
// 开始按钮元素
var startBtn = document.getElementById("startBtn");
startBtn.onclick = function() {
// 判断是否正在抽奖
if (running) return;
// 设置为正在抽奖
running = true;
// 可抽取的奖项编号(1~8)排除已经抽取的
const available = Array.from({ length: award.length }, (_, i) => i + 1)
.filter(i => !lucks.includes(i));
// 全部抽完
if (available.length === 0) {
startBtn.innerHTML = "所有奖项已抽完";
running = false;
return;
}
// 随机中奖编号(1~8中未抽的一个)
const target = available[Math.floor(Math.random() * available.length)];
// 随机圈数(2~4圈)
const rounds = Math.floor(Math.random() * 2) + 2;
const totalSteps = rounds * award.length + (target - 1);
let current = 0;
let speed = 60;
function spin() {
const index = current % award.length;
// 重置未中奖项颜色
for (let i = 0; i < award.length; i++) {
if (!lucks.includes(i + 1)) {
award[i].className = "award unselected";
}
}
// 高亮当前
award[index].className = "selected award";
current++;
// 是否结束
if (current > totalSteps) {
lucks.push(index + 1);
startBtn.innerHTML = `恭喜您中了<br>${index + 1}等奖 🎊`;
running = false;
return;
}
// 越接近目标速度越慢
if (totalSteps - current < award.length) {
speed += 40;
}
setTimeout(spin, speed);
}
spin();
};
</script>
5

完整代码

完整代码如下 效果如视频所示 大家也可以自行优化或者不加延迟之类的


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>幸运转盘</title>
<style type="text/css">
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
overflow: hidden;
width: 100vw;
height: 100vh;
background: url('img/background.jpg');
/* 背景图片居中 */
background-position: center;
/* 背景图片不重复 */
background-repeat: no-repeat;
}

/* 幸运抽奖的标题图片 */
.draw-title {
z-index: 10;
width: 300px;
transform: translateY(10px);
}

/* 转盘的外层边框 */
#turntable-content {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 5px;
border-radius: 15px;
background-color: #922a21;
position: relative;
width: 510px;
height: 410px;
margin: 0 auto;
padding: 10px;
}

/* 转盘下面的每个模块样式 */
#turntable-content>div {
display: flex;
align-items: center;
justify-content: center;
border-radius: 25px;
width: 160px;
height: 130px;
text-align: center;
font-size: 25px;
}



/* 幸运转盘最外层 */
.draw-turntable-box {
display: flex;
align-items: center;
justify-content: center;
border-radius: 5%;
background: #de4b3f;
height: 500px;
width: 600px;
}

/* 开始抽奖按钮 */
#startBtn {
cursor: pointer;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
white-space: normal;
background-color: #eb5e4a;
color: white;
}
/* 奖项 */
.unselected {
background-color: #f8e7c1;
}
.selected {
background-color: #ee7c45;
}
</style>
</head>
<body>
<img src="./img/draw.jpg" alt="抽奖标题" class="draw-title" />
<div class="draw-turntable-box">
<div id="turntable-content">
<div class="award unselected">一等奖</div>
<div class="award unselected">二等奖</div>
<div class="award unselected">三等奖</div>
<div class="award unselected">四等奖</div>
<div id="startBtn">参与游戏<br />赢得大奖</div>
<div class="award unselected">五等奖</div>
<div class="award unselected">六等奖</div>
<div class="award unselected">七等奖</div>
<div class="award unselected">八等奖</div>
</div>
</div>
</body>

<script type="text/javascript">
// 奖项元素列表
var award = document.getElementsByClassName("award");
// 已经拿到的奖励序号
const lucks = [];
// 是否正在抽奖
let running = false;
// 开始按钮元素
var startBtn = document.getElementById("startBtn");
startBtn.onclick = function() {
// 判断是否正在抽奖
if (running) return;
// 设置为正在抽奖
running = true;
// 可抽取的奖项编号(1~8)排除已经抽取的
const available = Array.from({ length: award.length }, (_, i) => i + 1)
.filter(i => !lucks.includes(i));
// 全部抽完
if (available.length === 0) {
startBtn.innerHTML = "所有奖项已抽完";
running = false;
return;
}
// 随机中奖编号(1~8中未抽的一个)
const target = available[Math.floor(Math.random() * available.length)];
// 随机圈数(2~4圈)
const rounds = Math.floor(Math.random() * 2) + 2;
const totalSteps = rounds * award.length + (target - 1);
let current = 0;
let speed = 60;
function spin() {
const index = current % award.length;
// 重置未中奖项颜色
for (let i = 0; i < award.length; i++) {
if (!lucks.includes(i + 1)) {
award[i].className = "award unselected";
}
}
// 高亮当前
award[index].className = "selected award";
current++;
// 是否结束
if (current > totalSteps) {
lucks.push(index + 1);
startBtn.innerHTML = `恭喜您中了<br>${index + 1}等奖 🎊`;
running = false;
return;
}
// 越接近目标速度越慢
if (totalSteps - current < award.length) {
speed += 40;
}
setTimeout(spin, speed);
}
spin();
};
</script>
</html>
阅读记录0
点赞0
收藏0
禁止 本文未经作者允许授权,禁止转载
猜你喜欢
评论/提问(已发布 0 条)
评论 评论
收藏 收藏
分享 分享
pdf下载 下载
pdf下载 举报