Vue前端攻城狮

Vue<幸运抽奖-九宫格>

2021-01-12  本文已影响0人  誰在花里胡哨
image.png
效果参考地址
效果地址有些许bug,此处代码已经加以优化处理,css样式方面通过使用scss,更加方便!

实现思路:
1.要想实现从 特 - 1 - 2 - 3 - 4 - 5 - 6 - 7的方向执行,必须要在css内对标签进行position定位处理,以便于实现走马灯的效果
2.借助setTimeout计时器的方法,通过递归改变time来实现由快变慢的效果

配置参数:

      winner: 0, //指定获奖下标 specified为true时生效
      specified: true, //是否指定获奖结果,false时为随机
      list: [], //抽奖列表

      //----------------------上面的为主要参数--------------------------

      rollIndex: -1, //转动时的下标位置
      prize: -1, // 中奖位置
      count: 8, // 总共有多少个位置
      speed: 100, // 初始转动速度
      cycle: 50, // 转动基本次数:即至少需要转动多少次再进入抽奖环节
      rolling: false, //是否处于抽奖状态,防止多次点击
      timer: null, // 每次转动定时器
      times: 0, // 转动次数
     $lottery_w: 5rem; //每个奖品的宽高
     $lottery_h: 5rem; //每个奖品的宽高
     $lottery_margin: 0.2rem; //每个奖品的间隔

代码如下:

<template>
  <div class="overall">
    <div class="lottery-box">
      <div class="lottery" v-for="(i,index) in list" :key="index">
        <div class="item" :class="{'on':index == rollIndex}">{{i.title}}</div>
      </div>
      <div class="start" @click="start()">抽奖</div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      winner: 0, //指定获奖下标 specified为true时生效
      specified: true, //是否指定获奖结果,false时为随机
      rollIndex: -1, //转动时的下标位置
      prize: -1, // 中奖位置
      count: 8, // 总共有多少个位置
      speed: 100, // 初始转动速度
      cycle: 50, // 转动基本次数:即至少需要转动多少次再进入抽奖环节
      rolling: false, //是否处于抽奖状态,防止多次点击
      timer: null, // 每次转动定时器
      times: 0, // 转动次数
      list: [
        {
          title: '特等奖'
        },
        {
          title: '一等奖'
        },
        {
          title: '二等奖'
        },
        {
          title: '三等奖'
        },
        {
          title: '四等奖'
        },
        {
          title: '五等奖'
        },
        {
          title: '六等奖'
        },
        {
          title: '七等奖'
        }
      ]
    }
  },
  methods: {
    start() {
      if (!this.rolling) {
        this.startRoll()
      }
    },
    //开始转动方法
    startRoll() {
      this.rolling = true //开启转动状态
      this.times += 1 // 转动次数
      this.oneRoll() // 转动过程调用的每一次转动方法,这里是第一次调用初始化

      // 如果当前转动次数达到要求 && 目前转到的位置是中奖位置
      if (this.times > this.cycle + 10 && this.prize === this.rollIndex) {
        clearTimeout(this.timer) // 清除转动定时器,停止转动
        //初始化相关数据
        this.times = this.$options.data().times
        this.speed = this.$options.data().speed
        setTimeout(res => {
          this.rolling = false
          alert(`恭喜你抽中了${this.list[this.rollIndex].title}`)
        }, 500)
      } else {
        if (this.times < this.cycle) {
          this.speed -= 10 // 加快转动速度
        } else if (this.times === this.cycle) {
          //当转动次数达到规定的 必要转动次数后 开始确定中奖位置
          //判断是否指定获奖结果,false时为随机
          if (this.specified) {
            this.prize = this.winner
          } else {
            const index = this.random(0, this.count - 1) // 随机获得一个中奖位置
            this.prize = index //中奖位置,可由后台返回
          }
        } else {
            //当转动次数times > cycle规定停止的转次时,开始慢慢减速,直到达到指定的中奖位置
          this.speed += 20
        }
        //当转速达到一定高度时,就固定为40ms/转
        if (this.speed < 40) {
          this.speed = 40
        }
        this.timer = setTimeout(this.startRoll, this.speed)
      }
    },
    // 每一次转动
    oneRoll() {
      let index = this.rollIndex // 当前转动到哪个位置
      const count = this.count // 总共有多少个位置
      index += 1
      if (index > count - 1) {
        index = 0
      }
      this.rollIndex = index
    },
    random(min, max) {
      return parseInt(Math.random() * (max - min + 1) + min)
    }
  }
}
</script>
<style lang="scss" scoped>
$lottery_w: 5rem; //每个奖品的宽高
$lottery_h: 5rem; //每个奖品的宽高
$lottery_margin: 0.2rem; //每个奖品的间隔

.lottery-box {
  position: relative;
  //抽奖盒子宽高 因为是 3*3布局,所以这里*3
  width: $lottery_w * 3;
  height: $lottery_h * 3;
  //抽奖按钮样式
  .start {
    width: $lottery_w - $lottery_margin * 2;
    height: $lottery_h - $lottery_margin * 2;
    background: rgb(8, 230, 218);
    position: absolute;
    top: $lottery_h + $lottery_margin;
    left: $lottery_w + $lottery_margin;
    border-radius: 0.5rem;
    display: flex;
    justify-content: center;
    align-items: center;
    color: white;
  }
  //每个奖品的外层样式
  .lottery {
    background: #fcfcfc;
    width: $lottery_w;
    height: $lottery_h;
    box-sizing: border-box;
    position: absolute;
    left: 0;
    top: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: $lottery_margin;
    // 每个奖品的内容样式
    .item {
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      box-sizing: border-box;
      border-radius: 0.5rem;
      box-shadow: 0 0 5px #ccc;
      //转动时的高亮效果
      &.on {
        background: rgb(92, 245, 199);
        color: white;
        font-weight: bold;
      }
    }
  }
  //针对每个奖品块单独调整位置,以便适应于跑马灯的效果
  .lottery:nth-child(1) {
    left: 0;
    top: 0;
  }
  .lottery:nth-child(2) {
    top: 0 * $lottery_h;
    left: $lottery_w;
  }
  .lottery:nth-child(3) {
    top: 0 * $lottery_h;
    left: 2 * $lottery_w;
  }
  .lottery:nth-child(4) {
    top: 1 * $lottery_h;
    left: 2 * $lottery_w;
  }
  .lottery:nth-child(5) {
    top: 2 * $lottery_h;
    left: 2 * $lottery_w;
  }
  .lottery:nth-child(6) {
    top: 2 * $lottery_h;
    left: 1 * $lottery_w;
  }
  .lottery:nth-child(7) {
    top: 2 * $lottery_h;
    left: 0 * $lottery_w;
  }
  .lottery:nth-child(8) {
    top: 1 * $lottery_h;
    left: 0 * $lottery_w;
  }
}
</style>
上一篇下一篇

猜你喜欢

热点阅读