React簡易版老虎機
一直很忙很少有空寫點東西,難得閒下來,還是記錄下作為懷念。關於React看過文件,很多東西還在摸索中。沒想到來到掘金的第一篇文章既然是關於React的,覺得不錯的點個贊,哪裡需要改進還望各路大大指點!。
附錄
-
- ofollow,noindex">DEMO
-
- DEMO中使用styled-component,請自行了解.
-
- 歡迎擴充套件使用.
一、讀前思考,如下圖換做你需要考慮哪些地方?

實際中至少要注意到以下幾點:
-
1、使用者是否有資格參與?(抽獎剩餘次數,是否繫結手機號,實名認證等...)
-
2、點選開始啟動轉盤,同時要做到幾點:
- 1):禁止使用者再次再次點選開始按鈕
- 2):剩餘次數要減少一次
- 3):動畫要由快到慢的緩慢去執行
-
3、何時停下?(由介面控制如:禮物id),既然由介面控制又會出現:
- 1):介面正確返回禮物id在客戶端禮物列表中存在,正常邏輯
- 2):介面正確返回但是禮物id在客戶端列表中不存在
- 2):介面超時
- 3):介面返回錯誤
-
4、如果沒有抽獎限制(只要有次數就能抽獎),至於是先從介面拿要停下的結果還是一邊啟動轉盤同時去拿結果,根據實際應用中適當處理
-
5、轉盤停止需要一個彈框告訴使用者中了什麼
-
6、轉盤未停止再次點選需要給使用者提示資訊
-
7、如果沒資格(沒次數,沒認證...)也需要給使用者提示資訊
二、簡單分析:這裡只展示部分程式碼
- 1、初始化元件狀態和部分引數,React中是當前元件的狀態(state)變化就會觸發render重新渲染元件
constructor(props) { super(props) this.state = { giftList: getGift(), // 一圈的總長度,禮物總數量 stepCount: getGift().length, // 剩餘抽獎次數,介面返回 myCount: 5, // 轉動啟用位置預設:1,動態,可設定(>=1&&<=stepCount) activeIndex: 1,//這裡從1開始對應陣列的下標0 // 最終要停下的位置:介面返回(>=1&&<=stepCount) endStopIndex: 14, // 抽獎是否正在進行中 isDrawing: false, // 轉速分別為最後0,1,2,3,4,5圈的轉速 speed: [336, 168, 84, 42, 42, 42], // 抽獎結果的禮物名字 showDialog: false, gotGift: null, // 訊息提示框 message: null, messageType: null, animationName: null, }; // 開啟轉盤的定時器 this.timer = null; //alert message list this.messageInfo = { success: { message: "恭喜您中獎了!", //提示訊息的進場動畫 animationName: null }, warning: { message: "抽獎進行中,請稍後再試!", animationName: "slideInLeft" }, error: { message: "抽獎次數不足,抓緊去完成任務獲得抽獎資格吧~", animationName: "shake", }, } } 複製程式碼
2、點選開始獲得停下的位置,需要重置的當前狀態。實際中要:從介面獲取禮物id,根據id獲得對應禮物和要停下的位置(1-18)。其實點選開始的時候就知道獲得哪個禮物了~
let {endStopIndex} = 17; let myCount = this.state.myCount - 1; // 開啟轉盤,當前抽獎狀態設定為true正在抽獎中,並準備啟動動畫:startRun this.setState({isDrawing: true, endStopIndex, myCount}, this.startRun); 複製程式碼
3、準備轉動,呼叫只移動一步的方法
startRun() { // 總共需要轉的圈數 let leftRound = this.state.speed.length - 1; this.addOneStep({isContinue: true, leftRound}) } 複製程式碼
4、移動一步的同時需要重置選中狀態,那如何再移動一步?定時器遞迴呼叫該移動一步的方法,注意引數變化(特別是如何讓動畫由快緩慢的變慢),當最後一圈的時候在停在要停的位置。最主要的一部分!
/* * 每次增加一步,滿一圈,總圈數-1同時速度變慢,直到最後一圈停在指定位置 * 直到知道結果,慢慢變慢速度,停在結果那; * 轉盤停到結果值時,重置初始值({isDrawing:false}); * * Function addOneStep * 獎品位置移動一步 * @isContinue{Booleans}是否應該繼續這個定時器 * @leftRound{Number}剩餘幾圈3代表一個無限大的值,因為還不知道結果 */ addOneStep = (params) => { let {activeIndex, stepCount, speed} = this.state; let {isContinue, leftRound} = params; activeIndex += 1; if (isContinue) { // 如果到超過獎品個數,重置為1 if (activeIndex > stepCount) { console.log(`轉了${leftRound}圈`); // 圈數減少的同時轉動的速度要變慢!!!!!! leftRound -= 1; activeIndex = 1; } // 如果已經到最後一圈了且已經到了指定要中獎的位置了就不需要繼續了 if (leftRound === 0 && activeIndex === this.state.endStopIndex) { console.log(`現在停在:${this.state.endStopIndex}`); isContinue = false; } this.setState({activeIndex}); const nextParams = { isContinue, leftRound, }; this.timer = setTimeout(() => { this.addOneStep(nextParams) }, speed[leftRound]);//下一次移動的一步的速度 } else { clearTimeout(this.timer); this.timer = null; let gotGift = this.state.giftList[this.state.endStopIndex - 1]; this.setState({ isDrawing: false, gotGift, showDialog: true, }); this.alertMessage("success") } } 複製程式碼
5、停下之後抽獎結束,彈框獲得提示資訊告訴使用者中了什麼!
三、提示
- 1、有些地方根據實際應用中變化,如禮物個數,開始的位置,轉動速度,轉動圈數等
- 2、鄙人最開始寫的時候動畫由快變慢非常明顯,經高人指點,得出這個有快變慢的緩動效果
- 3、DEMO中用了某直播平臺的禮物圖片如有不適請告知。