0
点赞
收藏
分享

微信扫一扫

vue大转盘旋转效果-停在随机定位的奖品处

代码有点乱,给予vue写的,奖品可以自定义数量

抽奖也是随机生成了奖品的下标,然后停在该下标的位置

里面有个大转盘的背景图,自己随便找个圆形图片放上去就行了

<!-- 这个案例大概实现了停止在初始位置,误差在±10度左右 增加了奖品分布-->
<template>
  <div class="hello">
    <div class="container" :style='{"transform":"rotate("+rotate+"deg)"}'>
      <div class="turntable">
        <div class="prize" v-for="(item,index) in zp_gift_list" :key="index" :style='{"transform":"rotate("+(zp_gift_step*index-zp_gift_rotate_ni)+"deg)"}'>
<!--                <div class="prize-child" :style='{"transform": "rotate("+(zp_gift_step*index)+"deg) skewY(-30deg)"}'>-->
          <div class="prize-child" :style='{"transform": "rotate(45deg) skewY(0deg)"}'>
            <div>
              <img :src="item.img" alt="">
            </div>
            <div>{{item.name}}</div>
          </div>
        </div>
      </div>
      <div class="draw-btn" @click="startRotate"></div>
    </div>
    <!-- <img src="@/assets/zhuanpan.png" ref="logo" :style='{"transform":"rotate("+rotate+"deg)"}' class="shunhua"> -->
    <button @click="startRotate">开始</button>
    <button @click="stopRotate">停止</button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      //元素当前角度
      rotate:0,
      //定时器对象
      interverObj:null,
      //旋转步进角度
      rotateStep:1,
      //最大步进角度
      rotateStepMax:10,
      //每多少毫秒累加一次步进角度
      rotateAddTime:100,
      //每多少毫秒运行一次
      rotateRunTimeOut:10,
      //当前运行毫秒数
      nowRunTime:0,
      //旋转状态0停止中 1旋转中 2停止中
      rotateState:0,
      //停止旋转步进角度
      rotateStepStop:1,
      //---------------------------------------转盘奖品相关变量
      //奖品列表
      zp_gift_list:[
        {name:'aaa',img:''},
        {name:'bbb',img:''},
        {name:'ccc',img:''},
        {name:'ddd',img:''},
        {name:'eee',img:''},
        {name:'fff',img:''},
        {name:'ggg',img:''},
        {name:'hhh',img:''},
        {name:'iii',img:''},
        {name:'jjj',img:''},
      ],
      //礼物倾斜角度步进值
      zp_gift_step:0,
      //奖品逆角度
      zp_gift_rotate_ni:44,
      //转盘刹停范围
      zp_stop_range:[]
    }
  },
  mounted(){
    // this.startRotate()
    this.getGiftRotate()
  },
  methods:{
    //计算出每个奖品占用的角度
    getGiftRotate(){
      this.zp_gift_step = 360/this.zp_gift_list.length
    },
    //重置相关参数
    resetData(){
      //元素角度
      // this.rotate = 0
      //定时器对象
      clearInterval(this.interverObj)
      this.interverObj = null
      //步进角度
      this.rotateStep = 1
      //当前运行毫秒数
      this.nowRunTime = 0
      //旋转状态0停止中 1旋转中 2停止中
      this.rotateState = 0
    },
    //启动旋转
    startRotate(){
      let that = this
      if(that.rotateState == 0){
        that.rotateState = 1
        that.interverObj = setInterval(function(){that.rotateLogo()},that.rotateRunTimeOut)
      }
      
    },
    //停止旋转
    stopRotate(){
      if(this.rotateState == 1){
        this.getGiftIndexRotate()
        this.rotateState = 2
      }
      //计算距离回正方向差多少度
      // let cha = 720 - this.rotate % 360
      //计算出每次执行需要降速多少度,假设2秒刹车完毕:差多少度/(2000/每次变速时间)
      // this.rotateStepStop = cha/(50000/this.rotateAddTime)
    },
    //控制旋转步进角度
    handleRotate(){      
      if(this.rotateState == 1){//如果当前为旋转中
        //步进角度小于最大步进角度
        if(this.rotateStep < this.rotateStepMax){
          if(this.nowRunTime % this.rotateAddTime == 0){
            //继续累加步进角度
            this.rotateStep += this.rotateStep
          }          
        }
      }else if(this.rotateState == 2){//如果当前为停止中
        if(this.nowRunTime % this.rotateAddTime == 0){
          //减少步进角度
          if((this.rotateStep - this.rotateStepStop)>2){//如果减少之后,步进角度大于0,就继续减少
            this.rotateStep -= this.rotateStepStop
          }else{//否则就是要停止了
            let cha = this.rotate % 360
            //如果在以下角度范围内就停止转动,此判断不涉及到停止在指定奖品角度内
            // if( (cha>=0 && cha<=5) || (cha>=355 && cha<=359) ){
            if( (cha>=this.zp_stop_range[0][0] && cha<=this.zp_stop_range[0][1]) || (cha>=this.zp_stop_range[1][0] && cha<=this.zp_stop_range[1][1]) ){
            // if( (cha>=306 && cha<=324) || (cha>=324 && cha<=342) ){
              this.rotateStep = 0
              this.resetData()
            }
            //如果在以下角度范围就停转,此角度是指定奖品所在的角度
          }          
        }
      }else{//静止状态

      }      
    },
    //随机得出奖品的角度
    getGiftIndexRotate(){
      let res = []
      //随机奖品下标
      let i = Math.round(Math.random()*(this.zp_gift_list.length-1))
      // let cha = this.zp_gift_step * (giftIndex + 1) / 2
      //计算开始范围和结束范围
      let j = this.zp_gift_step/2

      if(i == 0){
        res.push([(360-(2*i+1)*j+j),359])
        res.push([0,(360-(2*i-1)*j)])
      }else{
        res.push([(360-(2*i+1)*j),(360-(2*i+1)*j+j)])
        res.push([(360-(2*i+1)*j+j),(360-(2*i-1)*j)])
      }

      this.zp_stop_range = res
      console.log("停止下标:"+i,res)
    },
    //执行旋转
    rotateLogo(){
      //累加运行毫秒数
      this.nowRunTime += this.rotateRunTimeOut
      //累加旋转角度
      this.rotate += this.rotateStep
      //调用控制旋转步进角度函数
      this.handleRotate()
    }    
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .shunhua{
    transition: 0.1s;
  }
  .container {
    width: 300px;
    height: 300px;
    /*background-color: red;*/
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    background-image: url("../assets/zhuanpan.png");
    background-position: center;
    background-size: 100%;
    color: white;

    /*animation: mymove 8s;*/
    /*-webkit-animation: mymove 8s; !* Safari 与 Chrome *!*/
    /*animation-iteration-count: infinite;*/
    /*animation-timing-function: ease;*/
  }

  .turntable {
    width: 280px;
    height: 280px;
    border-radius: 50%;
    position: absolute;
    overflow: hidden;
  }

  /*扇形区*/
  .prize-container {
    width: 280px;
    height: 280px;
    background-color: bisque;
    position: absolute;
    left: 50%;
    top: -50%;
    /*600-280/2,将prize正方形左下角点对准圆心*/
    border: 1px solid red;
    /*以正方形左下角为中心旋转,0% 100%即左下角的坐标*/
    transform-origin: 0% 100%;
  }

  .prize-container:nth-child(1) {
    transform: rotate(0deg) skewY(-30deg);
  }

  .prize-container:nth-child(2) {
    transform: rotate(60deg) skewY(-30deg);
  }

  .prize-container:nth-child(3) {
    transform: rotate(120deg) skewY(-30deg);
  }

  .prize-container:nth-child(4) {
    transform: rotate(180deg) skewY(-30deg);
  }

  .prize-container:nth-child(5) {
    transform: rotate(240deg) skewY(-30deg);
  }

  .prize-container:nth-child(6) {
    transform: rotate(300deg) skewY(-30deg);
  }

  /* 奖品区 */
  .prize {
    width: 140px;
    height: 140px;
    position: absolute;
    left: 50%;
    top: 0;
    transform-origin: 0% 100%;
  }

  /* 奖品内容 */
  .prize-child {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    transform: rotate(30deg) translateX(-15%) translateY(10%);
  }
  .prize-child div:nth-child(1){
    width: 30px;
    height: 30px;
    /*background-color: blue;*/
  }
  .prize-child img{
    width: 100%;
    height: 100%;
  }
  .prize-child div:nth-child(2){
    font-size: 12px;
  }

  .prize:nth-child(1) {
    transform: rotate(0deg);
  }

  .prize:nth-child(2) {
    transform: rotate(60deg);
  }

  .prize:nth-child(3) {
    transform: rotate(120deg);
  }

  .prize:nth-child(4) {
    transform: rotate(180deg);
  }

  .prize:nth-child(5) {
    transform: rotate(240deg);
  }

  .prize:nth-child(6) {
    transform: rotate(300deg);
  }

  .draw-btn {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    /*background-color: red;*/
    color: white;
    font-size: 30px;
    line-height: 80px;
    text-align: center;
    position: absolute;
    /* background-image: url("../assets/img/zhuanpan/zhen.png"); */
    background-position: center;
    background-size: 100%;
  }
</style>

举报

相关推荐

0 条评论