【SSD】掘金的抽獎,「拆穿她「,而後實現一個,順便封裝一個庫

這是我參與8月更文挑戰的第12天,活動詳情查看:8月更文挑戰css

前言

關於關於【SSD系列】
前端一些有意思的內容,旨在3-10分鐘裏, 500-1500字,有所獲,又不爲所累。前端

掘金抽獎,不中大獎,本身復原UI, 中一個大獎知足本身,順便封裝一個庫。css3

若是點贊破100,再寫一篇轉盤抽獎的相關文章,並順便封裝一個庫。git

效果演示

PC端

luckDraw_d.gif

模擬移動端

luckDraw_m.gif

源碼

luckDraw 源碼github

  1. 包含封裝庫
  2. 包含UI

抽獎簡析

抽獎嘛,簡單說就是障眼法。 前先後後的動畫都是加強一些體驗,尋求一點刺激罷了,幻想本身能成爲那個大獎得到者。web

常見表現形式

常見的抽獎表現有兩種,九宮格轉盤,轉盤又有轉動指針轉動轉盤兩種。 從實現難度上來講, 轉盤大於九宮格。chrome

通常的實現方式

  1. 九宮格
    間隔的設置背景色或者蒙層,越日後間隔越大。
  2. 轉盤
    1. 純腳本控制:每一個一段時間,轉動轉盤或者指針,越日後,轉動越少。
    2. css動畫: 提早計算旋轉角度好,配合css3, 利用好貝塞爾函數,梭哈。

通常邏輯處理

  1. 動畫先行
    就是先執行動畫,期間去獲取結果,而後決定定格在何處。
  2. 結果先行
    先獲取結果,而後啓動動畫。

掘金站點技術淺析

這裏就客串分析下掘金的技術棧,推薦一款 BuiltWith Technology Profiler的chrome建立,其能分析出網站的採用哪些技術構建。 咱們一看看看掘金的。api

image.png

看看DOm節點熟悉的__nuxtdata-v, 還真是那麼回事。 image.png微信

掘金抽獎簡析

掘金的抽獎屬於典型的九宮格,中間是抽獎的按鈕。markdown

佈局

典型的flex佈局,九個格子,九個turntable-itemdiv,抽獎按鈕採用單獨的lottery樣式標記。

image.png

動畫先行仍是結果先行?

抽獎接口是https://api.juejin.cn/growth_api/v1/lottery/draw,咱們打開控制面板, Network板塊,輸入draw過濾請請求。

執行一次,而後block抽獎請求。

image.png

再次執行,能夠明顯的看到先執行了動畫,因此我推斷是動畫先行,至於真相,他重要嗎?不重要,反正我也抽不中!!!!!!

luckDraw_block.gif

實現思路

咱們採用動畫先行方案,先啓動動畫,中途請求結果,獲得結果後,執行命中動畫。

基本思路

1. 編號
0-n個坑位,九宮格的話,就是0-7個坑位,坑位的東西能夠重複。

image.png

2.啓動動畫
勻速的切換格子,同時請求服務接口。

3. 中獎動畫
收到結果後,計算出命中獎品的編號,並執行減速邏輯。

分離邏輯

基本思路就是這樣子的,爲了通用性,咱們須要多思考一些,抽獎重要的是邏輯,表面的形式重要嗎? 其實並不過重要,因此咱們這裏把抽獎邏輯封裝,提供可變性,並對外提供事件通知。

可變性
可變性通常是經過參數和對外暴露方法來實現的,咱們也不例外。

  1. 格子數,不單單是九宮格,10宮格,12宮格都支持
  2. 起始位置,不必定是從0開始
  3. 起始的時間間隔,以後會愈來愈慢
  4. 至少轉動的次數, 若是接口太快,可能感受沒開始就結束了。
  5. 獲得結果後,咱們的減速動畫邏輯,應該是內置,同時能夠被覆寫。

事件通知

整個過程可能存在的事件:

  1. onStart: // 當開始
  2. onUpdate: // 旋轉一次
  3. onEnded: // 結束
  4. onError: // 異常

咱們把這些整個起來, 大概就是這個樣子了,都很簡單。

var defaultOption = {
        startIndex: 0, // 初始位置
        pits: 8,  // 格子數
        interval: 100, // 初始間隔
        rate: 2.5,  // 係數
        cycle: 5,  //轉動基本次數:即至少須要轉動多少次再進入抽獎環節
        getInterval: null // 自定義旋轉間隔函數
        //onStart: null, // 當開始
        //onUpdate: null, // 旋轉一次
        //onEnded: null, // 結束
        //onError: null // 異常, 好比轉動次數已經達到設定值, 可是沒有設置獎項
    };
複製代碼

使用代碼

工具方法

先封裝兩個添加方法,一個添加選中的class,一個刪除選中的class。

function removeChosenClass() {
    var el = lotteryEl.querySelector('.turntable-item.chosen');
    if (el) {
        el.classList.remove('chosen');
    }
}

function addChosenClass(index){
    lotteryEl.querySelector('.turntable-item.turntable-item-' + index).classList.add('chosen');
}
複製代碼

實例化

Lottery是咱們封裝的邏輯類。

var options = {
};
var lottery = new Lottery(options);
複製代碼

註冊啓動事件和模擬中獎

4號坑位是大獎

var btnStart = document.querySelector(".turntable-box .turntable-item.lottery");
btnStart.addEventListener('click', function () {
    lottery.start();
    setTimeout(() => {
        setPrize();
    }, 800)
})

function setPrize() {
    lottery.setPrize([4]) // 4號坑位是大獎
}

複製代碼

監聽抽獎事件

lottery.onUpdate = function (ins, index, times) {
    removeChosenClass();
    addChosenClass(index);
}

lottery.onEnded = function (ins, index, prizeIndexes) {
    removeChosenClass();
    addChosenClass(index);

    setTimeout(function () {
        dialogEl.classList.remove("hide");
    }, 500)
}
複製代碼

到此爲止,使用代碼完畢,與框架無關。

邏輯庫封裝

邏輯庫的完整代碼位於 抽獎邏輯Lottery.js , 我就不全貼出來,否則違揹我500-1500字的原則了,就貼一張簡單的屬性圖吧。

image.png

小結

是否是很簡單,一切都看起來沒那麼難。

寫在最後

不忘初衷,【SSD系列】,3-5分鐘,500-1000字,有所得,而不爲所累,若是你以爲不錯,你的一讚一評就是我前行的最大動力。

技術交流羣請到 這裏來。 或者添加個人微信 cloud-dirge,一塊兒學習。

相關文章
相關標籤/搜索