目录
基本需求分析
源代码
运行效果
基本需求分析
有一个由九个小正方形组成的大正方形,类似与一个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>
复制
运行效果
每次转盘停止后,弹窗提示当前所抽中的物品。
同时,为了更符合真实场景应用,在程序设计的时候就控制了最小的旋转次数,避免碰到转盘刚开始就停止了的情况。