第一篇關於Canvas環形進度條的博文獲得不少關注度,時隔這麼多日才發出第二篇關於Canvas的博文,並不是我懈怠了,而是最近公司比較忙,寫好的demo一直沒機會發,今天公司終於閒下來了,把我做好的demo整理一下發上來,給喜歡canvas的初學者看看,因爲本人也是初學者,所以一下內容僅供參考,有不理解的地方或者有更好的想法,都可以與我聯繫,互相探討一下。
決定寫這個幸運大轉盤是因爲網上的素材很有限,可能是因爲太簡單,大佬們都沒有發的很詳細,跑馬燈的介紹也是一星半點,現在我把我的思路和代碼給大家展示一下,希望能幫到大家。
按照慣例,先看效果圖。
下面是代碼:
wxml:
<view class='content'>
<canvas canvas-id='bgCanvas' id='canvas-bg' class='canvasII'></canvas>
<view class='canvasI' style="{{isRotate?'transform:rotate('+isRotate+'deg)':''}};">
<canvas canvas-id='canvasI' id="canvas-one" class='canvasI' ></canvas>
</view>
<cover-image class='start' src="/images/start.png" catchtap='start' />
</view>
wxss:
.content{
width: 90%;
height: 600rpx;
background-color: #666;
margin: 0 auto;
margin-top: 100rpx;
position: relative;
/* display: flex;
align-items: center;
justify-content: center; */
}
.canvasI{
width: 500rpx;
height: 500rpx;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto auto;
transition:all 3s ease;
}
.canvasII{
width: 600rpx;
height: 600rpx;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto auto;
}
.start{
position: absolute;
width: 100rpx;
height: 100rpx;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto auto;
}
js:
const ctx = wx.createCanvasContext("canvasI"); //創建id爲canvasI的繪圖
const ctx2 = wx.createCanvasContext("bgCanvas");//創建id爲bgCanvas的背景繪圖
var mytime;//跑馬燈定時器名稱
var lamp = 0; //判斷跑馬燈閃爍標記
var w2 = "";
var h2 = "";
var w1 = "";
var h1 = "";
Page({
/**
* 頁面的初始數據
*/
data: {
itemsNum: 6, //大轉盤等分數
itemsArc: 0, //大轉盤每等分角度
color: ["#FFB932", "#ffd57c"],//扇形的背景顏色交替;
text: ["一等獎", "二等獎", "三等獎", "四等獎", "五等獎", "六等獎"],//每個扇形中的文字填充
isRotate: 0,
},
start() { //點擊抽獎按鈕, 爲了達到慢速開始慢速結束的效果,在這裏使用css3的過渡效果
console.log("start");
// 五等獎:0
// 六等獎:300
// 一等獎:240
// 二等獎:180
// 三等獎:120
// 四等獎:60
let that = this;
// 指定獲獎結果
let n = that.data.isRotate; //傳入指定的旋轉角度,內部指定獲獎結果。在指定角度上加上旋轉基數模擬轉盤隨機旋轉。
//隨機獲獎結果
let rand = Math.random() * 1000;//取一個隨機的旋轉角度,使獲獎結果隨機化。
n = n + rand - (rand % 60) + 1440; //1440爲旋轉基數,最低要旋轉1440度,即4圈。rand-(rand%60) 這個是讓指針永遠停在扇形中心的算法。n + 是爲了重複點擊的時候有足夠的旋轉角度。
console.log(n % 360);
that.setData({
isRotate: n,
})
},
// startt() {
// let that = this;
// let n = that.data.isRotate; //傳入指定的旋轉角度,內部指定獲獎結果。在指定角度上加上旋轉基數模擬轉盤隨機旋轉。
// //隨機獲獎結果
// let rand = Math.random() * 1000;//取一個隨機的旋轉角度,使獲獎結果隨機化。
// n = n + rand - (rand % 60) + 1440; //1440爲旋轉基數,最低要旋轉1440度,即4圈。rand-(rand%60) 這個是讓指針永遠停在扇形中心的算法。n + 是爲了重複點擊的時候有足夠的旋轉角度。
// ctx.save();
// ctx.beginPath();
// ctx.rotate(w1, h1);
// ctx.rotate(n * Math.PI / 180);
// ctx.draw(true);
// },
/**
* 生命週期函數--監聽頁面加載
*/
onLoad: function (e) {
let that = this;
let itemsArc = 360 / that.data.itemsNum;//獲取大轉盤每等分的角度。
that.setData({
itemsArc
}, function () {
wx.createSelectorQuery().select('#canvas-one').boundingClientRect(function (rect) {
w1 = parseInt(rect.width / 2);
h1 = parseInt(rect.height / 2);
console.log("w1,h1", w1, h1)
that.Items(itemsArc);//每一份扇形的內部繪製。
}).exec()
mytime = setInterval(that.light, 1000);//啓動跑馬燈定時器。
})
},
/**
* 生命週期函數--監聽頁面初次渲染完成
*/
onReady: function () {
var that = this;
wx.createSelectorQuery().select('#canvas-bg').boundingClientRect(function (rect) {//監聽canvas的寬高
w2 = parseInt(rect.width / 2);//獲取canvas寬度的一半;
h2 = parseInt(rect.height / 2);//獲取canvas高度的一半
console.log(w2, h2); //獲取canvas寬高一半的原因是爲了便於找到中心點
that.light();
}).exec()
},
light() { //跑馬燈的繪製
let that = this;
let itemsNum = that.data.itemsNum;
lamp++;
if (lamp >= 2) {
lamp = 0
}
ctx2.beginPath();
ctx2.arc(w2, h2, w2, 0, 2 * Math.PI);//繪製底色爲紅色的圓形
ctx2.setFillStyle("#DF1E14");
ctx2.fill();
ctx2.beginPath();
ctx2.arc(w2, h2, w2 - 15, 0, 2 * Math.PI);//繪製底色爲深黃的圓形
ctx2.setFillStyle("#F5AD26");
ctx2.fill();
for (let i = 0; i < itemsNum * 2; i++) {//跑馬燈小圓圈比大圓盤等分數量多一倍。
ctx2.save();
ctx2.beginPath();
ctx2.translate(w2, h2);
ctx2.rotate(30 * i * Math.PI / 180);
ctx2.arc(0, w2 - 15, 8, 0, 2 * Math.PI);//繪製座標爲(0,-135)的圓形跑馬燈小圓圈。
//跑馬燈第一次閃爍時與第二次閃爍時繪製相反的顏色,再配上定時器循環閃爍就可以達到跑馬燈一閃一閃的效果了。
if (lamp == 0) { //第一次閃爍時偶數奇數的跑馬燈各繪製一種顏色
if (i % 2 == 0) {
ctx2.setFillStyle("#FBF1A9");
} else {
ctx2.setFillStyle("#fbb936");
}
} else { //第二次閃爍時偶數奇數的跑馬燈顏色對調。
if (i % 2 == 0) {
ctx2.setFillStyle("#fbb936");
} else {
ctx2.setFillStyle("#FBF1A9");
}
}
ctx2.fill();
ctx2.restore();//恢復之前保存的上下文,可以將循環出來的跑馬燈都保存下來。沒有這一句那麼每循環出一個跑馬燈則上一個跑馬燈繪圖將被覆蓋,
}
ctx2.draw();
},
Items(e) {
console.log("items,w1,h1", w1, h1)
let that = this;
let itemsArc = e;//每一份扇形的角度
let Num = that.data.itemsNum;//等分數量
let text = that.data.text;//放文字的數組
for (let i = 0; i < Num; i++) {
ctx.beginPath();
ctx.moveTo(w1, h1);
ctx.arc(w1, h1, w1 - 5, itemsArc * i * Math.PI / 180, (itemsArc + itemsArc * i) * Math.PI / 180);//繪製扇形,注意下一個扇形比上一個扇形多一個itemsArc的角度。
ctx.closePath();
if (i % 2 == 0) {//繪製偶數扇形和奇數扇形的顏色不同
ctx.setFillStyle(that.data.color[0]);
} else {
ctx.setFillStyle(that.data.color[1]);
}
ctx.fill();
ctx.save();
ctx.beginPath();
ctx.setFontSize(12);//設置文字字號大小
ctx.setFillStyle("#000");//設置文字顏色
ctx.setTextAlign("center");//使文字垂直居中顯示
ctx.setTextBaseline("middle");//使文字水平居中顯示
ctx.translate(w1, h1);//將原點移至圓形圓心位置
ctx.rotate((itemsArc * (i + 2)) * Math.PI / 180);//旋轉文字,從 i+2 開始,因爲扇形是從數學意義上的第四象限第一個開始的,文字目前的位置是在圓心正上方,所以起始位置要將其旋轉2個扇形的角度讓其與第一個扇形的位置一致。
ctx.fillText(text[i], 0, -(h1 * 0.8));
ctx.restore();//保存繪圖上下文,使上一個繪製的扇形保存住。
}
that.Images();
ctx.draw(true);//參數爲true的時候,保存當前畫布的內容,繼續繪製
},
Images() {//繪製獎品圖片,與繪製文字方法一致。
let that = this;
let itemsArc = that.data.itemsArc;
let Num = that.data.itemsNum;
for (let i = 0; i < Num; i++) {
ctx.save();
ctx.beginPath();
ctx.translate(w1, h1);
ctx.rotate(itemsArc * (i + 2) * Math.PI / 180);
ctx.drawImage("/images/quan.jpg", -(w1 * 0.2), -(h1 * 0.6), (w1 * 0.4), (h1 * 0.2));
ctx.restore();
}
},
/**
* 生命週期函數--監聽頁面顯示
*/
onShow: function () {
}
})
詳細的解釋我都我都寫在js裏邊了,有不理解的地方可以給我留言哦,下邊放上圖片資源:
今天的博文就到這裏了,希望能幫到各位,也希望能給我點個贊鼓勵鼓勵我~ 不然的話,我就要讓我大哥胖虎錘死在座各位的,包括躺着的和站着的!!