vue 中實現大轉盤抽獎


 

想要開發一個,可進行配置獎品的大轉盤抽獎活動:如下圖:

要求: 轉盤底圖可配置,相對應的獎品也能夠配置

 

    

 

 

 

開發思路:

  1. 可以把轉盤開發成一個組件,所有參數皆是可配置的,做成組件具有公用型
  2. 通過 transform的rotate旋轉 以及 transition過渡來實現動畫
  3. 確定旋轉實現的原理,不想能像表盤那樣指針轉,應該是指針不動,表盤旋轉,用戶體驗性更好 

 

具體實現步驟:

 

  1.dom加載完成后,在mounted鈎子中寫一個transition平移動畫

  

   //渲染完了
    mounted() {
      this.oTurntable = document.querySelector('#turnUl');
      // 過度中屬性用時5s
      this.oTurntable.style.webkitTransition = 'transform ' + this.time / 1000 + 's ease';
    },

 

  2.先根據獎品列表數量來計算每個獎品對應的角度,指針一般是定位到該中獎獎品的中心位置,這個要考慮到

autoRotate(arr) {
      if (arr.length) {
          let len = arr.length;
          let base = 360 / len;
          arr.forEach((item, index) => {
            // 指的是某個獎品區域的中間 : base/2
            item.angle = 360 - (base / 2 + index * base);
          });
      }
      return arr;
},

 

 

  3.點擊按鈕時請求接口,拿到中獎獎品進行旋轉到之前計算好的該獎品的角度,可以寫在定時器當中,完成后即清除定時器

      // 點擊開始,請求接口抽獎
      startPlay(){
        const a = {
          prize: "50元和包券",
          id: 4
        }
        this.startBtn(a)
      },
      // 開始轉動,通過獎項級別進行匹配:id 
      startBtn(val) {
        const self = this
        self.activeObj.prizeData.forEach((i,d)=>{
          if(i.id == val.id){
            self.pIndex = d
          }
        })
        // 拿到相應的角度調旋轉接口
        self.startrotate(self.activeObj.prizeData[self.pIndex].angle, () => {
          self.fulfillHandle(self.activeObj.prizeData[self.pIndex].prize);
        });
      },

      //開始旋轉 angle角度  complete回調成功函數
      startrotate(angle, complete) {
        // 相應的角度 + 滿圈 只是在原角度多轉了幾圈 360 * 6
        let rotate = 2160 * (this.rotNum + 1) + angle;
        this.oTurntable.style.webkitTransform = 'rotate(' + rotate + 'deg)';
        clearTimeout(this.timer);
        // 設置5秒后停止旋轉,處理接口返回的數據
        this.timer = setTimeout(() => {
          complete();
          this.rotNum++;
        }, this.time);
      },
      //得獎后的處理
      fulfillHandle(prizeName) {
        this.$emit('result',prizeName)
      },

 

  4.抽獎旋轉結束后再去處理后續操作,寫在startrotate 這個函數中,通過吧結束處理的函數當做參數進行回調

 

下面是完整代碼:

html:

<template>
  <div id="turnBox">
    <ul id="turnUl" :style="{ backgroundImage : 'url(' + activeObj.turntableBgc + ')'}">
      <li
        v-for="(item,index) in activeObj.prizeData"
        :key="index"
        :style="{webkitTransform: 'rotate(' + -item.angle + 'deg)'}"
      >
      </li>
    </ul>
    <img :src="activeObj.turntablebtn" alt=""  @click="startPlay" class="turnBtn">
  </div>
</template>

 

js:

<script>
  export default {
    props: {
      activeObj: {
        type: Object,
        default: null
      },
    },
    data(){
      return {
        pIndex: 0, // 中獎物品的下標
        rotNum:  0, // 旋轉圈數基數
        time: 5000, // 旋轉時間
        timer: null, // 定時器
        oTurntable: '', // 旋轉圓盤背景圖
        type: 0, // 0 圖片 1 漢字
      }
    },   
    created() {
      this.activeObj.prizeData = this.autoRotate(this.activeObj.prizeData)
      console.log(this.activeObj.prizeData);
    },
    //渲染完了
    mounted() {
      this.oTurntable = document.querySelector('#turnUl');
      // 過度中屬性用時5s
      this.oTurntable.style.webkitTransition = 'transform ' + this.time / 1000 + 's ease';
    },
    methods:{
      //自動生成角度添加到數組上
      autoRotate(arr) {
        if (arr.length) {
          let len = arr.length;
          let base = 360 / len;
          arr.forEach((item, index) => {
            // 指的是某個獎品區域的中間 : base/2
            item.angle = 360 - (base / 2 + index * base);
          });
        }
        return arr;
      },
      // 點擊開始,請求接口抽獎
      async startPlay(){
        const a = {
          prize: "50元和包券",
          id: 4
        }
        this.startBtn(a)
      },
      // 開始轉動,通過獎項級別進行匹配:id 
      async startBtn(val) {
        const self = this
        self.activeObj.prizeData.forEach((i,d)=>{
          if(i.id == val.id){
            self.pIndex = d
          }
        })
        // 拿到相應的角度調旋轉接口
        self.startrotate(self.activeObj.prizeData[self.pIndex].angle, () => {
          self.fulfillHandle(self.activeObj.prizeData[self.pIndex].prize);
        });
      },

      //開始旋轉 angle角度  complete回調成功函數
      startrotate(angle, complete) {
        // 相應的角度 + 滿圈 只是在原角度多轉了幾圈 360 * 6
        let rotate = 2160 * (this.rotNum + 1) + angle;
        this.oTurntable.style.webkitTransform = 'rotate(' + rotate + 'deg)';
        clearTimeout(this.timer);
        // 設置5秒后停止旋轉,處理接口返回的數據
        this.timer = setTimeout(() => {
          complete();
          this.rotNum++;
        }, this.time);
      },
      //得獎后的處理
      fulfillHandle(prizeName) {
        this.$emit('result',prizeName)
      },
      
      //自動換行
      autoWrap(str) {
        if (str.length > 5 && str.length <= 10) {
          str = str.substring(0, 5) + '<br/>' + str.substring(5, str.length);
        } else if (str.length > 10) {
          str = str.substring(0, 5) + '<br/>' + str.substring(5, 9) + '...';
        }
        return str;
      }
    }
  }
</script>

 

css:

<style lang="less" scoped>
  #turnBox {
    width: 545px;
    height: 544px;
    position: relative;
    overflow: hidden;
    margin: 0px auto;
    margin-top: 30px;
    background-position: center center;
    .turnBtn {
      position: absolute;
      width: 1.3rem;
      left: 50%;
      top: 50%;
      transform: translateX(-50%) translateY(-59%);
      overflow: hidden;
      background-repeat: no-repeat;
      background-size: 100% auto;
      z-index: 3;
    }
    ul {
      position: absolute;
      width: 100%;
      height: 100%;
      z-index: 1;
      background-repeat: no-repeat;
      background-size: 100% auto;
      li {
        position: absolute;
        box-sizing: border-box;
        // padding-top: 0.5rem;
        color: #7e250d;
        font-size: 0.3rem;
        top: 0pc;
        left: 0px;
        width: 100%;
        height: 100%;
        line-height: 20px;
        transform-origin: 50% 50%;
        img {
          position: absolute;
          top: 0.3rem;
          left: 50%;
          transform: translateX(-50%);
          width: 20%;
        }
      }
    }
  }

</style>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM