微信小程序多宫格/九宫格抽奖 基于vue来写

html

<template>
  <view>
    <!-- <image  src="@/static/images/activity/classify.png" mode="aspectFill"> -->
    <view class="box">
        <view :class="luckynum==index?'luck boxsub':'boxsub'" 
                v-for='(item,index) in box' 
                :style="index>0&&index<4?('top:0;left:'+index*140+'rpx;')
                                        :(index>3&&index<8?('right:0;top:'+((index-4)*100)+'rpx;')
                                                        :(index>7&&index<12?('bottom:0;right:'+(index-7)*140+'rpx;')
                                                                            :(index>11&&index<14?('left:0;bottom:'+(index-11)*100+'rpx;')
                                                                                                :'')
                                                        )
                                        ) " :key='index'>
             <text class='boxcontent' :style='item.name.length>6?"line-height:40rpx;margin-top:10rpx;":"line-height:100rpx;"'>{{item.name}}</text> 
            
        </view>
        <view class="lucky" @tap="luckyTap">
            <text class="taplucky">点击抽奖</text>
            <text class="howMany">您还有<text class="howMany_num" >{{howManyNum}}</text>次抽奖机会</text>
        </view>
    </view>
    <view class="explain">
    
    </view>
  </view>
</template>

js

export default {
  data() {
    return {
        box: [{
              name:'100积分'
            }, {
                name: '10元优惠券
满100可用'
            }, {
                name: '60积分'
            }, {
                name: '30积分'
            }, {
                name: '50积分'
            }, {
                name: '30元优惠券
满120可用'
            }, {
                name: '100积分'
            }, {
                name: '200积分'
            }, {
                name: '10积分'
            }, {
                name: '50积分'
            }, {
                name: '40积分'
            }, {
                name: '50优惠券满500可用'
            }, {
                name: '60积分'
            }, {
                name: '70积分'
            }],
            luckynum:0,//当前运动到的位置,在界面渲染
            howManyNum:10,//抽奖的剩余次数
            content:{
              index: 0,    //当前转动到哪个位置,起点位置
              count: 0,    //总共有多少个位置
              speed: 50,    //初始转动速度
              cycle: 3*14,    //转动基本次数:即至少需要转动多少次再进入抽奖环节,这里设置的是转动三次后进入抽奖环节
            },
            prize:12,//中奖的位置
            luckytapif:true//判断现在是否可以点击
    };
  },
  
  onLoad() {
     // let that = this;
  },
  methods: {
    //点击抽奖
      luckyTap:function(){
        var i=0,
            that=this,
            howManyNum = this.howManyNum,//剩余的抽奖次数
            luckytapif = this.luckytapif,//获取现在处于的状态
            luckynum = this.luckynum,//当前所在的格子
            prize =Math.floor(Math.random()*14) ;//中奖序号,随机生成
        if (luckytapif && howManyNum>0){//当没有处于抽奖状态且剩余的抽奖次数大于零,则可以进行抽奖
          console.log('prize:'+prize);
          this.content.count=this.box.length;
          this.howManyNum=howManyNum-1//更新抽奖次数
          this.luckytapif=false;//设置为抽奖状态
          this.prize = prize;//中奖的序号
          this.roll();//运行抽奖函数
        } else if (howManyNum == 0 && luckytapif){
          wx.showModal({
            title: '',
            content: '您的抽奖次数已经没有了',
            showCancel:false
          })
        }
      },
    //抽奖
      roll:function(){
        var content=this.content,
          prize = this.prize,//中奖序号
          that=this;
        if (content.cycle - (content.count-prize)>0){//最后一轮的时间进行抽奖
          content.index++;
          content.cycle--;
            this.luckynum= content.index%14  //当前应该反映在界面上的位置
          setTimeout(this.roll, content.speed);//继续运行抽奖函数
        }else{
          if (content.index < (content.count*3 + prize)){//判断是否停止
    
            content.index++;  
            content.speed += (550 /14);//最后一轮的速度,匀加速,最后停下时的速度为550+50
            this.content=content;
              this.luckynum= content.index % 14
            console.log(content.index, content.speed);//打印当前的步数和当前的速度
            setTimeout(this.roll,content.speed);
          }else{
            //完成抽奖,初始化数据
            console.log('完成');
            content.index =0;
            content.cycle = 3 * 14;
            content.speed = 50;
            this.luckytapif = true;
            // clearTimeout(time);
            wx.showModal({
              title: '',
              content: '恭喜你抽到了'+that.box[prize].name,
              showCancel:false
            })
          }
        }
      }
  }
  
};

