原生微信小程序九宫格自定义配置以及动画实现

<view class="nine_palaces_horse_lights">
      <view class="content">
        <view wx:for="{{awardList1}}" wx:key="*this" wx:for-index="index">
          <view wx:if="{{index == 4}}" class="award1" bind:tap="{{jiuFlag?'clickPrize':''}}">
            <view wx:if="{{activityCount > 0}}" class="btn {{lucking ? 'lucking' : 'lucked'}}">
              <text class="btn_text font-num" wx:for="{{item.name}}" wx:for-item="item1" wx:key="*this">
                {{item1}}
              </text>
            </view>
            <view wx:else class="btn lucking">
              <text class="btn_text font-num" wx:for="{{item.name}}" wx:for-item="item1" wx:key="*this">
                {{item1}}
              </text>
            </view>
          </view>
          <view wx:else class="award  {{item.isSelected ? 'selected' : 'unselected'}}">
            <block wx:if="{{item.type == 'prize'}}">
              <view class="option">
                <image src="{{item.icon || ''}}" mode="widthFix"></image>
              </view>
              <view class="txt {{item.name.length >1?'txt1':''}}">
                <view wx:for="{{item.name}}" wx:for-item="item1" wx:key="*this">{{item1}}</view>
              </view>
            </block>
            <block wx:elif="{{item.type == 'btn'}}">
              <view class="txt">
                <view wx:for="{{item.name}}" wx:for-item="item1" wx:key="*this">{{item1}}</view>
              </view>
            </block>
          </view>
        </view>
      </view>
      <view class="chance" bind:tap="{{jiuFlag?'clickPrize':''}}">剩余{{activityCount}}次</view>
    </view>
activityCount: 0,
lucking: false,
awardList1:  [
{"id": "1678684429869957122", "actId": "1681129774631436290", 
"actName": "九宫格活动", "name": "88元现金红包", "icon": "xxxx",
 "prizeId": "1681138598855655426", "prizeName": "88元现金红包", 
"sort": 0, "status": 1, "createTime": "2023-07-11T16:35:31", "lastModifyTime": null}, 
{"id": "1678684592919330818", "actId": "1681129774631436290", 
"actName": "九宫格活动", "name": "iPhone12", "icon": "xxxx", 
"prizeId": "1681139939384573954", "prizeName": "iPhone12", "sort": 1, "status": 1, "createTime": "2023-07-11T16:36:10", "lastModifyTime": "2023-07-25T15:34:19"}, 
{"id": "1678684695847550977", "actId": "1681129774631436290", 
"actName": "九宫格活动", "name": "1.8元现金红包", "icon": "xxx", 
"prizeId": "1681139399015612417", "prizeName": "1.8元现金红包", 
"sort": 2, "status": 1, "createTime": "2023-07-11T16:36:35", "lastModifyTime": null}, 
{"id": "1678684847689744385", "actId": "1681129774631436290", 
"actName": "九宫格活动", "name": "爱玛电动车", "icon": "xxxx", 
"prizeId": "1727575759369265153", "prizeName": "爱玛电动车", 
"sort": 3, "status": 1, "createTime": "2023-07-11T16:37:11", "lastModifyTime": "2023-12-28T15:07:21"}, 
{"id": "1678686592151109634", "actId": "1681129774631436290", "actName": "九宫格活动", "name": "官方微商城优惠券", "icon": "xxx", 
"prizeId": "1681141611565498369", "prizeName": "官方微商城优惠券", 
"sort": 4, "status": 1, "createTime": "2023-07-11T16:44:07", "lastModifyTime": null},
 {"id": "1678686724460429314", "actId": "1681129774631436290", 
"actName": "九宫格活动", "name": "定制鼠标垫", "icon": "xxx", "prizeId": "1681140439781818369", "prizeName": "定制鼠标垫", "sort": 5, "status": 1, "createTime": "2023-07-11T16:44:38", "lastModifyTime": "2023-10-31T16:24:04"}, 
{"id": "1678686818400256002", "actId": "1681129774631436290", 
"actName": "九宫格活动", "name": "0.3元现金红包", "icon": "xxx", 
"prizeId": "1683718254670725121", "prizeName": "0.3元现金红包", "sort": 6, "status": 1, "createTime": "2023-07-11T16:45:01", "lastModifyTime": "2023-07-25T22:49:56"}, 
{"id": "1678687275726192642", "actId": "1681129774631436290", "actName": "九宫格活动", "name": "惊喜好礼,等你拿", "icon": "xxx", "prizeId": "1681143035510734850", "prizeName": "惊喜好礼", 
"sort": 7, "status": 1, "createTime": "2023-07-11T16:46:50", "lastModifyTime": "2024-01-30T18:26:37"}
],
/*
     * 数组的长度就是最多所转的圈数,最后一圈会转到中奖后的位置
     * 数组里面的数字表示从一个奖品跳到另一个奖品所需要的时间
     * 数字越小速度越快
     * 想要修改圈数和速度的,更改数组个数和大小即可
     */
    // num_interval_arr: [90, 80, 70, 60, 50, 50, 50, 100, 150, 250],
    num_interval_arr: [90, 80, 100, 150],
    // num_interval_arr: [90, 80],
    /*
     * 页面中奖项的实际数组下标
     * 0  1  2
     * 3     5
     * 6  7  8
     * 所以得出转圈的执行顺序数组为 ↓
     */
    order_arr: [0, 1, 2, 5, 8, 7, 6, 3],
    // 抽奖状态,是否转完了
    isTurnOver: true,
    // 是否需要复原,把没转完的圈转完
    isRecover: false,
    // 记录上一次抽奖后的奖品id
    prize_id_last: '',
   indexSelect: '', //被选中的奖品index
    jiuFlag:false
