「js」記錄一下滾動抽獎邏輯

在實現(xiàn)活動頁的時候經(jīng)常會遇到要寫滾動抽獎游戲的需求,類似如下奇瘦,按順時針滾動:

0 1 2
7 抽獎按鈕 3
6 5 4

思路:根據(jù)定位索引判斷結(jié)束點棘催。

一般情況下,會有一個獎品個數(shù)award_num(比如上圖就是8個)耳标,默認(rèn)的滾動圈數(shù)default_times醇坝,在默認(rèn)滾動圈數(shù)default_times完成后進(jìn)行結(jié)果result定位,所以當(dāng)前累計的滾動次數(shù)interval_times要大于等于默認(rèn)滾動次數(shù)default_times次坡,對結(jié)果定位就是使累計次數(shù)對獎品個數(shù)取余呼猪,如果相同則定位正確:

if(interval_times >= default_times && interval_times % award_num === result) {
    // 定位到結(jié)果獎品
}

完整代碼:

function postLottery() {
    const _this = this;
    let result = -1, // 結(jié)果索引
        interval_index = 0,
        lottery_index = 0, // 當(dāng)前定位索引
        award_num = 8,
        _times = award_num * 2,
        _speed = 100;
    let lotteryInterval = setInterval(roundFunction, _speed);
    function roundFunction() {
        if (result > -1) {
            // ^ 接口產(chǎn)生結(jié)果,判斷并定位結(jié)果
            if (interval_index >= _times && interval_index % award_num === result) {
                clearInterval(lotteryInterval);
                setTimeout(() => {
                    // 展示結(jié)果
                }, 300);
                return;
            }
        }
        lottery_index = lottery_index === award_num - 1 ? 0 : lottery_index + 1;
        interval_index++;
    }
    // 抽獎post請求砸琅,異步獲取結(jié)果result
    $.ajax({
        type: 'POST',
        url: '...',
        dataType: 'json',
        headers: _this.getRequestHeaders(),
        success: function(res) {
            result = res.result; // 請求抽獎結(jié)果
        },
        error: err => {
            showMessage('抽獎失敗', 2000, true);
        }
    });
}

新優(yōu)化:動態(tài)改變滾動速度宋距,提高用戶體驗

然后此時為了更好的用戶體驗需求又來了,為了增加緊張感需要進(jìn)行動態(tài)的改變滾動速度症脂,快要結(jié)束時速度變慢谚赎。
以上圖為例,定位到結(jié)果前4(n)個開始速度變慢摊腋。
思路:在還剩最后一圈時候?qū)Ξ?dāng)前定位進(jìn)行判斷沸版,所以需要在結(jié)果出來之后先計算定位到結(jié)果需要的滾動次數(shù)total_times,需要在結(jié)果前n個開始速度變慢兴蒸,那么在最后一圈的時候需要當(dāng)前是否為前第n個:

if(total_times - interval_times >= award_num && Math.abs(interval_times % award_num - result) === n){
    // 當(dāng)前可以開始改變速度
}

完整代碼:

function postLottery() {
    const _this = this;
    let result = -1,
        init_result = 0, 
        total_interval = 0, // 定位結(jié)果需要的總次數(shù)
        lottery_index = 0,
        interval_index = 0,
        award_num = 8,
        _times = award_num * 2,
        _speed = 100,
        slow_index = 4; // 速度需要變慢的地方
    let lotteryInterval = setInterval(roundFunction, _speed);
    function roundFunction() {
        if (result > -1) {
            if(!init_result) { // ^ 結(jié)果產(chǎn)生時视粮,先計算當(dāng)前累計滾動次數(shù)
                total_interval = roundTotal(interval_index, _times, result);
            }
            init_result = true;
            // ! 產(chǎn)生結(jié)果后判斷需要速度變慢的位置
            // TODO 計算最后一圈
            if((total_interval - interval_index) <= award_num && Math.abs(result - interval_index % award_num) === slow_index) {
                _speed = 300; // 改變速度
                clearInterval(lotteryInterval);
                lotteryInterval = setInterval(roundFunction, _speed);
            }
            // ^ 接口產(chǎn)生結(jié)果
            if (interval_index >= _times && interval_index % award_num === result) {
                clearInterval(lotteryInterval);
                setTimeout(() => {
                  // 展示結(jié)果
                }, 300);
                return;
            }
        }
        lottery_index = lottery_index === award_num - 1 ? 0 : lottery_index + 1;
        interval_index++;
    }
    // & 計算滾動到結(jié)果需要的累計次數(shù)
    function roundTotal(current, _times, result) {
        let total = 0;
        if(current <= _times) {
            total = _times + result;
        } else {
            total = current + Math.abs(award_num - result);
        }
        return total;
    }
    // 抽獎post請求,異步獲取結(jié)果result
    $.ajax({
        type: 'POST',
        url: '...',
        dataType: 'json',
        headers: _this.getRequestHeaders(),
        success: function(res) {
            result = res.result; // 請求抽獎結(jié)果
        },
        error: err => {
            showMessage('抽獎失敗', 2000, true);
        }
    });
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末橙凳,一起剝皮案震驚了整個濱河市蕾殴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岛啸,老刑警劉巖钓觉,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異坚踩,居然都是意外死亡荡灾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來批幌,“玉大人础锐,你說我怎么就攤上這事∮担” “怎么了皆警?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長截粗。 經(jīng)常有香客問我信姓,道長,這世上最難降的妖魔是什么绸罗? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任意推,我火速辦了婚禮,結(jié)果婚禮上从诲,老公的妹妹穿的比我還像新娘左痢。我一直安慰自己靡羡,他們只是感情好系洛,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著略步,像睡著了一般描扯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上趟薄,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天绽诚,我揣著相機(jī)與錄音,去河邊找鬼杭煎。 笑死恩够,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的羡铲。 我是一名探鬼主播蜂桶,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼也切!你這毒婦竟也來了扑媚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤雷恃,失蹤者是張志新(化名)和其女友劉穎疆股,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體倒槐,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡旬痹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片两残。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡羡忘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出磕昼,到底是詐尸還是另有隱情卷雕,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布票从,位于F島的核電站漫雕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏峰鄙。R本人自食惡果不足惜浸间,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吟榴。 院中可真熱鬧魁蒜,春花似錦、人聲如沸吩翻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狭瞎。三九已至细移,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間熊锭,已是汗流浹背弧轧。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留碗殷,地道東北人精绎。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像锌妻,于是被迫代替她去往敵國和親代乃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容