scss

.box{
      margin:20rpx 25rpx;
      height: 400rpx;
       698rpx;
      /*border:1px solid #ddd;*/
      position: relative;
      /*box-sizing: border-box;*/
    }
    .boxsub{
       140rpx;
      height: 100rpx;
      /*border: 1px solid #f00;*/
      box-sizing: border-box;
      position: absolute;
      background: #ff6100;
      border: 1rpx solid #fff;
     
    }
    .boxcontent{
      text-align: center;
      font-size: 26rpx;
      display: block;
      color: #fff;
    }
    .lucky{
       300rpx;
      height:130rpx;
      background:#ff6100;/* #ff6100;007FFF*/
      position: absolute;
      left: 0;
      bottom: 0;
      right: 0;
      top: 0rpx;
      margin: auto;
    }
    
    .lucky:active{
      opacity: 0.7;
    }
    .taplucky{
      display: block;
      text-align: center;
      font-size: 30rpx;
      line-height: 50rpx;
      height: 50rpx;
      color: #fff;
      margin-top: 20rpx;
    }
    .howMany{
      display: block;
      text-align: center;
      font-size: 26rpx;
      color: #fff;
      line-height: 40rpx;
      height: 40rpx;
    }
    .howMany_num{
      color:#007FFF;
      font-size:32rpx;
      line-height:40rpx;
      padding:0 10rpx;
    }
    .luck{
      opacity: 0.5;
      background: #ff6100;
    }

 九宫格方法写抽奖:

 简单样式,图片啥的自己替换就行了

html部分

<div class="gameBox">
        <div class="bg1"></div>
        <div class="bg2" v-show="lampShow"></div>
        <div class="start" @click="move">
            <p>({{number_of_draws}}次)</p>
        </div>
        <ul>
            <li v-for="(item,i) in list" :key="i" :class="['item' + (i+1), {'active': index == i}]">
                <div class="img1">
                    <!-- <img :src="item.image" alt=""> -->
                </div>
                <p>+{{item.number}}{{item.prize_name}}</p>
            </li>
        </ul>
    </div>

js部分

export default {
  data() {
    return {
        list: [
            {
                number:0,
              prize_name:'100积分'
            }, {
                number:1,
                prize_name: '10元优惠券
满100可用'
            }, {
                number:2,
                prize_name: '30积分'
            }, {
                number:3,
                prize_name: '50积分'
            }, {
                number:4,
                prize_name: '30元优惠券
满120可用'
            }, {
                number:5,
                prize_name: '100积分'
            }, {
                number:6,
                prize_name: '200积分'
            }, {
                number:7,
                prize_name: '10积分'
            }
        ],//奖品列表
        index: 0, // 当前转动到哪个位置,第一次起点位置0,对应页面item1位置
        count: 8, // 总共有多少个位置
        times: 0, // 转动跑格子次数,
        cycle: 60, // 转动基本次数:即至少需要转动多少次再进入抽奖环节
        speed: 200, // 初始转动速度
        lampShow:false,//开始抽奖,灯光闪烁
        timer: 0, // 转动定时器
        lamp:0, // 灯光定时器
        prize: 0, // 中奖位置,接口返回
        number_of_draws:3,//限制每天抽奖次数,接口返回
        prize_data: {//中奖信息
            id:0,//奖品ID
            name:'中奖',//奖品名称
            number:1,//奖品数量
            image:'',//奖品图片
            type:0,// 奖品类型
        },
    };
  },
  
  onLoad() {
     // let that = this;
     //获取奖品列表
         // this.axios.post('/api/luckdraw/prizeList').then(res=>{
         //     if(res.status == 1){
         //         this.list = res.data.list; // 奖品列表数据
         //         this.number_of_draws = res.data.number_of_draws; // 该用户剩余抽奖次数
         //     }
         // })
  },
  methods: {
    //点击开始抽奖
        move() {
            if( this.number_of_draws == 0){
                this.$toast('今日抽奖次数已用完,明天再来吧');
            }else if(this.times != 0){
                this.$toast('正在抽奖中,请勿重复点击')
            } else{
                // this.axios.post(baseURL+'/api/luckdraw/doDraw').then(res=>{
                //     if(res.status == 1){
                        this.number_of_draws--;//抽奖开始,次数-1
                        this.speed = 200;//每次抽奖速度初始化为200
                        // this.prize_data = res.data.yes;//已经拿到中奖信息,页面展示,等抽奖结束后,将弹窗弹出
                        this.prize = 6-1;//中奖位置赋值,跑马灯最终停留位置,这里实际位置需要-1
                        this.startRoll();//执行抽奖
                        this.lamp = setInterval(()=>{//灯光闪烁开启
                            this.lampShow = !this.lampShow;
                        },500)
                //     }
                // })
            }
        },
        // 开始转动
        startRoll() {
            this.times += 1; // 转动次数
            this.oneRoll(); // 转动过程调用的每一次转动方法,这里是第一次调用初始化
            this.usePrize();
        },
        
        // 每一次转动
        oneRoll() {
            let index = this.index; // 当前转动到哪个位置
            const count = 8; // 总共有多少个位置
            index += 1;
            if (index > count - 1) {
                index = 0;
            }
            this.index = index;
        },
    
        usePrize() {
            // 如果当前转动次数达到要求 && 目前转到的位置是中奖位置
            if (this.times > this.cycle +10 && this.prize === this.index) {
                clearTimeout(this.timer); // 清除转动定时器
                clearTimeout(this.lamp); // 清除灯光定时器
                this.lampShow = false; // 白色灯隐藏
                this.times = 0; // 转动跑格子次数初始化为0,可以开始下次抽奖
                
                if(this.prize_data.type == 0){
                    console.log('未中奖,谢谢参与');//未中奖提示弹出,
                }else{
                    console.log('中奖啦');//中奖弹出提示
                }
            } else {
                if(this.times < this.cycle -20){
                    this.speed -= 4; // 加快转动速度
                }else{
                    this.speed += 10; // 抽奖即将结束,放慢转动速度
                }
                this.timer = setTimeout(this.startRoll, this.speed);//开始转动
            }
        },
  }
};
</script>

