<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      抽獎動畫 - lao虎機抽獎

      本文介紹一個lao虎機抽獎動畫的實現,lao虎機抽獎在各類商家營銷活動中非常常見,這里主要介紹動畫的實現過程,其他細節不做詳細分析。

      ps:lao虎機是敏感詞,博客園的富文本和markdown編輯器都限制不允許出現,所以文章中的“老”字用拼音代替。

      1. 需求

      UI給到的藍湖如下截圖1
      image
      圖1

      • 三欄圖片,每欄圖片是一樣的,都包含所有的獎品圖片。
      • 點擊抽獎三欄圖片從左到右依次開始上下滾動,從慢到塊,滾動幾輪后根據抽獎結果固定圖片位置。
      • 如果中獎三欄顯示同一張獎品圖片,否則隨機顯示三張獎品圖片。最后彈出抽獎結果彈框。

      2. 整體思路

      2.1 滾動

      說到滾動,首先想到的是scroll,但是scroll會有滾動條出現。并且需求要求先滾動幾輪,這個使用scroll的話我暫時想不出什么好的辦法。
      然后想到可以使用background-img結合background-repeat,background-position-y來實現這個功能,簡單說就不斷地修改背景圖片的background-position-y,并且設置背景重復顯示,這樣看起來就是獎品圖片在滾動了。

      2.2 jquery動畫

      雖然可以使用css中的animation動畫來讓背景滾動,但是這里有個問題,在開始滾動圖片同要去請求接口,在接口有了結果之后要根據結果來固定圖片位置,使用keyframe的話要動態設置關鍵幀,這也很麻煩。
      其實jquery提供的api來修改元素的尺寸信息,和尺寸相關的都可以使用jquery動畫。參考jquery文檔如下:

      所有用于動畫的屬性必須是數字的,除非另有說明;這些屬性如果不是數字的將不能使用基本的jQuery功能。(例如,width, height或者left可以執行動畫,但是background-color不能,除非使用jQuery.Color()插件。)屬性值的單位像素(px),除非另有說明。單位em 和 %需要指定使用。

      另外,背景開始滾動的時候是空轉的,然后等到有抽獎結果之后在原來的background-position-y的基礎上加上一個值,意思再滾動一個距離,固定在獎品圖片上。這個需求和jquery動畫屬性中“相對值”的概念不謀而合。參考下面的jquery引文。

      動畫屬性也可以是一個相對值。如果提供一個以+= 或 -=開始的值,那么目標值就是以這個屬性的當前值加上或者減去給定的數字來計算的。

      等待接口有響應之后還要播放第二個動畫固定獎品,這時就要再播放一個動畫,jquery已經想到了這個問題,所有提供一個done回調方法,如下:

      done
      Type: Function( Promise animation, Boolean jumpedToEnd )
      在動畫完成時執行的函數。 (他的Promise對象狀態已完成). (version added: 1.8)..

      2.3 尺寸問題

      這個動畫中尺寸問題至關重要,因為要對準獎品圖片,尺寸稍有差別,就不容易設置好位置。還有UI給到我們的需求一般都是px,我們的vue項目中使用到“postcss-plugin-px2rem”插件會將px修改成相對的尺寸單位rem。postcss-plugin-px2rem配置如下:

      'postcss-plugin-px2rem': {
        rootValue: 75,
        unitPrecision: 8,
        propWhiteList: [],
        propBlackList: [],
        selectorBlackList: [],
        ignoreIdentifier: false,
        replace: true,
        mediaQuery: false,
        minPixelValue: 3,
        exclude: /vant/i
      }
      

      這里最關鍵的信息是rootValue,設計稿給到的屏幕寬度是750px,這個值被換算成rem是750px/75=10rem,我們代碼中所有的尺寸都會按照這個公式換算成rem。
      然后我們動畫中計算background-position-y的時候也要像這樣換算一下,不然也有可能對不準獎品圖片。

      還有每個獎品圖片在整張背景圖中的次序也要先弄清楚,這里記在一個數組中,最后固定獎品圖片的時候用到。如下:

      prizeList: [
        {pid: 3251, order: 4, code: "HW-AM115", title: "華為半入耳式耳機AM115"},
        {pid: 3231, order: 3, code: "iphone-12", title: "蘋果12 64G綠色"},
        {pid: 3261, order: 2, code: "PMC_iphone12_bhk", title: "浦諾菲-蘋果12水晶保護殼"},
        {pid: 3271, order: 6, code: "PMC-18C", title: "浦諾菲_PMC-18C PD雙口充電器"},
        {pid: 3241, order: 5, code: "SLY_RPB-N16", title: "絲蘭雅_RPB-N16移動電源"},
        {pid: 3221, code: "lost", title: "離大獎就差一點點啦~"}
      ]
      
      

      3.實現過程

      3.1 布局

      這里頁面布局的時候要和UI溝通一個細節,就是背景圖中上下兩個獎品的間隔是最上面一個獎品和頂部中間間隔的兩倍。如下圖2
      image
      圖2
      同理,背景圖中上下兩個獎品的間隔是最下面一個獎品和底部中間間隔的兩倍。如下圖3
      image
      圖3
      最后整張背景圖片如下圖4
      image
      圖4
      這樣滾動起來看上去是一張整體的圖片,而不會出現偏差。三欄布局使用flex來實現,html代碼如下:

      <div class="session">
        <div class="lottory-box">
          <div class="top-fill"></div>
          <div class="tiger tiger-first"></div>
          <div class="tiger tiger-second center"></div>
          <div class="tiger tiger-thired"></div>
          <div class="bottom-fill"></div>
        </div>
        <img src="../assets/images/btn-lottery/btn-draw-lottery.gif" alt="" class="dray-lottery" @click="lotteryClick">
      </div>
      

      css代碼如下:

      .box {
        background: #FFBA76;
        width: 702px;
        margin: 50px auto;
        border-radius: 0px 0px 8px 8px;
        .session {
          padding-top: 22px;
          .lottory-box {
            position: relative;
            width: 664px;
            height: 341px;
            margin: 0 auto;
            background: no-repeat url("../assets/images/bg-lottery-box.png") center/664px 341px;
            border-radius: 8px;
            @include flex(center, center, nowrap, row);
            .tiger-first, .tiger-second, .tiger-thired {
              width: 191px;
              height: 341px;
            }
            //背景圖是同一個圖片,y軸位置不同
            .tiger-first {
              background: url("../assets/images/img-prizelist-border.png") center 62px/191px auto;
            }
            .tiger-second {
              background: url("../assets/images/img-prizelist-border.png") center -167px/191px auto;
            }
            .tiger-thired {
              background: url("../assets/images/img-prizelist-border.png") center -396px/191px auto;
            }
            .center {
              margin: 0 20px;
            }
            .top-fill, .bottom-fill {
              position: absolute;
            }
            .top-fill {
              top: 0;
              width: 660px;
              height: 49px;
              background: linear-gradient(180deg, #D15000 0%, rgba(241, 92, 0, 0) 100%);
              border-radius: 5px 5px 1px 1px;
            }
            .bottom-fill {
              bottom: 0;
              width: 660px;
              height: 49px;
              background: linear-gradient(180deg, rgba(241, 92, 0, 0) 0%, #D15000 100%);
              border-radius: 1px 1px 7px 7px;
            }
          }
          img.dray-lottery {
            width: 549px;
          }
        }
      }
      

      注意初始狀態下,tiger-first,tiger-second,tiger-thired三張背景圖片的定位已近寫在css里面,可以根據情況調整。最后界面效果如下圖5:
      image
      圖5

      3.2 動畫

      布局有了就可以讓它動起來了,首先讓三張背景圖勻速運動起來,最后一起停止。代碼如下:

      lotteryClick() {
        let u = 1145                             //整個背景高度
        let that = this
        //播放動畫
        jQuery(".tiger").each(function(index) {
          let currNum = jQuery(this)
          currNum.animate({backgroundPositionY: "+=" + (u * 3)/75 + 'rem'},
            {easing: "easeInOutCirc", duration: 4000 })
        })
      }
      

      變量u是整個背景圖片的高度,先讓背景滾動3次,然后再除以75得到先對單位rem,這個75就是上面提到的rootValue,這里用到的是'+=',也就是在原有的backgroundPositionY的基礎上再加上一個相對的位移,duration:4000,讓這個動畫整個執行4秒鐘時間。效果如下圖6
      image
      圖6

      需求要求三張圖片從左到有先后滾動,這個可以使用setTimeout(fn, time);來實現,代碼如下:

      //播放動畫
      jQuery(".tiger").each(function(index) {
        let currNum = jQuery(this)
        setTimeout(() => {
          currNum.animate({backgroundPositionY: "+=" + (u * 3)/75 + 'rem'},
            {easing: "easeInOutCirc", duration: 4000 })
        }, index * 300)
      })
      

      利用jquery中each的參數index,代表當前元素的下標,乘以300,這樣第一個立即執行,第二個300毫秒后執行,第三個600毫秒后執行,效果如下圖7:
      image
      圖6

      為了使效果看起來更加逼真,可以讓每個圖片滾動的時間有所差異,第一個最短,最后一個最長,這樣看起來效果更逼真。方法是給一個延遲參數wast,加在配置參數duration上,代碼如下:

      lotteryClick() {
        let u = 1145                             //整個背景高度
        let waste = 800                          //調整動畫時間
        //播放動畫
        jQuery(".tiger").each(function(index) {
          let currNum = jQuery(this)
          setTimeout(() => {
            currNum.animate({backgroundPositionY: "+=" + (u * 3)/75 + 'rem'},
              {easing: "easeInOutCirc", duration: 4000 + index * waste })
          }, index * 300)
        })
      }
      

      效果如下圖7
      image
      圖7

      3.3 請求接口&再動畫

      動畫有了,現在要開始從接口中拿數據來定位獎品了。請求接口和上面的動畫一起執行,這里假定接口響應的時間一定是少于2 * 300 + 4000 + 2 * 800 = 6200ms,一般來說這個時間足夠了,這段時間內動畫空轉。拿到結果后再播放第二個動畫來固定獎品圖片。代碼如下:

      //避免重復點擊
      let that = this
      if (this.disabled) {
        return
      }
      this.disabled = true
      //抽獎
      that.pid = -1
      coc2.drawLottery({actId: actId.lottery}).then(res => {
        // 臨時抽獎
        // res = {"code": "0","data":{"pid":3221}}
        if (res.code == 0) {
          let data = res.data
          this.pid = data.pid
        } else if (res.code == 102002) {
          this.pid = 3221
        } else if (res.code == 303) {
          //拉起登錄
          pullLogin()
        } else {
          this.lotteryMsg = res.message
        }
      })
      

      這里用一個變量pid記住獎品id,然后播放第二個動畫,這時jquery動畫提供了一個done方法執行動畫完成之后的后續操作。代碼如下:

      //播放動畫
      jQuery(".tiger").each(function(index) {
        let currNum = jQuery(this)
        setTimeout(() => {
          currNum.animate({backgroundPositionY: "+=" + (u * 3)/75 + 'rem'},
            {easing: "easeInOutCirc", duration: 4000 + index * waste, done: function() {
              snapToGrid(currNum, index)
            }})
        }, index * 300)
      })
      
      

      snapToGrid方法就是執行第二個動畫了,代碼如下:

      //對齊獎品圖片
      function snapToGrid(domObj, index) {
        let prizeNumber = 0
        //謝謝惠顧
        if ([3221, -1].includes(that.pid)) {
          let result = that.numRand()
          let numArr = (result + '').split('')
          prizeNumber = parseInt(numArr[index])
        } else {
          let prize = that.prizeList.find(p => p.pid == that.pid)
          prizeNumber = prize.order
        }
        domObj.animate({backgroundPositionY:  "+=" + (prizeH * prizeNumber) / 75 + "rem"},
          {easing: "linear", duration: prizeNumber * waste, done: function() {
            if (index == 2) {
              if (that.pid > -1) {
                that.$refs.dialogPrize.popUp(that.pid)
              } else {
                that.$toast(that.lotteryMsg)
              }
              that.disabled = false
            }
          }
          })
      }
      

      這里這里還有個邏輯,如果未中獎(謝謝惠顧),要生成三個不相等的隨機數來讓獎品圖片固定,就是上面的that.numRand(),用它在0,1,2,3,4中隨機選三個來固定獎品圖片。具體方法如下:

      //生成隨機順序
      numRand() {
        let arr = ["0", "1", "2", "3", "4"], res = ""
        for (let i = 0; i < 3; i++) {
          let rnd = Math.floor(Math.random() * arr.length)
          res += arr[rnd]
          arr.splice(rnd, 1)
        }
        return res
      }
      

      還有個地方要注意,一開始的時候默認顯示的獎品圖片是沒有對齊的,在動畫空轉3圈結束后讓然不會對齊,等接口有結果后需要對齊獎品,而prizeList變量中紀錄的order是按照從上到下的次序來的,最后固定到獎品圖片時不可能對準。所以在開始動畫之前要將每張背景圖片固定到起始的位置,代碼如下:

      jQuery(".tiger").css('backgroundPositionY', 0)
      

      最后看一下整體抽獎動畫效果,如下圖8
      image
      圖8

      4.總結

      jquery動畫提供了豐富的功能,能靈活的控制動畫參數和想要的效果,在vue中雖然也提供了動畫功能,但是處理一些復雜的操作用起來不是太理想。

      posted @ 2022-08-12 14:13  nd  閱讀(277)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产激情一区二区三区四区| 四虎国产精品成人免费久久| 午夜精品福利亚洲国产| 97人人超碰国产精品最新| 国产偷自视频区视频| 二区中文字幕在线观看| 久久一日本综合色鬼综合色| 十四以下岁毛片带血a级| 国产jlzzjlzz视频免费看| 农村肥熟女一区二区三区| 少妇爽到呻吟的视频| 秋霞人妻无码中文字幕| 国产资源精品中文字幕| 青青青爽在线视频观看| 亚洲国产午夜福利精品| 久热天堂在线视频精品伊人| 蜜桃av亚洲精品一区二区| 久久久国产成人一区二区| 一区二区三区成人| 国产精品亚洲а∨天堂2021 | 亚洲中文字幕人妻系列| 亚洲丰满熟女一区二区v| 国产视频最新| 国内极度色诱视频网站| a4yy私人毛片| 精品亚洲无人区一区二区| 亚洲精品中文字幕二区| 黄色舔女人逼一区二区三区| 爱啪啪av导航| 日本韩国一区二区精品| 久久精品无码免费不卡| 兴和县| 精品少妇后入一区二区三区 | 国产91麻豆视频免费看| 国产农村妇女毛片精品久久| 中文字幕乱码中文乱码毛片| 精品国产免费一区二区三区香蕉 | 饥渴的熟妇张开腿呻吟视频 | 国产精品色哟哟在线观看| 欧美人与zoxxxx另类| 国产美女被遭强高潮免费一视频 |