如題,該小程序爲一款利用canvas實現的轉盤抽獎效果,今天我就來總結一下轉盤旋轉具體實現原理,首先還是上圖上代碼(一下代碼爲轉盤部分代碼,想要查看完整代碼,請移步支我的github,飛機票,點擊跳轉)
wxml代碼(中間轉盤部分代碼)
<view class="canvas-container" style='margin:0 auto;'>
<view animation="{{animationData}}" class="canvas-content" style='margin:0 auto;'>
<canvas style="width: 300px; height: 300px; margin:0 auto;" class="canvas-element" canvas-id="lotteryCanvas"></canvas>
<view class="canvas-line">
<view class="canvas-litem" wx:for="{{awardsList}}" wx:key="unique" style="-webkit-transform: rotate({{item.lineTurn}});transform: rotate({{item.lineTurn}})"></view>
</view>
<view class="canvas-list">
<view class="canvas-item" wx:for="{{awardsList}}" wx:key="unique">
<view class="canvas-item-text" style="-webkit-transform: rotate({{item.turn}});transform: rotate({{item.turn}})">
<text class='canvas-item-text-inner {{scale===1.4?"btnfont":"normal"}}'> {{item.award}}</text>
</view>
</view>
</view>
</view>
<view class="{{scale===1.4?'btnfont':'normal'}} canvas-btn {{turning?disabled:able}} {{chanceRemain==0?disabled:able}}"></view>
</view>
js代碼(轉盤部分代碼):
/**
* 抽獎處理函數:
*/
getLottery: function () {
var that = this;
if (that.data.count < 5) { //判斷用戶鑽石數量是否大於等於5
that.setData({
isShare: true
})
return
}
//減少鑽石數量:
this.setData({
count:that.data.count-5,
turning:true
});
setTimeout(function(){
that.setData({
turning:false
})
},4500)
var cot = that.data.count
// var awardIndex = Math.random() * 6 >>> 0;
// 獲取獎品配置
var awardsConfig = app.awardsConfig,
runNum = 4,
awardIndex=0;
// if (awardIndex < 2) awardsConfig.chance = false
// console.log(awardIndex)
//設置概率:隨機從數組中抽取一個數,數組中越大的數出現的次數越少,以此實現概率差異
var Parr = [150, 140, 100, 100, 60, 60, 60, 30, 30, 10, 10, 10, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2];
var PrandomNum = Math.random() * 78 >>> 0;
switch (Parr[PrandomNum]){
case 2:
awardIndex = 1
break
case 5:
awardIndex = 0
break
case 10:
awardIndex = 2
break
case 30:
awardIndex = 3
break
case 60:
awardIndex = 4
break
case 100:
awardIndex = 5
break
case 150:
awardIndex = 6
break
}
console.log("獎品序號:"+awardIndex);
// 旋轉抽獎
app.runDegs = app.runDegs || 0
console.log('deg', app.runDegs)
app.runDegs = app.runDegs + (360 - app.runDegs % 360) + (360 * runNum - awardIndex * (360 / 7))
console.log('deg', app.runDegs)
var animationRun = wx.createAnimation({
duration: 4000,
timingFunction: 'ease'
})
that.animationRun = animationRun
animationRun.rotate(app.runDegs).step()
that.setData({
animationData: animationRun.export()
})
// 記錄獎品
var winAwards = wx.getStorageSync('winAwards') || {data:[]}
winAwards.data.push(awardsConfig.awards[awardIndex].name + '1個')
wx.setStorageSync('winAwards', winAwards)
// 中獎提示
setTimeout(function() {
if(awardIndex == 0){
that.setData({
isHongbao: true
})
hongbao = Math.random().toFixed(4)
} else if(awardIndex == 1){
that.togglePopup3()
} else if(awardIndex == 2){
wx.showModal({
title: '恭喜',
content: '您獲得10鑽石',
showCancel: false
})
let timer = setInterval(function(){
that.setData({
count: that.data.count + 1
})
let a = parseInt(that.data.count - cot)
if(a==10){
clearInterval(timer)
}
},50)
} else if(awardIndex == 3){
that.setData({
isShare: true
})
return
} else if(awardIndex == 4){
wx.showModal({
title: '恭喜',
content: '您獲得寶箱',
showCancel: false
})
}else if(awardIndex == 5){
wx.showModal({
title: '恭喜',
content: '您獲得1元紅包已存入賬戶',
showCancel: false
})
let m = parseFloat(parseFloat(that.data.money) + 1).toFixed(4)
that.setData({
money: m
})
} else{
wx.showModal({
title: '恭喜',
content: '您獲得5元紅包已存入賬戶',
showCancel: false
})
let m = parseFloat(parseFloat(that.data.money) + 5).toFixed(4)
that.setData({
money: m
})
}
}, 4000);
},
onReady: function (e) {
var that = this;
wx.getSystemInfo({
success: function(res) {
that.setData({
contentHeight:res.windowHeight
});
if(res.windowWidth<360){
that.setData({
scale:0.9
})
}else if(res.windowWidth>500){
that.setData({
scale: 1.4
})
}
},
})
// getAwardsConfig
app.awardsConfig = {
count: 50,
awards:[
{ 'index': 0, 'name': '隨機紅包'},
{ 'index': 1, 'name': '幸運獎'},
{ 'index': 2, 'name': '10鑽'},
{ 'index': 3, 'name': '大量鑽石'},
{ 'index': 4, 'name': '寶箱'},
{ 'index': 5, 'name': '1元紅包' },
{ 'index': 6, 'name': '5元紅包'}
]
}
// wx.setStorageSync('awardsConfig', JSON.stringify(awardsConfig))
that.setData({
count: app.awardsConfig.count
})
// 繪製轉盤
var awardsConfig = app.awardsConfig.awards,
len = awardsConfig.length,
rotateDeg = 360 / len / 2 + 90,
html = [],
turnNum = 1 / len; // 文字旋轉 turn 值
var ctx = wx.createContext();
for (var i = 0; i < len; i++) {
// 保存當前狀態
ctx.save();
// 開始一條新路徑
ctx.beginPath();
// 位移到圓心,下面需要圍繞圓心旋轉
ctx.translate(150, 150);
// 從(0, 0)座標開始定義一條新的子路徑
ctx.moveTo(0, 0);
// 旋轉弧度,需將角度轉換爲弧度,使用 degrees * Math.PI/180 公式進行計算。
ctx.rotate((360 / len * i - rotateDeg) * Math.PI/180);
// 繪製圓弧
ctx.arc(0, 0, 150, 0, 2 * Math.PI / len, false);
// 顏色間隔
if (i % 2 == 0) {
ctx.setFillStyle('rgba(255,184,32,.1)');
}else{
ctx.setFillStyle('rgba(255,203,63,.1)');
}
// 填充扇形
ctx.fill();
// 繪製邊框
ctx.setLineWidth(0.5);
ctx.setStrokeStyle('rgba(228,55,14,.1)');
ctx.stroke();
// 恢復前一個狀態
ctx.restore();
// 獎項列表
html.push({ turn: i * turnNum + 'turn', lineTurn: i * turnNum + turnNum / 2 + 'turn', award: awardsConfig[i].name, img: awardsConfig[i].img });
};
that.setData({
awardsList: html
});
app.globalData.moneyData = {
count: that.data.count,
money: that.data.money
}
},
wxss代碼:
/* 轉盤 */
.canvas-container ul, .canvas-container li {
margin: 0;
padding: 0;
list-style: none;
}
.canvas-container {
padding: 2px;
margin: 0 auto;
position: relative;
left: 10rpx;
top: 0;
width: 330px;
height: 310px;
border-radius: 50%;
/*border: 2px solid #E44025;*/
}
.canvas-content {
box-sizing: content-box;
border: 2px solid rgb(255, 224, 151);
position: absolute;
left: 5px;
top: 5px;
z-index: 1;
display: block;
width: 300px;
height: 300px;
border-radius: inherit;
background-clip: padding-box;
background-color: rgb(255, 224, 151);
}
.canvas-element {
position: relative;
z-index: 1;
width: inherit;
height: inherit;
border-radius: 50%;
}
.canvas-list {
position: absolute;
left: 0;
top: 0;
width: inherit;
height: inherit;
z-index: 9999;
}
.canvas-item {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
color:rgb(228, 64, 37);
font-weight: bold;
}
.canvas-item-text {
position: relative;
display: block;
margin: 0 auto;
padding-top: 10rpx;
text-align: center;
-webkit-transform-origin: 50% 150px;
transform-origin: 50% 150px;
}