// luckRoll.wxml<view class="canvas-container" style="transform: rotate({{isRotate}}deg)">    <canvas disable-scroll="true" canvas-id='canvas' id="canvas-bg" class='canvas '></canvas>    <image src="{{tempFilePath}}"></image></view>

须要定义的数据

// luckRoll.jsdata: {    trunBtn: false,//抽奖按钮是否能够点击    itemsNum: 3, //大转盘等分数,可依据后盾配置加载    itemsArc: 0, //大转盘每等分角度    coupons: [],//每个扇形中的文字填充    isRotate: -180, // 初始旋转角度}

创立一个canvas对象,因为它是个组件,所以在传入转盘数据的时候,初始化canvas

properties: {    rollOptions: {        type: Array,        observer(val) {            if(val.length > 0) {                this.setData({                    coupons: val,                    itemsNum: val.length                })                const ctx = wx.createCanvasContext("canvas", this); //创立id为canvas的绘图                this.getGiftList(ctx)            }        }    }},getGiftList(ctx) {    let that = this;    let itemsArc = 360/that.data.itemsNum    that.setData({        itemsArc    }, function () {        const query = wx.createSelectorQuery().in(that)        query.select('#canvas-bg').boundingClientRect()        query.exec(function (rect) {            w1 = parseInt(rect[0].width / 2);            h1 = parseInt(rect[0].height / 2);            that.drawRegion(itemsArc, ctx);//每一份扇形的外部绘制。        })    })}

绘制扇形

drawRegion(e, ctx) {    let that = this;    let itemsArc = e;//每一份扇形的角度    let num = that.data.itemsNum;//等分数量    let itemArr = that.data.coupons.map(item=>item.name);//放文字的数组    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 = ['#7cd8e3', '#ffffff']        ctx.setFillStyle(colorList[i % 2]);        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("#7cd8e3");//设置文字色彩        }        ctx.setTextAlign("center");//使文字垂直居中显示        ctx.setTextBaseline("middle");//使文字水平居中显示        if (itemArr[i].length < 7) {            ctx.setFontSize(12);//设置文字字号大小            ctx.fillText(itemArr[i], 0, -(h1 * 0.75));        } else if (itemArr[i].length >= 7 && itemArr[i].length <= 10) {            let len = Math.ceil(itemArr[i].length / 2)            ctx.fillText(itemArr[i].slice(0, len), 0, -(h1 * 0.80));            ctx.fillText(itemArr[i].slice(len), 0, -(h1 * 0.65));            ctx.setFontSize(20);//设置文字字号大小        } else {            let mainInfo = itemArr[i].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(20);//设置文字字号大小        }        ctx.restore();//保留绘图上下文,使上一个绘制的扇形保留住。    }    ctx.draw();    setTimeout(()=>{        wx.canvasToTempFilePath({            x: 0,            y: 0,            width: 2 * w1,            height: 2 * h1,            destWidth: 8 * w1,            destHeight: 8 * h1,            fileType: 'jpg',             quality: 1,//图片的品质,目前仅对 jpg 无效。取值范畴为 (0, 1],不在范畴内时当作 1.0 解决。            canvasId: 'canvas',            success: function (res) {                var tempFilePath = res.tempFilePath;                that.setData({                    tempFilePath: res.tempFilePath                })            },            fail: function (res) {                console.log('----------  ', res)            }        }, that)    },1000)    ctx.draw(true);//参数为true的时候,保留以后画布的内容,持续绘制}
wx.canvasToTempFilePath 特地重要,必须将canvas转换为图片在页面上渲染,不然会呈现各种问题,canvas用translateY移出页面显示

另外wx.canvasToTempFilePath必须写在setTimeout外面,不然安卓机的图片是黑屏

下面转盘曾经画成,上面就要转动起来

startRoll(index) {    let that = this;    let turntableRegionId = index+1    let rotate = that.data.isRotate - that.data.isRotate % 360 + (720 - Number(turntableRegionId - 1) * that.data.itemsArc - 0.5 * that.data.itemsArc - 90)    // 转动过程写在css动画外面,时长3s    that.setData({        isRotate: rotate + 2160    })    let cur = that.data.coupons[index]    let isBingo = !!cur.isPrize    let award = cur.name    that.setData({        isBingo: isBingo, // 是否中奖        award: award // 奖品    })    setTimeout(()=>{        //3S后显示最终后果弹窗        that.setData({            dialogShow: true        })    },3000)}

其余细节,我的项目不同再另外写
外围css

.canvas-container {    width: 550rpx;    height: 550rpx;    transition:all 3s ease;    position: absolute;    top: 45rpx;    left: 110rpx;    z-index: 1;    border-radius: 50%;    overflow: hidden;}.canvas{    width: 550rpx;    height: 550rpx;    display: block;    position: fixed;    left: -5000px;}