css样式部分

/*
     整体布局采用定位实现
     gameBox:父盒子,最外层背景图
     bg1:灰色灯
     bg2:点击开始按钮后,白色灯出现,同时要每个500s同bg1做切换隐藏显示
     start:按钮样式
     item1-8:通过定位方式将dom元素顺时针排列
     active:点击开始开妞后,从1位置开始高亮,类似跑马灯
    */
    .gameBox {
            display: flex;
            align-items: center;
            justify-content: center;
             326px;
            height: 326px;
            margin: 150px auto 0;
            border-radius: 8px;
            background: url(../../static/images/activity/shop.png)no-repeat left top;
            background-size: 326px 326px;
            position: relative;
            .bg1 {
                position: absolute;
                left: 4.5px;
                top: 4px;
                 317px;
                height: 317px;
                background: url(../../static/images/activity/shop.png)no-repeat center;
                background-size: 317px 317px;
            }
            .bg2 {
                position: absolute;
                left: 4.5px;
                top: 4px;
                 317px;
                height: 317px;
                background: url(../../static/images/activity/shop.png)no-repeat center;
                background-size: 317px 317px;
            }
            .start {
                position: relative;
                padding-top: 70px;
                 86px;
                height: 86px;
                background: url(../../static/images/activity/shop.png)no-repeat center;
                background-size: 86px 86px;
                p {
                    text-align: center;
                    font-size: 12px;
                    font-weight: 400;
                    color: rgba(255, 255, 255, 1);
                }
            }
            ul {
                li {
                    position: absolute;
                     86px;
                    height: 86px;
                    background: rgba(255, 255, 255, 1);
                    border: 2px solid rgba(227, 161, 0, 1);
                    border-radius: 8px;
                    .img1 {
                        margin: 15px auto 3px;
                         35px;
                        height: 35px;
                        img {
                             100%;
                            height: auto;
                        }
                    }
                    p {
                        text-align: center;
                        font-size: 13px;
                        font-weight: 500;
                        color: rgba(153, 153, 153, 1);
                    }
                }
                .item1 {left: 25px;top: 25px;}
                .item2 {left: 120px;top: 25px;}
                .item3 {left: 215px;top: 25px;}
                .item4 {left: 215px;top: 120px;}
                .item5 {left: 215px;top: 215px;}
                .item6 {left: 120px;top: 215px;}
                .item7 {left: 25px;top: 215px;}
                .item8 {left: 25px;top: 120px;}
                .active {background: #FFF2B1;}
            }
        }
原文地址:https://www.cnblogs.com/yishifuping/p/14037450.html