首先咱們來看一下效果: javascript
說明:在這個案例中,中止位置的輸入範圍是0-7,表明8箇中止位置(順時針排列),而後咱們後臺設置的中獎位置是1。html
8箇中止位置的分佈圖:java
0 | 1(中獎位置) | 2 |
7 | 抽獎 | 3 |
6 | 5 | 4 |
下面是相關的代碼,相信聰明的你必定可以理解!數組
<div id="box">
<div id="header">
<span>中止位置:</span>
<input type="text" value="0" id="txt">
</div>
<div id="comment"><span>輸入值的範圍:0-7,默認中止位置:0</span></div>
<div id="main">
<div class="num"><img src="./xingyun.jpg" alt=""></div>
<div class="num"><img src="./xingyun.jpg" alt=""></div>
<div class="num"><img src="./xingyun.jpg" alt=""></div>
<div class="num"><img src="./xingyun.jpg" alt=""></div>
<div class="num" id="mid"><input type="button" value="抽獎" id="start"></div>
<div class="num"><img src="./xingyun.jpg" alt=""></div>
<div class="num"><img src="./xingyun.jpg" alt=""></div>
<div class="num"><img src="./xingyun.jpg" alt=""></div>
<div class="num"><img src="./xingyun.jpg" alt=""></div>
</div>
</div>
複製代碼
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
}
#box {
width: 100%;
height: 100%;
background-color: silver;
}
#header {
width: 600px;
height: 70px;
margin: 0 auto;
text-align: center;
padding-top: 30px;
background-color: aquamarine;
opacity: 0.65;
}
#header span {
line-height: 35px;
font-size: 35px;
color: black;
}
#header input {
height: 40px;
font-size: 35px;
}
#comment{
width: 600px;
height: 50px;
margin: 0 auto;
color: black;
background-color: aquamarine;
opacity: 0.65;
text-align: center;
font-size: 30px;
}
#main {
width: 600px;
height: 600px;
margin: 0 auto;
}
.num {
width: 200px;
height: 200px;
float: left;
opacity: 0.3;
}
img {
width: 100%;
height: 100%;
}
#mid {
opacity: 0.7;
}
#mid input {
width: 100%;
height: 100%;
background-color: red;
font-size: 40px;
color: aliceblue;
}
複製代碼
//定義一個定時器的句柄
var interval = null;
//定義點擊開始之後,定時器執行的時間間隔
var inTime = 100;
//獲取1-8的div
var divNum = document.getElementsByClassName('num');
//把獲取到的數組從新排序,由於獲得的divNum長度爲9,可是最中間的那個「開始」盒子不須要,並且divL裏面的class對象順序不符合要求
var divList = [];
for (let i = 0; i < 3; i++) {
divList.push(divNum[i])
}
divList[3] = divNum[5];
divList[4] = divNum[8];
divList[5] = divNum[7];
divList[6] = divNum[6]
divList[7] = divNum[3];
//自動轉圈函數
function animation() {
var index = 0;
interval = setInterval(function () {
//divList[index].style.opacity = 1;注意,這句不能寫在這裏,由於在最後,index會等於8,可是divList數組最大下標爲7
if (index > 7) {
index = 0;
divList[7].style.opacity = 0.5;
} else if (index != 0) {
divList[index - 1].style.opacity = 0.5;
}
//給盒子的透明度設置爲1
divList[index].style.opacity = 1;
index++;
}, 1000)
}
//頁面加載之後,先自動轉圈
window.onload = animation;
//爲盒子裏面的「開始」按鈕註冊點擊事件
var inputStart = document.getElementById("start");
var valTxt = document.getElementById("txt");
inputStart.onclick = function () {
//首先判斷用戶輸入的中止位置的值是否合乎格式,默認的位置爲0
if (valTxt.value.length == 1 && parseInt(valTxt.value) >= 0 && parseInt(valTxt.value) <= 7) {
//禁用按鈕
inputStart.disabled="disabled";
inputStart.value = "抽獎中..."
//取消頁面加載之後設置的定時器(也就是取消自動轉圈)
clearInterval(interval);
//先更改全部的盒子透明度
for (let i = 0; i < divList.length; i++) {
divList[i].style.opacity = 0.5;
}
//設置更快的定時器,時間間隔爲inTime=0.1s
var index = 0;
interval = setInterval(function () {
//divList[index].style.opacity = 1;注意,這句不能寫在這裏,由於在最後,index會等於8,可是divList數組最大下標爲7
if (index > 7) {
index = 0;
divList[7].style.opacity = 0.5;
} else if (index != 0) {
divList[index - 1].style.opacity = 0.5;
}
//給盒子的透明度設置爲1
divList[index].style.opacity = 1;
index++;
}, inTime)
//快速轉圈兩秒之後,執行stop函數
//思考一個問題?兩秒之後,快速轉圈還會繼續轉嗎?
//答案:會的,兩秒後執行延時器裏面的操做之後,還會繼續執行定時器裏面的操做
setTimeout(function () {
stop(parseInt(valTxt.value));
}, 2000)
} else {
alert("尊敬的用戶,請正確輸入中止位置的值!");
}
//讓轉動停下來,接收的形參爲中止位置的值
function stop(luckPosition) {
//清除定時器
clearInterval(interval)
//獲得opacity爲1的那個盒子的位置current
var current = -1;
for (let i = 0; i < divList.length; i++) {
if (divList[i].style.opacity == 1) {
current=i;
}
}
//注意:current+1
stopLuck(luckPosition,current+1,inTime,10)//inTime是點擊「開始」之後,定時器執行的時間間隔,大小爲100,也就是轉圈的速度
}
//
function stopLuck(luckPosition,index,time,stepTime) {
//設置一個延時器,0.1s之後執行(傳進來的time=100)
//思考一個問題,爲何這裏也須要設置一個延時器,並且最開始時候,延遲時間time爲傳進來的inTime=100?答案在下面的註釋中!
setTimeout(function () {
//重置opacity
//這裏須要注意兩個問題?
//第一個問題:不明白爲何這裏須要重置opacity,由於在「開始」按鈕註冊點擊事件裏面的定時器函數語句會重置opacity,這裏再重置
//是畫蛇添足,其實這裏重置opacity是爲了在遞歸該函數時候,重置opacity
//第二個問題:第一次執行stopLuck函數的時候(也就是stop最開始調用stopLuck函數的時候),index的值實際上是
//比opacity爲1的那個盒子下標大1,由於傳進來的是:current+1,因此認爲下面這種重置opacity的寫法會致使錯誤,可是重點來了!
//這裏是設置了一個延時器,而且第一次的延遲時間爲time=inTime=0.1s,因此第一次執行stopLuck的時候,opacity爲1的那個盒子其實
//已經繼續轉動一次,因此第一次執行stopLuck函數時候,下面這種寫法沒有錯
if (index > 7) {
index = 0;
divList[7].style.opacity = 0.5;
} else if (index != 0) {
divList[index - 1].style.opacity = 0.5
}
// 當前位置選中狀態
divList[index].style.opacity = 1;
// 若是說當前旋轉時間過短, 或者當前位置不等於中止位置, 遞歸一下,直到旋轉至中止位置
//(注意:第一次的延遲時間爲time=inTime=0.1s)
if (time < 400 || index != luckPosition) {
//思考兩個問題?
//第一個問題,若是index == luckPosition的話,會怎麼樣?
//由於time < 400,仍然也會執行這裏,也就是說,即便當前位置等於中止位置也會執行這裏,爲了是使得速度先變慢。
//而後index會再++直到time>=400而且index==luckPosition再也不執行這裏。
//第二個問題,爲何愈來愈慢?
//在最開始的時候,time=100,stepTime=10,index爲當前opacity爲1盒子的下標,因此執行到這裏,遞歸一下。time值和
//stepTime值變大,那麼stopLuck()裏面的延時器的延遲時間也會變長,從而使得轉圈的速度變慢
//同時index++,延時器裏面重置opacity的代碼會重置opacity,從而達到轉圈的效果
stepTime++;
time += stepTime;
index++;
stopLuck(luckPosition, index, time, stepTime);
} else {
//執行到這裏說明當前位置等於中止位置
//設置一個延時器,爲了使1s後顯示結果
setTimeout(function () {
//這裏咱們後臺手動設置中獎的位置是:1,也就是輸入luckPosition的值爲1時中獎,固然也能夠設置中獎位置爲負數,從而永遠不中獎
if (luckPosition == 1 ) {
alert("恭喜中獎!")
//恢復按鈕
inputStart.disabled=false;
inputStart.value = "抽獎";
animation();
} else {
alert("很遺憾,你沒有中獎!")
//恢復按鈕
inputStart.disabled=false;
inputStart.value = "抽獎";
animation();
}
},1000)
}
},time)
}
}
複製代碼