// 九宫格列表显示接口
  getXPP9List() {
    wx.showLoading({
      title: '加载中'
    })
    apiRequest('xxx', {}, 'get').then(res => {
      console.log(res, '九宫格显示列表接口');
      wx.hideLoading()
      if (res.code == 100) {
        let awardList1 = res.data
        let len = res.data.length
        for (var i = 0; i < len; i++) {
          awardList1[i].isSelected = false
          awardList1[i].type = 'prize'
        }
        awardList1[0].isSelected = true
        awardList1.splice(4, 0, {
          name: '抽奖',
          type: 'btn'
        })
        awardList1.forEach(item => {
          if (item.name.indexOf(',') > -1) {
            item.name = item.name.split(',')
          } else {
            item.name = [item.name]
          }
        })
        this.setData({
          awardList1
        })
      }
    }).catch(() => {
    })
  },
// 九宫格抽奖接口
  getXPPTakePrize() {
    let {
      indexSelect
    } = this.data
    let activityCount = this.data.activityCount
    activityCount -= 1
    this.setData({
      activityCount
    })
    let { openId } = this.data.member.originFrom
    let { id } = this.data.member
    let codeStartWith = 'XP9'
    let { province, provinceCode, city, cityCode, district, districtCode, sematicDescription, latitude, longitude, locationStatus } = this.data.addressInfo
    // 调用抽奖接口
    let query = {
      codeString: this.data.code,
      openid: openId,
      qmMemberId: id,
      province,
      provinceCode,
      city,
      cityCode,
      district,
      districtCode,
      sematicDescription,
      latitude,
      longitude,
      locationStatus,
      // test: 1
    }
    wx.showLoading({
      title: '加载中'
    })
    apiRequest(`xxx`, query, 'post').then(res => {
      console.log(res, '九宫格抽奖接口');
      wx.hideLoading()
      if (res.code == 100) {
        try {
          this.setData({
            prizeType: res.data.prizeType,
            prizeName: res.data.prizeName,
            toUrl: res.data.toUrl,
            drawId: res.data.drawId,
            actId1: res.data.actId,
            memberId: res.data.memberId,
            xpfPrizeVO: res.data.xpfPrizeVO,
            surpriseGiftPrizeUrl: res.data.prizeUrl
          })
          let params = res.data.toUrl.split('||')
          this.setData({
            djqMoney: params[2]
          })
          this.data.awardList1.forEach((item, index) => {
            if (item.prizeId === res.data.prizeId) {
              this.setData({
                prizeUrl: item.icon
              })
              indexSelect = this.data.order_arr.indexOf(index)
              // 调用抽奖方法
              this.lottery(indexSelect + 1);
            }
          })
        } catch (error) {
          console.log(error, '九宫格抽奖error信息');
        }
      } else {
        this.setData({
          isTurnOver: true
        })
      }
    }).catch(() => {
      this.setData({
        jiuFlag: true,
        isTurnOver: true
      })
    })
  },
