完整~小程序canvas制作幸运抽奖转盘

小程序转盘完整版

最近在做一款小程序幸运转盘抽奖,遇到了不少坑,分享一下
先看下效果图
数据都可以加载过来,此处数据为固定一个例子
wxml里面比较简单,但是canvas在真机上面显示会有问题,只需要生成你想要的canvas后转化为图片

<view class="turn-table">
		<image class="bg-turntable" src='{{turntableImage}}'  mode="widthFix"></image>
	  	<view>
	  		<view class='canvas-container'>
	  			<canvas style="position:fixed;left: -10000rpx;" disable-scroll="true" canvas-id='canvas' id="canvas-bg" class='canvas '></canvas>
	  			<image src='{{tempFilePath}}' style="-webkit-transform:rotate({{isRotate}}deg);transform:rotate({{isRotate}}deg);display: block;"  class='canvasI-image'></image>
	  		</view>
	  	</view>
	  	<view class="center-bg">
	  	 	<image class='start' src="../../../images/turntable/start.png" catchtap='{{trunBtn?"getStart":""}}'  mode="widthFix" />
	  	</view>
	</view>

wxss

.contaner{
  width: 100%;
  padding-bottom: 28rpx;
}
.bg-image{
  position: absolute;
  top: 0rpx;
  width: 100%;
}
.turn-table{
  margin: 0 auto;
  min-height: 574rpx;
  height: auto;
  margin-top: 442rpx;
  margin-bottom: 13rpx;
  position: relative;
}
.canvas{
  width: 600rpx;
  height: 600rpx;
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto auto;
 
  -webkit-transition:all 3s ease;
    /* Firefox 4 */
  -moz-transition:all 3s ease;
    /* Opera */
  -o-transition:all 3s ease;
   transition:all 3s ease;
}
.canvas-image{
  width: 556rpx;
  height: 556rpx;
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 10;
  margin: auto auto;
  
  -webkit-transition:all 3s ease;
    /* Firefox 4 */
  -moz-transition:all 3s ease;
    /* Opera */
  -o-transition:all 3s ease;
  transition:all 3s ease;
}
.canvas-container{
  width: 600rpx;
  height: 600rpx;
  margin: 0 auto;
}
.bg-turntable{
  display: block;
  width: 648rpx;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: 10;
  margin: auto auto;
}
.center-bg{
  position: absolute;
  width: 240rpx;
  height: 240rpx;
  z-index: 999;

  background: #fbd56d;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto auto;
  border-radius: 50%;
}
.start{
  position: absolute;
  width: 196rpx;
  height: 246rpx;
  left:22rpx;
  bottom: 22rpx;
  z-index: 999;
  margin: auto auto;
}

js部分

