微信小程序大转盘抽奖

1、样式

page {
  width: 100%;
  height: 100%;
}

.container {
  z-index: 1;
  padding-top: 220rpx;
  padding-bottom: 20rpx;
  box-sizing: border-box;
  height: 100%;
  
}

.plate-wrap-box {
  position: relative;
  z-index: 999;
  width: 500rpx;
  height: 500rpx;
  border-radius: 50%;
  margin: 0 auto 60rpx;
}

.plate-border {
  position: relative;
  z-index: 9;
  width: 500rpx;
  height: 500rpx;
  background-color: #22a7ca;
  border-radius: 50%;
}

.plate-wrap {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 9;
  width: 440rpx;
  height: 440rpx;
  border: 1rpx solid #1f0193;
  border-radius: 50%;
  overflow: hidden;
  margin: auto;
}

.plate-light {
  z-index: 1;
  width: 500rpx;
  height: 500rpx;
  border: none;
}

.plate-box {
  position: absolute;
  z-index: 1;
  left: 50%;
  width: 0;
  height: 0;
  font-size: 24rpx;
}

.bulb {
  position: absolute;
  width: 12rpx;
  height: 12rpx;
  left: 50%;
  top: -242rpx;
  transform: translate(-50%, 0);
  border-radius: 50%;
  background-color: #fdcf03;
  filter: blur(0.5rpx);
}

.text-box {
  position: absolute;
  text-align: center;
  display: inline-block;
  width: 15rpx;
  word-break: break-all;
  top: -200rpx;
  transform: translate(-100%, 0);
  font-size: 28rpx;
}

.plate-btn-wrap {
  position: absolute;
  z-index: 10;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 110rpx;
  height: 110rpx;
  border-radius: 50%;
}

.plate-btn-wrap::before {
  content: '';
  position: absolute;
  z-index: 9;
  left: calc(50% - 10rpx);
  top: -40rpx;
  transform: translate(-50%, 0);
  width: 0;
  height: 0;
  border-bottom: 80rpx solid #fdcf03;
  border-left: 20rpx solid transparent;
}

.plate-btn-wrap::after {
  content: '';
  position: absolute;
  z-index: 9;
  left: calc(50% + 10rpx);
  top: -40rpx;
  transform: translate(-50%, 0);
  width: 0;
  height: 0;
  border-bottom: 80rpx solid #fdcf03;
  border-right: 20rpx solid transparent;
}

.plate-btn-box {
  position: relative;
  z-index: 11;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: #ffe401;
  display: flex;
  justify-content: center;
  align-items: center;
}

.plate-inner-btn {
  position: relative;
  z-index: 999;
  width: 90rpx;
  height: 90rpx;
  border-radius: 50%;
  background-color: #fdcf03;
  font-size: 28rpx;
  font-weight: 800;
  color: #1f0193;
  display: flex;
  justify-content: center;
  align-items: center;
}

2、wxml文件

<view class="container">
  <view class="plate-wrap-box">
    <view class="plate-border" animation="{{ aniData }}">
      <!-- 转盘以及文字 -->
      <view class="plate-wrap">
        <view class="plate-box" wx:for="{{ lottery }}" wx:key="" style="top:-{{ (lottery.length - 6)<=2?(36+4*(lottery.length - 6)):50 }}rpx;transform-origin: 50% {{ (lottery.length - 6) <=2?(256+4*(lottery.length - 6)):270 }}rpx;border-top: {{ (lottery.length - 6) <=2?(256+4*(lottery.length - 6)):270 }}rpx solid #{{ index % 2==0?'1f0193':'22a7ca' }};transform:translate(-50%,0) rotate({{ 360 / lottery.length * ( index )}}deg);border-left: {{ 440 / lottery.length * 2 }}rpx solid transparent;border-right: {{ 440 / lottery.length * 2 }}rpx solid transparent;">
          <text class="text-box" style="color:#{{ index % 2==0?'fcff0c':'fcff0c' }}">{{ item }}</text>
        </view>
      </view>
      <!-- 边框的小灯泡 -->
      <view class="plate-wrap plate-light">
        <view class="plate-box" wx:for="{{ lottery }}" wx:key="" style="top:-{{ (lottery.length - 6)<=2?(44+4*(lottery.length - 6)):60 }}rpx; transform-origin: 50% {{ (lottery.length - 6) <=2?(294+4*(lottery.length - 6)):310 }}rpx;border-top: {{ (lottery.length - 6) <=2?(294+4*(lottery.length - 6)):310 }}rpx solid transparent;transform:translate(-50%,0) rotate({{ 360 / lottery.length * ( index )}}deg);border-left: {{ 500 / lottery.length * 2 }}rpx solid transparent;border-right: {{ 500 / lottery.length * 2 }}rpx solid transparent;">
          <view class="bulb"></view>
        </view>
      </view>
    </view>
    <view class="plate-btn-wrap" bindtap="startRollTap">
      <view class="plate-btn-box">
        <view class="plate-inner-btn">
          <text>GO</text>
        </view>
      </view>
    </view>

  </view>