// 抽奖旋转动画方法
  async lottery(prize_id) {
    console.log('中奖ID:' + prize_id)
    // 如果不是第一次抽奖,需要等待上一圈没跑完的次数跑完再执行
    this.recover().then(() => {
      let num_interval_arr = this.data.num_interval_arr;
      let order_arr = this.data.order_arr;
      // 旋转的总次数
      let sum_rotate = num_interval_arr.length;
      // 每一圈所需要的时间
      let interval = 0;
      num_interval_arr.forEach((delay, index) => {
        setTimeout(() => {
          this.rotateCircle(delay, index + 1, sum_rotate, prize_id, order_arr);
        }, interval)
        //因为每一圈转完所用的时间是不一样的,所以要做一个叠加操作
        interval += delay * 8;
      })
    })
  },
  /*
   * 封装旋转一圈的动画函数,最后一圈可能不满一圈
   * delay:表示一个奖品跳到另一个奖品所需要的时间
   * index:表示执行到第几圈
   * sum_rotate:表示旋转的总圈数
   * prize_id:中奖后的id号
   * order_arr_pre:表示旋转这一圈的执行顺序
   */
  rotateCircle(delay, index, sum_rotate, prize_id, order_arr_pre) {
    // console.log(index)
    let _this = this;
    // 页面奖品总数组
    let awardList1 = this.data.awardList1;
    // 执行顺序数组
    let order_arr = []
    // 如果转到最后以前,把数组截取到奖品项的位置
    if (index == sum_rotate) {
      order_arr = order_arr_pre.slice(0, prize_id)
    } else {
      order_arr = order_arr_pre;
    }
    for (let i = 0; i < order_arr.length; i++) {
      setTimeout(() => {
        // 清理掉选中的转态
        awardList1.forEach(e => {
          e.isSelected = false
        })
        // 执行到第几个就改变它的选中状态
        awardList1[order_arr[i]].isSelected = true;
        // 更新状态
        _this.setData({
          awardList1: awardList1
        })
        // 如果转到最后一圈且转完了,并且是非重置圈,把抽奖状态改为已经转完了
        if (index === sum_rotate && i === order_arr.length - 1 && !this.data.isRecover) {
          _this.setData({
            isTurnOver: true,
            isRecover: true,
            prize_id_last: prize_id,
            jiuFlag: true
          })
          // 带复购红包
          if (_this.data.xpfPrizeVO && _this.data.xpfPrizeVO.prizeName) {
            // 0 企业转账  1虚拟奖券  2实物奖品  3微信红包  4积分  8代金券 6翻倍卡
            if ((_this.data.prizeType == 2 || _this.data.prizeType == 0) && _this.data.xpfPrizeVO.prizeType == 8) {
              _this.setData({
                fuGouRedPacketFlag: true
              })

            } else if (_this.data.prizeType == 1 && _this.data.xpfPrizeVO.prizeType == 8) {
              _this.setData({
                yhjFuGouRedPacketFlag: true
              })
            }
          } else {
            // 虚拟奖券
            if (_this.data.prizeType == 1) {
              _this.setData({
                yhjFlag: true
              })
              // 企业转账 // 实物奖品
            } else if (_this.data.prizeType == 0 || _this.data.prizeType == 2) {
              _this.setData({
                hbOrswFlag: true
              })
            // 惊喜好礼 配的是翻倍卡
            }else if(_this.data.prizeType == 6){
              _this.setData({
                surpriseGiftFlag:true
              })
            }
          }
        }
      }, delay * i)
    }
  },
  // 复原,把上一次抽奖没跑完的次数跑完
  async recover() {
    if (this.data.isRecover) { // 判断是否需要重置操作
      let delay = this.data.num_interval_arr[0]; // 为了衔接流程,使用第一圈的转速
      // console.log(delay)
      let order_arr = this.data.order_arr;
      // console.log(order_arr)
      let prize_id_last = this.data.prize_id_last; // 上一次抽奖的id
      // console.log(prize_id_last)
      order_arr = order_arr.slice(prize_id_last); // 截取未跑完的格子数组
      // console.log(order_arr)
      return await new Promise(resolve => { // 确保跑完后才去执行新的抽奖
        this.rotateCircle(delay, 1, 1, 8, order_arr); // 第一圈的速度,最多只有一圈,旋转一圈,跑到最后一个奖品为止,未跑完的数组
        setTimeout(() => { // 确保跑完后才告诉程序不用重置复原了
          this.setData({
            isRecover: false,
          })
          resolve() // 告诉程序Promise执行完了
        }, delay * order_arr.length)
      })
    }
  },
