iOS平臺下抽獎程序的設(shè)計與實現(xiàn)

先上效果圖

? ? ? ?上來先一個對不起,標(biāo)題黨了,本來是打算擼一個原生版本的,但是考慮到安全性和可控性,選擇了用h5實現(xiàn),不然出個什么bug中了十個iphone X,這個鍋太重,背不動。gif圖由于被簡書自動加快,真實效果比較平緩正常。

實現(xiàn)

? ? ? ?九宮格抽獎,后臺返回八個獎品信息,排列順序如圖3-1所示,獲取到獎池數(shù)據(jù)后,遍歷數(shù)組,添加八個獎品圖 + 一個按鈕圖進div

for(var i=length;i<=(allNumber);i++){
  if (i == allNumber) {
    $("#checkDivId").append("<img style='background:#FF8082;width:" + onegiftWidth + "px; height:" + onegiftWidth + "px;border-radius: 8px;' src=" + centerCheckimgSrc + " class='checkAction'></img>");
  }else{
    $("#checkDivId").append("<img style='background:#FFFFFF;width:" + onegiftWidth + "px;height:" + onegiftWidth + "px;border-radius: 8px;' src=" +daysJoyAr[i].url +">" +  "</img>");
  }
}

children = $("#checkDivId").children('img');
width = children.eq(0).width() || 0;
height = children.eq(0).height() || 0;

//元素初始化
$("#checkDivId").css({
  position:'relative',
  width:col * width + (col-1) * spacing,
  height:row * height + (row-1) * spacing
});
children.css({
  position:'absolute'
});
            
if(line == 0){
  initOne();
}else{
  initTwo();
}

//初始化函數(shù)
//此時分成4個部分,上、右、下、左
//上: 0  ~  col-1
//右: col ~ col+line
//下: col+line+1 ~ 2*col+line-1
//左: else
//如果只有兩行
//此時分成4個部分,上、右、下、左
            
function initOne(){
    children.each(function(index){
        if(index >=0 && index <= (col-1)){
            $(this).css({
                top:0,
                left: index * width + index * spacing
            });
        }else{
            $(this).css({
                bottom:0,
                right: index%col*width
            });
        }
    });
}

//如果大于兩行
function initTwo(){
    children.each(function(index){
        //col 列數(shù)  lin 除去上下兩行的行數(shù) 此處為1
        if(index >=0 && index <= (col-1)){   //0~2
            $(this).css({
                top:0,
                left: index * width + index * spacing
            });
        }else if(index >= col && index <= (col+line-1)){ //3~3
            $(this).css({
                top:((index+1-col))*(height+spacing),
                right: 0
            });
        }else if(index >= (col+line) && index <= (2*col+line-1)){ //4~6
            $(this).css({
                bottom:0,
                right:(index-((col+line)))*(width+spacing)
            });
        }else if(index == 7){
            $(this).css({ 
                left:0,
                top:(index-(2*col+line-1))*(height+spacing)
            });
        }else{
            $(this).css({ //中心抽獎按鈕
                left:width + spacing,
                top:width + spacing
            });
        }
    });
}
3-1.png

? ? ? ?考慮到安全問題,抽獎結(jié)果肯定是由服務(wù)器返還,所以當(dāng)點擊中間的抽獎按鈕時,調(diào)用后臺抽獎接口,返回抽獎結(jié)果。假設(shè)抽獎轉(zhuǎn)盤轉(zhuǎn)動時間為三秒,在三秒內(nèi)必須拿到中獎獎品,當(dāng)網(wǎng)絡(luò)不順暢,或者后臺程序報錯時,給用戶彈窗,程序異常并強行刷新頁面。
? ? ? ?前端要做的是在拿到結(jié)果后讓轉(zhuǎn)盤停在對應(yīng)的位置上,這一點是關(guān)鍵。簡單的代碼實現(xiàn)如下所示。

//取一個隨機整數(shù)模擬后臺接口返回的中獎獎品id
var random = parseInt(10*Math.random());

//遍歷圖3-1中的獎池數(shù)組,找到對應(yīng)中獎的獎品
for (var giftindex = 0;giftindex < checkJoyArr.length;giftindex++) {
  if (checkJoyArr[giftindex].id == random) {
    winlocalIndex = giftindex;//中獎獎品的索引
    memberPrizeId = random;//中獎獎品的id
    break;
    }
}

動畫效果

? ? ? ?轉(zhuǎn)盤需要經(jīng)歷 加速--->勻速--->減速--->停止 這四個階段。初始位置從索引為0的獎品開始,調(diào)用speedUp()函數(shù),當(dāng)速度到達(dá)某一值時,勻速運動1s,之后減速,減速一圈后,開始找中獎獎品索引,當(dāng)ix == winlocalIndex時(ix為當(dāng)前選中的商品索引),動畫結(jié)束,彈窗提示用戶中獎。幾個重要的函數(shù)如下:

var ix = 0; //初始位置
var stop ;
flg = false; //抽獎是否正在運行
/*
加速度公式
v1 = v0 + a*t;注意加速度的v代表時間
此時的t可以我們自己定義,所以是常量,所以只需要求a的值
*/
//加速
function speedUp(){
  runner(ix);
  if(v <= 120){
    clearTimeout(stop);
    v = 120;
    t = 5.0;                
    uniform(); //跳轉(zhuǎn)到勻速
  }else{
    t++;
    v = v0 + a*t;                   
    stop = setTimeout(speedUp,v);
  }
}
//勻速
function uniform(){
  stop = setTimeout(uniform,v);
  if(t == time/50){
    clearTimeout(stop);
    t = 0.0;    
    speedDown();//跳轉(zhuǎn)到減速
  }else{
    t++;
  }
  runner(ix);   
}
//減速
function speedDown(){
  var stop3 = setTimeout(speedDown,v);
  if(v >= 500){
    v = 500;
    if(ix == winlocalIndex){                    
      children.removeClass('on').eq(ix).addClass('on');
      clearTimeout(stop3);
      setTimeout(function(){
        options.end(winlocalIndex);
        flg = false;
      },300)
      winlocalIndex = 20;
      return;
    }
  }else{
    t++;
    v = v - a*t;
  }
  runner(ix);
}
function runner(i){
  children.removeClass('on').eq(ix).addClass('on');
  i++;
  if(i == allNumber){
    ix = 0;
  }else{
    ix = i;
  }
}

? ? ? ?至此幾個重要的地方基本寫完了,功能不難,就是寫的過程中比較煩,特別是布局,分分鐘想哭。由于項目中業(yè)務(wù)邏輯比這個稍微復(fù)雜了一點。有七天一次免費抽獎,用完免費抽獎機會后才扣金幣,右上角的點擊刷新獎池等,所以,過兩天剝離出一個demo來。

結(jié)語

? ? ? ?這兩天交接工作,不算太忙,準(zhǔn)備好好梳理一下前段時間的幾個h5功能,但是寫的過程中發(fā)現(xiàn),好多東西不知道怎么去描述,接觸h5也已經(jīng)一年時間,特別是前段時間公司立項了幾個小游戲,研究了一段時間的白鷺引擎,看了兩周混合開發(fā)框架weex,也由最開始的抵觸慢慢到接受,技術(shù)終究是要為產(chǎn)品服務(wù)的。
? ? ? ?還有這周末就要飛重慶了,那個我心心念念的地方,不知道前面等待著我的會是什么,希望工作不會太難找。但行好事,莫問前程,祝我好運。。。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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