</view>

3、js文件

let canRoll = true, //加控制,防止用户点击两次
  num = 1, //用在动画上,让用户在第二次点击的时候可以接着上次转动的角度继续转
  lotteryArrLen = 0, //放奖品的数组的长度
  lottery = ['奖品1', '奖品2','奖品3']; //放奖品
Page({
  data: {},

  onLoad(opt) {
    this.setPlateData(); //执行设置转盘表面的文字
    let that = this;
    let aniData = wx.createAnimation({ //创建动画对象
      duration: 2000,
      timingFunction: 'ease'
    });
    this.aniData = aniData; //将动画对象赋值给this的aniData属性
  },
  setPlateData() { //设置奖品数组
    lotteryArrLen = lottery.length; //获取奖品数组的长度,用来判断
    if (lotteryArrLen < 2) { //数组的奖品只有一个,扩展数组的长度到4
      let evenArr = new Array(4); //创建一个数组,方便操作。
      for (let i = 0; i < 4; i++) {
        if (i % 2 == 1) { //这里为什么要取1是为了在默认的界面将指针放在谢谢的地方,防止别人拿着中奖的截图来要奖品
          evenArr[i] = lottery[0]; //将原数组的内容赋值到新的数组
        } else {
          evenArr[i] = '谢谢' //在数组中间隔插入谢谢
        }
      }
      lottery = [...evenArr]; //将整合好的数组赋值给lottery数组
    } else { //数组中的奖品超过1个,则正常扩展数组,扩展的数组为原来的2倍
      let dataLen = 0; //用来放原来数组的索引
      let evenArr = new Array(lotteryArrLen * 2); //创建扩展数组
      for (let i = 0; i < (lotteryArrLen * 2); i++) {
        if (i % 2 == 1) {
          evenArr[i] = lottery[dataLen]; //将原来数组的值赋值给新数组
          dataLen++; //原来数组的索引加一
        } else {
          evenArr[i] = '谢谢'
        }
      }
      lottery = [...evenArr]; //将整合好的数组赋值给lottery数组
    }

    lotteryArrLen = lottery.length; //获取新的数组长度
    this.setData({
      lottery: lottery //设置好值,用于页面展示
    })
  },
  startRollTap() { //开始转盘
    let that = this;
    if (canRoll) {
      canRoll = false;
      let aniData = this.aniData; //获取this对象上的动画对象
      let rightNum = ~~(Math.random() * lotteryArrLen); //生成随机数
      console.log(`随机数是${rightNum}`);
      console.log(`奖品是:${lottery[rightNum]}`);
      aniData.rotate(3600 * num - 360 / lotteryArrLen * rightNum).step();     
      this.setData({
        aniData: aniData.export()
      })
      num++;
      canRoll = true;
    }
  }
})

4、可能大家会发现一个问题,就是每次回退再次进行抽奖页面扇形面积会增加一倍的奖品数量,后台加上真实数据就可以了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值