天天看點

九宮格抽獎代碼實作

轉盤抽獎demo

九宮格抽獎代碼實作

核心代碼

class Lottery {
    constructor(domId) {
        this.prizeIndexArr = [0, 1, 2, 5, 8, 7, 6, 3] // 順時針轉動對應的獎品序号
        this.maxStep = this.prizeIndexArr.length * 5 // 最大滾動的格子數
        this.currentIndex = -1 // 目前滾動到的格子的index
        this.step = 0 // 目前滾動過的格子總數
        this.timer = null
        this.speed = 200 // 初始速度
        this.domId = domId
        this.isStart = false // 是否已經開始抽獎,防止連續點選
    }

    doLottery = (prizeIndex) => {
        if (this.isStart) {
            return
        }
        this.startRoll(prizeIndex)
    }

    startRoll = (prizeIndex) => {
        this.isStart = true
        this.step += 1
        this.currentIndex += 1
        // 如果轉到最後一個格子,則重置currentIndex為0,也就是從第一個格子繼續轉動
        if (this.currentIndex > 7) {
            this.currentIndex = 0
        }
        this.addActiveStyle()
        if (this.step >= this.maxStep + this.getIndex(prizeIndex) + 1 && prizeIndex === this.prizeIndexArr[this.currentIndex]) {
            clearTimeout(this.timer)
            this.step = 0
            this.speed = 200
            this.isStart = false
        } else {
            this.setSpeed(prizeIndex)
            this.timer = setTimeout(() => this.startRoll(prizeIndex), this.speed)
        }
    }

    /**
    * 給目前格子添加樣式,取消前一個格子的樣式,如果滾動到index為0的格子,則取消index為7的格子的樣式
    */
    addActiveStyle = () => {
        const dom = document.getElementById(this.domId)
        // 這裡可自行設定樣式
        dom.children[this.prizeIndexArr[this.currentIndex]].style.background = 'yellow'
        if (this.currentIndex === 0) {
            dom.children[this.prizeIndexArr[7]].style.background = ''
        }
        if (this.currentIndex > 0) {
            dom.children[this.prizeIndexArr[this.currentIndex - 1]].style.background = ''
        }
    }

    /**
    * 設定轉動的速度
    */
    setSpeed = (prizeIndex) => {
        // 前8個格子做加速運動
        if (this.step <= 8) {
            this.speed -= 20
        } else if (this.step >= this.maxStep + this.getIndex(prizeIndex) - 8) {
            // 後9個格子做減速運動
            this.speed += 60
        } else {
            this.speed = 40
        }
    }

    /**
    * 根據獎品的index找到prizeIndexArr對應的下标index
    * @returns {number}
    */
    getIndex = (prizeIndex) => {
        return this.prizeIndexArr.findIndex(item => item === prizeIndex)
    }
}

export default Lottery
           

頁面使用

這裡舉在vue中的使用方法,react或其他原理一樣

<template>
  <div class="lottery">
    <ul class="lottery-container" id="lottery-container">
      <li v-for="item in prizeList" :key="item.id" @click="doLottery(item.id)">
        {{ item.id === -1 ? "抽獎" : item.prizeName }}
      </li>
    </ul>
  </div>
</template>
<script>
import Lottery from "@/util/lottery";
export default {
  name: "lottery",
  setup() {
    const lottery = new Lottery("lottery-container");
    const prizeList = [
      { id: 1, prizeName: "mac pro" },
      { id: 2, prizeName: "吹風機" },
      { id: 3, prizeName: "電視機" },
      { id: 4, prizeName: "冰箱" },
      { id: -1 },
      { id: 5, prizeName: "優惠券" },
      { id: 6, prizeName: "華為手機" },
      { id: 7, prizeName: "電腦" },
      { id: 8, prizeName: "筆記本" },
    ];
    const doLottery = (id) => {
      if (id !== -1) return;
      const prizeIndex = Math.floor(Math.random() * 8 + 1)
      lottery.doLottery(prizeIndex);
    };
    return {
      prizeList,
      doLottery,
    };
  },
};
</script>
<style lang="scss" scoped>
.lottery-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  width: 3rem;
  height: 3rem;
  margin: 0 auto;

  li {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: calc(calc(100% / 3) - 0.1rem);
    height: 0.9rem;
    margin: 0.05rem;
    list-style: none;
    border-radius: 0.04rem;
    background-color: #eee;
    font-size: 0.16rem;

    &:nth-child(5) {
      background-color: #eb6a1a;
      cursor: pointer;
    }
  }
}
</style>

           

繼續閱讀