微信小程序 - 实现九宫格抽奖

2,399 阅读2分钟

先看效果图:

实际效果不会出现上图中闪烁的效果。

ok,进入正题

1、思路

  • 样式

    正常九宫格布局,中间是按钮,排列顺序是围绕中间按钮顺时针排列,这个要注意。

  • 逻辑

    使用setTimeout来循环滚动,重点在于滚动速度的控制,以及中奖位置的判断,下面看代码。

2、代码

wxml:

<view class="wrap">
  <view class="{{activeIndex === 0 ? 'active' : ''}}">1</view>
  <view class="{{activeIndex === 1 ? 'active' : ''}}">2</view>
  <view class="{{activeIndex === 2 ? 'active' : ''}}">3</view>
  <view class="{{activeIndex === 7 ? 'active' : ''}}">8</view>
  <view bindtap="start">开始</view>
  <view class="{{activeIndex === 3 ? 'active' : ''}}">4</view>
  <view class="{{activeIndex === 6 ? 'active' : ''}}">7</view>
  <view class="{{activeIndex === 5 ? 'active' : ''}}">6</view>
  <view class="{{activeIndex === 4 ? 'active' : ''}}">5</view>
</view>

wxss:

.wrap {
  width: 100%;
  display: flex;
  justify-content: start;
  align-items: flex-start;
  flex-wrap: wrap;
}

.wrap view {
  width: 200rpx;
  height: 200rpx;
  border: 1rpx solid #ccc;
  text-align: center;
  line-height: 200rpx;
}

.wrap .active {
  background-color: firebrick;
  color: #fff;
}

js:


// wxml中用不到的变量,没有放到data里面
let prize = '';         // 速度开始变化(变缓)的位置
let prizeId = '';       // 中奖位置
const cycle = 50;       // 基本转动次数
let speed = 30;         // 转动速度
let times = 0;          // 转动次数
let timer = null;       // 定时器ID
let click = false;      // 是否正在抽奖

Page({

  /**
   * 页面的初始数据
   */
  data: {
    activeIndex: -1,
  },

 
  // 点击开始
  start() {

    // 如果正在抽奖则直接return
    if (click) {
      return false;
    }

    click = true;
    speed = 100;

    // 中奖的位置,应该从服务端取到
    prizeId = Math.floor(Math.random() * 8);
    console.log('中奖位置:', prizeId)
    this.roll();
  },

  // 转动
  roll() {
    times += 1;
    this.setData({
      // 如果activeIndex是最后一个,则赋值0
      activeIndex: this.data.activeIndex >= 7 ? 0 : this.data.activeIndex + 1
    })

    if (times > cycle + 10 && this.data.activeIndex === prizeId) {
      // 最后滚动到中奖位置,停止滚动
      clearTimeout(timer);
      prize = -1;
      times = 0;
      click = false;
    } else {
      if (times < cycle) {
        // 一开始速度增加(speed越小速度越快)
        speed -= 20;
      } else if (times === cycle) {
        // 确定一个速度变化的位置,下一次滚动到此位置,速度明显变缓
        prize = Math.random() * 8 | 0;
      } else {
        // 滚动次数大于基本滚动次数并且到达上面确定的位置时,速度明显变缓
        if (times > cycle + 10 && ((prize === 0 && this.data.activeIndex === 7) || prize === this.data.activeIndex + 1)) {
          speed += 90;
        } else {
          // 滚动次数大于基本滚动次数,速度逐渐变缓
          speed += 30;
        }
      }

      // 控制速度在30
      if (speed < 30) {
        speed = 30;
      }

      timer = setTimeout(this.roll, speed);
    }
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    clearTimeout(timer);
  }
})