微信小程序实现抽奖大轮盘

最近遇到做活动抽奖要用转盘,记录下做个笔记。

最终效果图:

xml部分:

<view class="draw-container">
  <view class="draw-table-box">
    <image animation="{{animationData}}" src="{{tableBg}}" class="draw-table-bg"/>
    <image bindtap="tableroll" src="{{go}}" class="draw-table-go {{times?'':'draw-table-go-grey'}}"/>
  </view>
  <view>剩余抽奖次数: {{times}}</view>
</view>

css部分:

.draw-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-top: 40rpx;
}
.draw-table-box {
    width: 556rpx;
    height: 558rpx;
    position: relative;
}
.draw-table-bg {
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
}
.draw-table-go {
    width: 148rpx;
    height: 192rpx;
    position: absolute;
    z-index: 1;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
.draw-table-go-grey {
    filter: grayscale(100%);
    filter: gray;
}

js部分:

Page({
  data: {
    tableBg: 'https://o3pvuu23u.qnssl.com/2f9bddd9-bb82-47ed-bd0f-9b1bee4463b8.png',
    go: 'https://o3pvuu23u.qnssl.com/e36952f5-0458-467b-890c-61941877c0c9.png',
    animationData: {},
    singleDeg: 60, //单个奖项的角度
    i: 4, // 自测中奖初始值
    initDeg: 0,
    awards: [
      {id: 6, degree: '6等奖', name: 'iphone xs'},
      {id: 3, degree: '1等奖', name: '50积分'},
      {id: 4, degree: '2等奖', name: '10积分'},
      {id: 5, degree: '3等奖', name: '5积分'},
      {id: 2, degree: '4等奖', name: '2积分'},
      {id: 1, degree: '5等奖', name: '1积分'},
    ],
    times: 3,
    isClick: false, // 转盘转动时防止用户再次点击抽奖
  },
  onLoad() {
  },
  onShow() {
    // 创建一个动画实例
    var animation = wx.createAnimation({
      duration: 2000,
      timingFunction: 'ease',
    })
    this.animation = animation
  },
  tableroll() {
    if(this.data.isClick) return
    if(this.data.times<1) return
    console.log('触发抽奖=====')
    this.setData({
      isClick: true
    })
    let randomNum = Math.random()
    let deviation = randomNum > 0.5 ? randomNum - 0.1 : randomNum + 0.1
    this.mockDrawInfo().then((result) => {
      let res1 = this.data.awards.filter((item)=> {
        return item.degree == result.degree
      })
      this.data.i++
      if(this.data.i===7) {
        this.data.i = 1
      }
      console.log('mockDrawInfo==result=======res1[0]', result, res1[0])
      let rotateDeg = 60 * (res1[0].id - deviation) + 360
      console.log('rotateDeg===', rotateDeg, res1[0].id)
      let surplusDeg = (Math.floor(Math.random()*4) + 4) * 360
      this.animation.rotate(this.data.initDeg + rotateDeg + surplusDeg).step()
      this.data.initDeg += surplusDeg
      this.setData({
        animationData: this.animation.export(),
      })
      setTimeout(() => {
        this.setData({
          isClick: false,
          times:--this.data.times,
        })
      }, 2000)
    })
  },
  // 模拟中奖信息接口返回数据
  mockDrawInfo() {
    return new Promise((resolve, reject) => {
      setTimeout(() => { 
        resolve({degree: this.data.i+'等奖'})
      }, 1000)
    })
  }
})

以下是一个简单的微信小程序轮盘抽奖代码示例: 1. 在 `index.wxml` 文件中添加以下代码: ```html <canvas canvas-id="lottery" style="width: 100%; height: 100%;"></canvas> <button bindtap="startLottery">开始抽奖</button> ``` 2. 在 `index.js` 文件中添加以下代码: ```javascript Page({ data: { canvasWidth: 0, canvasHeight: 0, lotteryCtx: null, lotteryData: [ { id: 1, name: '奖品1' }, { id: 2, name: '奖品2' }, { id: 3, name: '奖品3' }, { id: 4, name: '奖品4' }, { id: 5, name: '奖品5' }, { id: 6, name: '奖品6' }, { id: 7, name: '奖品7' }, { id: 8, name: '奖品8' }, { id: 9, name: '奖品9' }, { id: 10, name: '奖品10' }, ], lotteryIndex: -1, lotteryResult: null, lotteryRunning: false, }, onReady: function () { const query = wx.createSelectorQuery(); query.select("#lottery").boundingClientRect((rect) => { this.setData({ canvasWidth: rect.width, canvasHeight: rect.height, }); const ctx = wx.createCanvasContext("lottery"); this.setData({ lotteryCtx: ctx, }); this.drawLottery(); }).exec(); }, drawLottery: function () { const ctx = this.data.lotteryCtx; const width = this.data.canvasWidth; const height = this.data.canvasHeight; // 绘制外圆 ctx.beginPath(); ctx.setStrokeStyle("#f5f5f5"); ctx.setLineWidth(0.5); ctx.arc(width / 2, height / 2, width / 2 - 10, 0, 2 * Math.PI); ctx.stroke(); ctx.closePath(); // 绘制内圆 ctx.beginPath(); ctx.setLineWidth(0.5); ctx.setStrokeStyle("#f5f5f5"); ctx.arc(width / 2, height / 2, width / 2 - 60, 0, 2 * Math.PI); ctx.stroke(); ctx.closePath(); // 绘制扇形 const data = this.data.lotteryData; const len = data.length; ctx.translate(width / 2, height / 2); const angle = 2 * Math.PI / len; for (let i = 0; i < len; i++) { ctx.beginPath(); ctx.moveTo(0, 0); ctx.setFillStyle("#fff"); ctx.arc(0, 0, width / 2 - 35, i * angle, (i + 1) * angle); ctx.closePath(); ctx.fill(); ctx.save(); ctx.rotate(i * angle + angle / 2); ctx.setFillStyle("#000"); ctx.setFontSize(16); ctx.setTextAlign("center"); ctx.setTextBaseline("middle"); ctx.fillText(data[i].name, 0, - width / 2 + 55); ctx.restore(); } ctx.draw(); }, startLottery: function () { if (this.data.lotteryRunning) { return; } this.setData({ lotteryRunning: true, }); const data = this.data.lotteryData; const len = data.length; const index = Math.floor(Math.random() * len); const angle = 360 / len; const startAngle = 270 - (index + 0.5) * angle; const endAngle = startAngle + 360 * 5 + angle; const ctx = this.data.lotteryCtx; const width = this.data.canvasWidth; const height = this.data.canvasHeight; const centerX = width / 2; const centerY = height / 2; const radius = width / 2 - 10; const step = 0.1; let currentAngle = startAngle; let currentStep = step; let timer = setInterval(() => { currentAngle += currentStep; if (currentAngle > endAngle) { clearInterval(timer); this.setData({ lotteryIndex: index, lotteryResult: data[index].name, lotteryRunning: false, }); wx.showModal({ title: '抽奖结果', content: data[index].name, showCancel: false, }); } else { currentStep += step; this.drawLottery(); ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.setFillStyle("#f5f5f5"); ctx.arc(centerX, centerY, radius, startAngle * Math.PI / 180, currentAngle * Math.PI / 180); ctx.closePath(); ctx.fill(); ctx.draw(true); } }, 20); }, }) ``` 3. 在 `index.wxss` 文件中添加以下代码: ```css button { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); } ``` 这样就可以在微信小程序实现一个简单的轮盘抽奖功能。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值