目录
基本需求分析
源代码
运行效果
基本需求分析
有一个由九个小正方形组成的大正方形,类似与一个3*3的矩阵,其中,最中间的小正方形颜色不同用于区分。
为了实现抽奖的效果,我将外层的八个小正方形作为我的抽奖格,其中八个抽奖格中应该有一个格子的颜色不同于其他七个格子,用来表示当前抽中的物品,
每次打开网页时,这个物品的位置应该是随机的
当我开始抽奖时,这个被抽中的物品的颜色就会变成和其他七个格子的颜色一样,它相邻的一个格子的颜色则变为它原本的颜色
就这样不停的变换,达到一个类似“动态”的效果,最后随机停在某个格子后就不再变换,表示为抽中的物品
源代码
<!--
@Author:Oswald
Time: 11.28
Name: HTML实现转盘
-->
<!DOCTYPE html>
<html lang="en">
<head>
<!--基本需求分析-->
<!--
有一个由九个小正方形组成的大正方形,类似与一个3*3的矩阵,其中,最中间的小正方形颜色不同用于区分。
为了实现抽奖的效果,我将外层的八个小正方形作为我的抽奖格,其中八个抽奖格中应该有一个格子的颜色不同于其他七个格子,用来表示当前抽中的物品,
每次打开网页时,这个物品的位置应该是随机的
当我开始抽奖时,这个被抽中的物品的颜色就会变成和其他七个格子的颜色一样,它相邻的一个格子的颜色则变为它原本的颜色
就这样不停的变换,达到一个类似“动态”的效果,最后随机停在某个格子后就不再变换,表示为抽中的物品
-->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--设置转盘的初始样式,本质上就是个九宫格-->
<style>
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
#wheel {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 4px;
width: 300px;
height: 300px;
}
.cell {
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
font-weight: bold;
width: 100%;
height: 100%;
background-color: #999; /* 初始颜色,可以根据需要修改 */
}
#selectedCell{
background-color: #f9f;
cursor: pointer;
}
</style>
<script>
function spinWheel() {
var cells = document.getElementsByClassName('cell');
//随机选择停止的位置,注意要绕过索引4 即中间的格子
do {
selectedCellIndex = Math.floor(Math.random() * 9);
} while (selectedCellIndex === 4);
// 每次启动时重置所有格子颜色
for (var i = 0; i < cells.length; i++) {
if(i==4){
continue;
}
cells[i].style.backgroundColor="#999";
}
/* !!难点就在如何实现“旋转”的效果 !!*/
//随机初始化开始的位置
do {
currentIndex = Math.floor(Math.random() * 9);
} while (currentIndex === 4);
var rotationCount = 0; // 计数器,表示转动的次数
function animate() {
cells[currentIndex].style.background = ''; // 将背景设置为空
cells[currentIndex].style.backgroundSize = '';
// 更新索引 保证它是逆时针旋转 并且绕过最中间的小正方形
// 这里注意索引值是0-8 这一步相当于是人工控制了下一步该往哪走
switch(currentIndex)
{
case 0:currentIndex=3;
break;
case 1:currentIndex=0;
break;
case 2:currentIndex=1;
break;
case 3:currentIndex=6;
break;
case 5:currentIndex=2;
break;
case 6:currentIndex=7;
break;
case 7:currentIndex=8;
break;
case 8:currentIndex=5;
break;
}
// 如果当前格子不是选中的格子,就改变颜色
if (currentIndex !== selectedCellIndex || rotationCount<16) {
cells[currentIndex].style.backgroundColor = '#00f'; // 表示选中的物品
setTimeout(animate, 100); // 0.1秒后继续
// 让轮盘多转几圈,更真实一点,避免出现一开始就停止的情况
// 每转一圈计数器加一
rotationCount++;
// 如果转动的次数超过一定值,可以停止动画,避免无限递归
} else {
cells[currentIndex].style.backgroundColor = '#00f'
// 设置一个定时器,最后一个格子是选中的格子,等待一段时间后弹窗显示抽中的物品
setTimeout(function () {
if(selectedCellIndex<5 && rotationCount>=16){
alert("抽中的物品:" + (selectedCellIndex+1));
}else if(selectedCellIndex>=5 && rotationCount>=16){
alert("抽中的物品:" + (selectedCellIndex));
}
}, 300);
}
}
animate(); // 开始执行
}
</script>
</head>
<body>
<div id="wheel">
<div class="cell" >1</div>
<div class="cell" >2</div>
<div class="cell" >3</div>
<div class="cell" >4</div>
<div class="cell" id="selectedCell" onclick="spinWheel()">抽奖</div>
<div class="cell" >5</div>
<div class="cell" >6</div>
<div class="cell" >7</div>
<div class="cell" >8</div>
</div>
</body>
</html>
运行效果
每次转盘停止后,弹窗提示当前所抽中的物品。
同时,为了更符合真实场景应用,在程序设计的时候就控制了最小的旋转次数,避免碰到转盘刚开始就停止了的情况。