const app = getApp()
const ctx = wx.createCanvasContext("canvas", this); //创建id为canvas的绘图
var w1 = '';
var h1 = '';
Page({
    /**
       * 页面的初始数据
       */
    data: {
        turntableRegionId:0,
        trunBtn:true,//抽奖按钮是否可以点击
        itemsNum: 6, //大转盘等分数,可根据后台配置加载
        itemsArc: 0, //大转盘每等分角度
        coupons:[],//每个扇形中的文字填充
        isRotate: 0,
        turntableImage:'../../../images/turntable/timg.jpg'
        
    },

    handleChoujiang(){
        //调用抽奖接口,返回是否中奖字段,以及中奖区域
        let That = this;
        let turntableRegionId = 2 //本地暂且固定中奖区域2
        That.setData({
            isRotate:That.data.isRotate-That.data.isRotate%360 + (720 -Number(turntableRegionId-1)*That.data.itemsArc-0.5*That.data.itemsArc-90),
            turntableRegionId:turntableRegionId
        })
        That.handleStart(turntableRegionId)
    },

    handleStart(turntableRegionId) { 
        let that = this;
        // 指定获奖结果
        let n = that.data.isRotate; //传入指定区域生成的旋转角度
        n = n  + 1440; //1440为旋转基数,最低要旋转1440度,即4圈。rand-(rand%60) 这个是让指针永远停在扇形中心的算法。n + 是为了重复点击的时候有足够的旋转角度。
        that.setData({
            isRotate: n,
            trunBtn:true
        })
        setTimeout(function(){
             if(turntableRegionId>0){
                //弹窗中奖了提示
            }else{
                 //弹窗未中奖
            }
        },3000)
       
    },

    getGiftList(){
        let That = this;
        for (let i = 0; i < That.data.itemsNum; i++) {
            That.data.coupons.push({
                validateStatus:2,
                turntableRegionId:i+1,
                mainInfo:(i+1)+'等奖'
            })              
        }  
        let itemsArc = 360 / That.data.itemsNum;
        That.setData({
            coupons:That.data.coupons
        })
       
        That.setData({
            itemsArc
        }, function () {
            wx.createSelectorQuery().select('#canvas-bg').boundingClientRect(function (rect) {
                w1 = parseInt(rect.width / 2);
                h1 = parseInt(rect.height / 2);
                That.drawRegion(itemsArc);//每一份扇形的内部绘制。
            }).exec()
        })
    },
     
    drawRegion(e) {
        let that = this;
        let itemsArc = e;//每一份扇形的角度
        let num = that.data.itemsNum;//等分数量
        let itemArr = that.data.coupons;//放文字的数组
        for (let i = 0; i < num; i++) {
            ctx.beginPath();
            ctx.moveTo(w1, h1);
            ctx.arc(w1, h1, w1 - 2, itemsArc * i * Math.PI / 180, (itemsArc + itemsArc * i) * Math.PI / 180);//绘制扇形,默认从第四象限开始画,所以区域编号1的地方为三点钟开始位置
            ctx.closePath();
            const colorList = ['#01a1dd','#fffdec','#fe5921','#fffdec','#fccc00','#fffdec']
            ctx.setFillStyle(colorList[i%6]);
            ctx.fill();
            ctx.save();
            ctx.beginPath();
            ctx.translate(w1, h1);//将原点移至圆形圆心位置
            ctx.rotate((itemsArc * (i + 1+(num-2)*0.25)) * Math.PI / 180);//旋转文字
            if(num>=6){
                ctx.setFontSize(18);//设置文字字号大小
             }else{
                ctx.setFontSize(20);//设置文字字号大小
             }
            if(i%2==0){
                ctx.setFillStyle("#ffffff");//设置文字颜色
            }else{
                ctx.setFillStyle("#ff484c");//设置文字颜色
            }
            ctx.setTextAlign("center");//使文字垂直居中显示
            ctx.setTextBaseline("middle");//使文字水平居中显示
            
            if(itemArr[i].validateStatus=='5'){
                ctx.fillText('谢谢', 0, -(h1 * 0.80));
                ctx.setFontSize(18);//设置文字字号大小
                ctx.fillText('参与', 0,-(h1 * 0.65) );
                
            }else{
                if(itemArr[i].mainInfo.length<7){
                    ctx.setFontSize(18);//设置文字字号大小
                    ctx.fillText(itemArr[i].mainInfo, 0, -(h1 * 0.75));
                }else if(itemArr[i].mainInfo.length>=7&&itemArr[i].mainInfo.length<=10){
                    let len = Math.ceil(itemArr[i].mainInfo.length/2)
                    ctx.fillText(itemArr[i].mainInfo.slice(0,len), 0, -(h1 * 0.80));
                    ctx.fillText(itemArr[i].mainInfo.slice(len), 0, -(h1 * 0.65));
                    ctx.setFontSize(28);//设置文字字号大小
                }else{
                    let mainInfo = itemArr[i].mainInfo.slice(0,10)+'...'
                    ctx.fillText(mainInfo.slice(0,6), 0, -(h1 * 0.80));
                    ctx.fillText(mainInfo.slice(6,13), 0, -(h1 * 0.65));
                    ctx.setFontSize(28);//设置文字字号大小
                }
            } 
            ctx.restore();//保存绘图上下文,使上一个绘制的扇形保存住。
        }
        ctx.draw();
        setTimeout(function(){
                wx.canvasToTempFilePath({
                    x: 0,
                    y: 0,
                    width: 2*w1,
                    height: 2*h1,
                    destWidth: 8*w1,
                    destHeight: 8*h1,
                    canvasId: 'canvas',
                    success: function (res) {
                      var tempFilePath = res.tempFilePath;
                      that.setData({
                        tempFilePath:res.tempFilePath
                    })
                  console.log(tempFilePath)

                },
                fail:function(res){
                  console.log('----------  ', res)
                }
            })
            },300);
        ctx.draw(true);//参数为true的时候,保存当前画布的内容,继续绘制
    },

  /**
   * 生命周期函数--监听页面加载
   */
    onLoad: function (option) {

    },

    onShow(){

    },
     
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
    onReady: function () {
        var that = this;
        this.getGiftList()
    },
     
})

由于固定了中奖区域为2,所以每次指针转到的地方为二等奖~~~

猜你喜欢

转载自blog.csdn.net/weixin_43464837/article/details/83182122