最近在做一款小程序幸运转盘抽奖,遇到了不少坑,分享一下
先看下效果图
wxml里面比较简单,但是canvas在真机上面显示会有问题,只需要生成你想要的canvas后转化为图片
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,所以每次指针转到的地方为二等奖~~~