// 跑马灯样式实现
    .nine_palaces_horse_lights {
      position: relative;
      margin: 0 auto;
      margin-top: 233rpx;
      width: 659rpx;
      height: 670rpx;
      background: url('xxx') no-repeat;
      background-size: 100% 100%;

      .content {
        position: relative;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 583rpx;
        height: 577rpx;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-around;
        align-items: center;
        padding: 13rpx;

        .award {
          // padding-top: 10rpx;
          width: 177rpx;
          height: 174rpx;
          // border-radius: 20rpx;
          opacity: 1;
          background: linear-gradient(180deg, #FF4943 0%, #FF120E 100%);
          // border: 3rpx solid #FFFBE1;
          display: flex;
          flex-direction: column;
          // justify-content: center;
          align-items: center;

          .btn_text {
            font-size: 48rpx;
            font-weight: normal;
            line-height: 57rpx;
            letter-spacing: 0.07em;
            background: linear-gradient(0deg, #FFF6B2 0%, #FFFFFF 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;

          }

          .btn_text1 {
            margin-top: -35rpx;
          }
        }

        .award1 {
          width: 177rpx;
          height: 174rpx;
          border-radius: 20rpx;
          opacity: 1;
          background: linear-gradient(180deg, #FF4943 0%, #FF120E 100%);
          border: 3rpx solid #FFFBE1;
          display: flex;
          justify-content: center;
          // flex-direction: column;
          // align-items: center;
          z-index: 9;

          .btn_text {
            position: absolute;
            top: 42%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 48rpx;
            font-weight: normal;
            line-height: 57rpx;
            letter-spacing: 0.07em;
            background: linear-gradient(0deg, #FFF6B2 0%, #FFFFFF 100%);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;

          }

          .btn_text1 {
            margin-top: -35rpx;
          }
        }

        .selected {
          width: 175rpx;
          height: 176rpx;
          background: url('https://txsb.oss-cn-beijing.aliyuncs.com/image/xiangpiaopiao/%E8%BD%AC%E7%9B%98%E5%B7%B2%E9%80%89%E4%B8%AD.jpg') no-repeat;
          background-size: 100%;
        }

        .unselected {
          width: 175rpx;
          height: 176rpx;
          background: url('https://txsb.oss-cn-beijing.aliyuncs.com/image/xiangpiaopiao/%E8%BD%AC%E7%9B%98%E6%9C%AA%E9%80%89%E4%B8%AD.jpg') no-repeat;
          background-size: 100%;
        }

        .option {
          image {
            width: 100rpx;
            height: 100rpx;
          }
        }

        .txt {
          width: 144rpx;
          font-size: 22rpx;
          font-weight: normal;
          text-align: center;
          letter-spacing: 0em;

          color: #B80000;
        }

        .txt1 {
          margin-top: -10rpx;
          width: 144rpx;
          font-size: 20rpx;
          font-weight: normal;
          text-align: center;
          letter-spacing: 0em;

          color: #B80000;
        }
      }

      .chance {
        position: absolute;
        top: 54%;
        left: 50%;
        transform: translate(-50%, -50%);
        font-size: 24rpx;
        font-weight: bold;
        letter-spacing: 0em;

        color: #FFFFFF;
      }
    }

所需素材

转盘背景.jpg

成图

9.jpg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容