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

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

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

      抽獎動畫 - 九宮格抽獎

      本文介紹九宮格抽獎功能的實現。

      1.需求

      功能很簡單,來看看高保截圖,如下圖1
      image
      圖1
      需求的功能點如下:

      1. 用戶點擊抽獎,九宮格四周的圖片順時針依次閃爍,空轉幾圈。
      2. 請求接口,等接口有返回后最后對應的獎品閃爍,其他獎品不閃爍。
      3. 登錄后,正中間的抽獎這個小方格點亮,未登錄是灰色,這一點和抽獎無關,本文不做介紹。
      4. 最后彈框彈出抽獎結果。

      2.整體思路

      圖片閃爍,只要圖片所在的dom的背景色和其他不一樣就可以了,如上圖1,5元話費的背景是紅色的。順時針依次閃爍的話只要不斷切換小方格的樣式,當然要按照次序來,需要給小方格排個序,并且正中間這個“抽獎”按鈕不能放在排序中。
      關于依次閃爍,這里想到的是setTimeout方法,并且需要按照一定的順序執行定時器,可以通過控制setTimeout(fn, timeout)的第二個參數來實現這個效果。

      3.實現過程

      3.1 布局

      這里把數據放在一個數組中,包含獎品圖片,獎品ID,獎品中獎后的圖片等。為了布局方便,把中間的抽獎按鈕和兩個謝謝合作也放在數據中。代碼如下:

      luckyDrawList: [
          {
              id: 1,
              prizeId: "1008604",
              active: false,
              imgSrc: require('../../assets/images/blog/lucky1@3x.png'),
              prizeSrc: require("../../assets/images/blog/prize1@2x.png"),
              prizeName: "10元紅包"
          },
          {
              id: 2,
              prizeId: "1008606",
              active: false,
              imgSrc: require('../../assets/images/blog/lucky2@3x.png'),
              prizeSrc: require("../../assets/images/blog/prize2@2x.png"),
              prizeName: "5元紅包"
          },
          {
              id: 3,
              prizeId: "1008602",
              active: false,
              imgSrc: require('../../assets/images/blog/lucky3@3x.png'),
              prizeSrc: require("../../assets/images/blog/prize3@2x.png"),
              prizeName: "50元紅包"
          },
          {
              id: 4,
              prizeId: "1008603",
              active: false,
              imgSrc: require('../../assets/images/blog/lucky4@3x.png'),
              prizeSrc: require("../../assets/images/blog/prize4@2x.png"),
              prizeName: "30元紅包"
          },
          {
              id: 5,
              active: false,
              imgSrc: require('../../assets/images/blog/lucky5@3x.png'),
              disableImg: require('../../assets/images/blog/lucky52@2x.png')
          },
          {
              id: 6,
              active: false,
              imgSrc: require('../../assets/images/blog/lucky67@3x.png'),
              prizeName: "謝謝參與"
          },
          {
              id: 7,
              active: false,
              imgSrc: require('../../assets/images/blog/lucky67@3x.png'),
              prizeName: "謝謝參與"
          },
          {
              id: 8,
              prizeId: "1008601",
              active: false,
              imgSrc: require('../../assets/images/blog/lucky8@3x.png'),
              prizeSrc: require('../../assets/images/blog/prize8@2x.png'),
              prizeName: "100元京東超市紅包"
          },
          {
              id: 9,
              prizeId: "1008605",
              active: false,
              imgSrc: require('../../assets/images/blog/lucky9@3x.png'),
              prizeSrc: require('../../assets/images/blog/prize9@2x.png'),
              prizeName: "一朵鮮花"
          }
      ]
      
      

      九宮格布局可以采用流行的flex布局,給容器設置寬度,高度,然后設置display: flex;并且align-content: space-between;每個格子設置固定寬度高度,這樣也不需要設置margin,自然分布在容器中,代碼如下:

      .lucky-draw-list {
          margin: 0 auto;
          width: 530px;
          height: 519px;
          @include flex(row, normal, normal, wrap, space-between);
          .lucky-draw-item {
              position: relative;
              width: 176px;
              height: 171px;
              border-radius: 20px;
              color: #fff;
              vertical-align: bottom;
              img {
                  width: 160px;
                  height: 157px;
              }
              .start-tips-times {
                  position: absolute;
                  left: 50%;
                  transform: translateX(-50%);
                  bottom: 40px;
                  width: 100%;
                  height: 28px;
                  font-size: 22px;
                  color: rgba(255, 255, 255, 1);
                  span {
                      font-size: 28px;
                      text-decoration: underline;
                  }
              }
          }
          .active {
              background: #ff5e06;
          }
      }
      
      

      3.2 順時針旋轉

      布局有了,就要開始讓每個格子切換背景色了,這里有一個問題,如何讓九宮格順時針旋轉。比較特殊的是,這里中間有一個格子不用切換,其他的需要切換,所以上面的獎品數據不能直接修改active屬性來切換樣式,需要用一個變量記住“順時針”的順序。代碼如下:

      alongPointer: [1, 2, 3, 6, 9, 8, 7, 4]
      
      

      這樣就可以alongPointer變量中每個元素的值和luckyDrawList中的id屬性一一對應,可以看到alongPointer數組中沒有5,這是中間的點擊按鈕。如下圖2。
      image
      圖2

      3.3 定時任務

      定時任務是這個動畫的關鍵,可以把這個順時針旋轉抽象為按照順序執行的一系列異步操作。Promise是一種異步操作解決方案,可以把這些異步操作放在Promise中,并給定它的等待時間。代碼如下:

      startRoll() {
          let count = 5 * 8                           //8個獎品,先空轉5圈
          let timeourID = null
          let tasks = []
          let exapsed = parseInt(1000 / 8)            //間隔時間
          const highlight = i =>
              new Promise((resolve, reject) => {
                  this.timeourID = setTimeout(() => {
                      this.luckyDrawList.forEach(u => {
                          u.active = u.id === this.alongPointer[i % 8] //輪播
                      })
                      resolve()
                  }, exapsed * i)
              })
          //添加異步任務
          for (let i = 0; i < count; i++) {
              tasks.push(highlight(i))
          }
          //完成所有異步任務,執行后續操作
          Promise.all(tasks).then(() => {
              clearTimeout(this.timeoutID)
          })
      }
      

      上面代碼中u.active = u.id === this.alongPointer[i % 8]這里不斷輪播,i的值的范圍是0~40,8個獎品的id保存在this.alongPointer變量中,用0到40和i取余,得到的是5組0,1,2,3,4,5,6,7,最后就空轉了5圈。如下圖3
      image
      圖3

      3.4 選中獎品

      最后完成空轉之后就可以定位獎品了,這里用一個隨機函數getRandomIntInclusive來生成獎品,它生成一個大于等于min,小于等于max的隨機數。代碼如下:

      //生成隨機獎品
      getRandomIntInclusive(min, max) {
          min = Math.ceil(min)
          max = Math.floor(max)
          return Math.floor(Math.random() * (max - min + 1)) + min
      }
      

      所有異步任務完成之后,可以隨機生成獎品了,使用Promise.all()來判斷所有異步任務都執行完畢。代碼如下:

      Promise.all(tasks).then(() => {
          clearTimeout(this.timeoutID)
          this.showLotteryResult()
      })
      //設置獎品
      showLotteryResult() {
        let randomIndex = this.getRandomIntInclusive(0, this.luckyDrawList.length - 1)
        let id = this.luckyDrawList[virtualIndex].id
        console.log(randomIndex, virtualIndex, id)
        this.luckyDrawList.forEach((u, i) => {
            u.active = u.id == id
        })
      }
      

      最后看看動畫的效果,如下圖4
      image
      圖3

      3.5 對Promise的改進

      Promise的寫法可以改進一下,使用async,await的方式來調用,這樣代碼看起來更加簡潔。代碼如下:

      startRoll() {
          let count = 5 * 8                           //8個獎品,先空轉5圈
          let interval = parseInt(1000 / 8)           //切換時間間隔
          let sleep = time => new Promise((resolve) => {
              this.timeoutID = setTimeout(resolve, time)
          })
          let pushEvent = async(count, interval) => {
              for (let i = 0; i < count; i++) {
                  await sleep(interval)
                  this.luckyDrawList.forEach(u => {
                      u.active = u.id === this.alongPointer[i % 8]
                  })
              }
          }
          pushEvent(count, interval).then(() => {
              clearTimeout(this.timeoutID)
              this.showLotteryResult()
          })
      }
      
      

      4. 總結

      本文介紹了九宮格抽獎的實現方式,涉及到的知識點有Promise,Promise.all,async/await/then等,這里還可以優化一個功能,就是讓九宮格先慢后快,最后再快速切換,下次有時間再研究。

      posted @ 2022-08-12 14:14  nd  閱讀(913)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 男女爽爽无遮挡午夜视频| 亚洲人成网网址在线看| 国产成人精品a视频| 亚洲成人av日韩在线| 亚洲精品一区国产欧美| 99热久久这里只有精品| 曰韩精品无码一区二区三区视频| 亚洲第一综合天堂另类专| 国产乱妇乱子视频在播放| 九九热在线精品视频观看| 亚洲人妻精品一区二区| 宜宾市| 亚洲国产在一区二区三区| 国产精品中文字幕免费| 巨大黑人极品videos精品| 亚洲成av人片无码不卡播放器| 超碰自拍成人在线观看| 人妻中文字幕精品一页| 免费看国产精品3a黄的视频| 综合色久七七综合尤物| 久久精品国产精品亚洲精品| 欧美日激情日韩精品嗯| 丰满人妻熟妇乱又仑精品| 亚洲精品一区二区区别| 国产精品成人久久电影| 久久久久无码中| 亚洲精品国产aⅴ成拍色拍| 亚洲日韩一区二区| 亚洲a∨无码无在线观看| 熟女精品色一区二区三区| 日本福利一区二区精品| 亚洲欧美日产综合在线网| 人妻少妇无码精品视频区| 亚洲一区二区三区丝袜| 亚洲av色在线播放一区| 日本熟妇色xxxxx| 亚洲男女羞羞无遮挡久久丫| 亚洲一二三区精品与老人| 非会员区试看120秒6次| 色综合久久精品中文字幕| 婷婷久久香蕉五月综合加勒比|