需求:在swiper輪播圖中做出如圖的弧形進度條,輪播的會員等級分别為白銀、黃金、鉑金、鑽石;
以下代碼會先展示一個弧形圖的代碼,之後會展示輪播圖中的弧形進度條代碼
單個弧形圖:
代碼
<view>
<block>
<view class='canvasBox' id = "canvasBox">
<canvas canvas-id="bgcanvas1" id="bgcanvas1" class='canvas'></canvas>
<canvas canvas-id="runCanvas1" id="runCanvas1" class='canvas'></canvas>
</view>
</block>
</view>
js
const app = getApp();
Component({
/**
* 元件的屬性清單
*/
properties: {
nowLevel:{
type: Number,
value: 0,
observer(nv, ov, path) {
if(nv){
}
}
},
levelList:{
type: Array,
observer(levelList, ov, path) {
// this.drawerbg("bgcanvas1",this.data.swiCurrent);// 擷取節點資訊
}
},
swiCurrent:{
type: Number,
value: 0,
observer(nv, ov, path) {
}
},
cardIndex: {
type: Number,
value: 0,
observer(nv, ov, path) {
}
}
},
/**
* 元件的初始資料
*/
data: {
// levelMembershipVo: {},
// loginState: app.globalData.loginState,
// levelList: app.globalData.levelList,
// gradeMember: app.globalData.gradeMember,
nowNum: 0,
canvasWidth: 0,
canvasHeight: 0
},
pageLifetimes: {
show: function() {
// 頁面被展示
},
},
lifetimes: {
ready: function(){
this.drawerbg("bgcanvas1",700,1000,0);// /參數(id,目前值,階段最高值,階段最低值)
this.runCanvas1("runCanvas1",700,1000,0) //參數(id,目前值,階段最高值,階段最低值)
}
},
observers: {
},
/**
* 元件的方法清單
*/
methods: {
drawerbg(id,now,end,start){
let that = this;
let ctx = wx.createCanvasContext(id,this);
const grd = ctx.createLinearGradient(20, 20, 300,300)
let topBorder;
let bottomBorder;
let textColor;
let botText;
grd.addColorStop(0.3, '#FF863D')//深
grd.addColorStop(0.42, '#FFF14B')
topBorder="#D29C54"
bottomBorder="#6D490B"
textColor="#A4825D"
botText="黃金會員"
wx.createSelectorQuery().in(this).select('#'+id).boundingClientRect(function (rect) { //監聽canvas的寬高
var w = parseInt(rect.width / 2); //擷取canvas寬的的一半
var h = parseInt(rect.height / 2); //擷取canvas高的一半,
that.setData({
canvasWidth: rect.width,
canvasHeight: rect.height
});
// arc(圓心x軸,圓心y軸,半徑機關像素,起始角度弧度制從x軸正方向開始,結束角度弧度制,true表示逆時針繪制)
ctx.arc(2*w/3*2, 2*h/3*1.8, 2*h/3*2.3, 0.833 * Math.PI, 1.35 * Math.PI,false ); //繪制圓形弧線 1.24
ctx.setStrokeStyle("#ffffff");
ctx.setLineWidth("2"); //設定線條寬度
ctx.setLineCap("round"); //設定線條端點樣式
ctx.stroke(); //對路徑進行描邊,也就是繪制線條。
ctx.closePath();
if(now < start){
//繪制下面黃色小圓
ctx.beginPath();
ctx.arc(w*0.62, 2*h/3*2.54,0.025*w,0,Math.PI*2,true);
ctx.fillStyle=bottomBorder;
ctx.closePath();
ctx.fill();
//繪制下面白色小圓
ctx.beginPath();
ctx.arc(w*0.62, 2*h/3*2.54,0.012*w,0,Math.PI*2,true);
ctx.fillStyle="#FFFFFF";
ctx.closePath();
ctx.fill();
}
if(now === start || now < start){
//繪制上面黃色小圓
ctx.beginPath();
ctx.arc(w*0.67, 2*h/3*0.73,0.025*w,0,Math.PI*2,true);
ctx.fillStyle=topBorder;
ctx.closePath();
ctx.fill();
//繪制上面白色小圓
ctx.beginPath();
ctx.arc(w*0.67, 2*h/3*0.73,0.012*w,0,Math.PI*2,true);
ctx.fillStyle="#FFFFFF";
ctx.closePath();
ctx.fill();
}
ctx.fillStyle=textColor;
// ctx.textAlign="right";
ctx.font="10px 微軟雅黑";
ctx.textAlign="center";
ctx.fillText("鉑金會員",w*0.84,2*h/3*0.7);
ctx.font="9px 微軟雅黑";
ctx.fillText(end,w*0.84,2*h/3*0.95);
ctx.font="10px 微軟雅黑";
ctx.fillText(botText,w*0.78,h*1.53);
ctx.font="9px 微軟雅黑";
ctx.fillText(start,w*0.78,h*1.7);
ctx.font="10px 微軟雅黑";
ctx.fillText("目前成長值",w*0.77,h*1);
ctx.font="9px 微軟雅黑";
ctx.fillText(now,w*0.77,h*1.15);
ctx.draw(); //開始繪制
}).exec();
},
runCanvas1(id,now,end,start){
let that = this;
let ctx = wx.createCanvasContext(id,this);
const grd = ctx.createLinearGradient(20, 20, 300,300)
let topBorder;
let bottomBorder;
grd.addColorStop(0.3, '#FF863D')//深
grd.addColorStop(0.42, '#FFF14B')
topBorder="#D29C54"
bottomBorder="#6D490B"
wx.createSelectorQuery().in(this).select('#'+id).boundingClientRect(function (rect) { //監聽canvas的寬高
let percent = (( now - start ) / ( end - start ));
if( percent < 0 || Object.is(percent,NaN) ){
percent = 0
}
var num =( 0.239 * percent + 0.9 ) //0.239由最高成長的弧度值1.139-最低成長的弧度值0.9
if((now > 0 || now > start) && (now < end )){
num = num;
}else if((now > 0 && (now > end)) || (now > 0 && (now === end))){
num = 1.139;
}else if(now < 0 || now < start){
num = 0.9;
}
var w = parseInt(rect.width / 2); //擷取canvas寬的的一半
var h = parseInt(rect.height / 2); //擷取canvas高的一半,
// arc(圓心x軸,圓心y軸,半徑機關像素,起始角度弧度制從x軸正方向開始,結束角度弧度制,true表示逆時針繪制)
ctx.arc(2*w/3*2, 2*h/3*1.8, 2*h/3*2.3, 0.833 * Math.PI, num * Math.PI,false ); //繪制圓形弧線
ctx.setLineWidth("4"); //設定線條寬度
ctx.setLineCap("round"); //設定線條端點樣式
ctx.strokeStyle = grd;
ctx.stroke(); //對路徑進行描邊,也就是繪制線條。
if(now === start || now > start){
//繪制下面黃色小圓
ctx.beginPath();
ctx.arc(w*0.62, 2*h/3*2.54,0.025*w,0,Math.PI*2,true);
ctx.fillStyle=bottomBorder;
ctx.closePath();
ctx.fill();
//繪制下面白色小圓
ctx.beginPath();
ctx.arc(w*0.62, 2*h/3*2.54,0.012*w,0,Math.PI*2,true);
ctx.fillStyle="#FFFFFF";
ctx.closePath();
ctx.fill();
}
if(now > start){
//繪制上面黃色小圓
ctx.beginPath();
ctx.arc(w*0.67, 2*h/3*0.73,0.025*w,0,Math.PI*2,true);
ctx.fillStyle=topBorder;
ctx.closePath();
ctx.fill();
//繪制上面白色小圓
ctx.beginPath();
ctx.arc(w*0.67, 2*h/3*0.73,0.012*w,0,Math.PI*2,true);
ctx.fillStyle="#FFFFFF";
ctx.closePath();
ctx.fill();
}
ctx.draw(); //開始繪制
}).exec();
},
}
})
輪播圖中的弧形圖:
html
<view>
<block>
<view class='canvasBox' id = "canvasBox">
<canvas canvas-id="bgcanvas1" id="bgcanvas1" class='canvas'></canvas>
<block wx:if="{{ swiCurrent === nowNum }}">
<canvas canvas-id="runCanvas1" id="runCanvas1" class='canvas'></canvas>
</block>
</view>
</block>
</view>
js
const app = getApp();
Component({
/**
* 元件的屬性清單
*/
properties: {
swiCurrent:{ //目前swiper所在的索引
type: Number,
value: 1,
observer(nv, ov, path) {
}
},
},
/**
* 元件的初始資料
*/
data: {
// levelMembershipVo: {},
// loginState: app.globalData.loginState,
levelList: [
{
id:5,
name:"白銀會員",
levelMinGrowthValue:0,
levelMaxGrowthValue:1000
},
{
id:6,
name:"黃金會員",
levelMinGrowthValue:1001,
levelMaxGrowthValue:6000
},
{
id:7,
name:"鉑金會員",
levelMinGrowthValue:6001,
levelMaxGrowthValue:15000
},
{
id:8,
name:"鑽石會員",
levelMinGrowthValue:15001,
levelMaxGrowthValue:null
}
],
// gradeMember: app.globalData.gradeMember,
nowNum: 1, //目前的等級
canvasWidth: 0,
canvasHeight: 0
},
pageLifetimes: {
show: function() {
// 頁面被展示
},
},
lifetimes: {
// attached: async function () {
// this.setData({
// levelMembershipVo: app.globalData.levelMembershipVo,
// gradeMember: app.globalData.gradeMember,
// nowNum: this.checkNumber(app.globalData.gradeMember)
// });
// },
ready: function(){
console.log("swiCurrent",this.data.swiCurrent)
this.drawerbg("bgcanvas1",this.data.swiCurrent,500);// 參數(id,目前的swiCurrent,目前值)
this.runCanvas1("runCanvas1",500,1000,0,this.data.swiCurrent) //(id,目前值,階段最高值,階段最低值,目前的swiCurrent)
}
},
observers: {
},
/**
* 元件的方法清單
*/
methods: {
drawerbg(id,currenLevel,now){
let that = this;
let ctx = wx.createCanvasContext(id,this);
const grd = ctx.createLinearGradient(20, 20, 300,300)
let topBorder;
let bottomBorder;
let textColor;
let botText;
if(currenLevel===0){//白銀會員
grd.addColorStop(0.3, '#DDDEDE')
grd.addColorStop(0.52, '#DDDEDE')
topBorder="#B2B2B2"
bottomBorder="#000000"
textColor="#888888"
botText="白銀會員"
}else if(currenLevel===1){//黃金會員
grd.addColorStop(0.3, '#FF863D')//深
grd.addColorStop(0.42, '#FFF14B')
topBorder="#D29C54"
bottomBorder="#6D490B"
textColor="#A4825D"
botText="黃金會員"
}else if(currenLevel===2){//鉑金會員
grd.addColorStop(0.3, '#3660A7')
grd.addColorStop(0.42, '#84BAE5')
topBorder="#7295E5"
bottomBorder="#295283"
textColor="#5F6B91"
botText="鉑金會員"
}else if(currenLevel===3){//鑽石會員
grd.addColorStop(0.3, '#8A53C8')
grd.addColorStop(0.42, '#A08FE7')
topBorder="#A97CE5"
bottomBorder="#381B6B"
textColor="#75639B"
botText="鑽石會員"
}
wx.createSelectorQuery().in(this).select('#'+id).boundingClientRect(function (rect) { //監聽canvas的寬高
var w = parseInt(rect.width / 2); //擷取canvas寬的的一半
var h = parseInt(rect.height / 2); //擷取canvas高的一半,
that.setData({
canvasWidth: rect.width,
canvasHeight: rect.height
});
// arc(圓心x軸,圓心y軸,半徑機關像素,起始角度弧度制從x軸正方向開始,結束角度弧度制,true表示逆時針繪制)
ctx.arc(2*w/3*2, 2*h/3*1.8, 2*h/3*2.3, 0.833 * Math.PI, 1.35 * Math.PI,false ); //繪制圓形弧線 1.24
ctx.setStrokeStyle("#ffffff");
ctx.setLineWidth("2"); //設定線條寬度
ctx.setLineCap("round"); //設定線條端點樣式
ctx.stroke(); //對路徑進行描邊,也就是繪制線條。
ctx.closePath();
let levelMaxGrowthValue = ( that.data.levelList[that.data.swiCurrent].levelMaxGrowthValue || 0) + 1
let levelMinGrowthValue= that.data.levelList[that.data.swiCurrent].levelMinGrowthValue || 0
if(now === levelMinGrowthValue || now > levelMinGrowthValue){
//繪制下面黃色小圓
ctx.beginPath();
ctx.arc(w*0.62, 2*h/3*2.54,0.025*w,0,Math.PI*2,true);
ctx.fillStyle=bottomBorder;
ctx.closePath();
ctx.fill();
//繪制下面白色小圓
ctx.beginPath();
ctx.arc(w*0.62, 2*h/3*2.54,0.012*w,0,Math.PI*2,true);
ctx.fillStyle="#FFFFFF";
ctx.closePath();
ctx.fill();
}
if( that.data.swiCurrent !== 3 && (now === levelMinGrowthValue || now < levelMinGrowthValue)){
//繪制上面黃色小圓
ctx.beginPath();
ctx.arc(w*0.67, 2*h/3*0.73,0.025*w,0,Math.PI*2,true);
ctx.fillStyle=topBorder;
ctx.closePath();
ctx.fill();
//繪制上面白色小圓
ctx.beginPath();
ctx.arc(w*0.67, 2*h/3*0.73,0.012*w,0,Math.PI*2,true);
ctx.fillStyle="#FFFFFF";
ctx.closePath();
ctx.fill();
}
ctx.fillStyle=textColor;
// ctx.textAlign="right";
ctx.font="10px 微軟雅黑";
// ctx.fillText("目前",w*0.5,h*1.25);
// ctx.fillText(now,w*0.5,h*1.45);
ctx.textAlign="center";
if( that.data.swiCurrent ===3 ){
levelMaxGrowthValue = 25000
}
if( that.data.swiCurrent !==3 ){
if(currenLevel===0){//白銀會員
ctx.fillText("黃金會員",w*0.84,2*h/3*0.7);
}else if(currenLevel===1){//黃金會員
ctx.fillText("鉑金會員",w*0.84,2*h/3*0.7);
}else if(currenLevel===2){//鉑金會員
ctx.fillText("鑽石會員",w*0.84,2*h/3*0.7);
}
ctx.font="9px 微軟雅黑";
ctx.fillText(levelMaxGrowthValue,w*0.84,2*h/3*0.95);
}
ctx.font="10px 微軟雅黑";
ctx.fillText(botText,w*0.78,h*1.53);
ctx.font="9px 微軟雅黑";
ctx.fillText(levelMinGrowthValue,w*0.78,h*1.7);
if(that.data.swiCurrent === that.data.nowNum && now){
ctx.font="10px 微軟雅黑";
ctx.fillText("目前成長值",w*0.77,h*1);
ctx.font="9px 微軟雅黑";
ctx.fillText(now,w*0.77,h*1.15);
}
ctx.draw(); //開始繪制
}).exec();
},
runCanvas1(id,now,end,start,currenLevel){
let that = this;
let ctx = wx.createCanvasContext(id,this);
const grd = ctx.createLinearGradient(20, 20, 300,300)
let topBorder;
let bottomBorder;
if(currenLevel===0){//白銀會員
grd.addColorStop(0.3, '#DDDEDE')
grd.addColorStop(0.52, '#DDDEDE')
topBorder="#B2B2B2"
bottomBorder="#000000"
}else if(currenLevel===1){//黃金會員
grd.addColorStop(0.3, '#FF863D')//深
grd.addColorStop(0.42, '#FFF14B')
topBorder="#D29C54"
bottomBorder="#6D490B"
}else if(currenLevel===2){//鉑金會員
grd.addColorStop(0.3, '#3660A7')
grd.addColorStop(0.42, '#84BAE5')
topBorder="#7295E5"
bottomBorder="#295283"
}else if(currenLevel===3){//鑽石會員
grd.addColorStop(0.3, '#8A53C8')
grd.addColorStop(0.42, '#A08FE7')
topBorder="#A97CE5"
bottomBorder="#381B6B"
}
wx.createSelectorQuery().in(this).select('#'+id).boundingClientRect(function (rect) { //監聽canvas的寬高
let percent = (( now - start ) / ( end - start ));
if( percent < 0 || Object.is(percent,NaN) ){
percent = 0
}
console.log("percent===",percent)
var num =( 0.239 * percent + 0.9 ) //0.23由最高成長的弧度值1.12-最低成長的弧度值0.9
// var num =1.15
if( currenLevel === 3 ){
end = 25000;
}
console.log("end",end)
if((now > 0 || now > start) && (now < end )){
num = num;
}else if((now > 0 && (now > end)) || (now > 0 && (now === end))){
num = 1.139;
}else if(now < 0 || now < start){
num = 0.9;
}
console.log("num",num)
var w = parseInt(rect.width / 2); //擷取canvas寬的的一半
var h = parseInt(rect.height / 2); //擷取canvas高的一半,
// arc(圓心x軸,圓心y軸,半徑機關像素,起始角度弧度制從x軸正方向開始,結束角度弧度制,true表示逆時針繪制)
ctx.arc(2*w/3*2, 2*h/3*1.8, 2*h/3*2.3, 0.833 * Math.PI, num * Math.PI,false ); //繪制圓形弧線
ctx.setLineWidth("4"); //設定線條寬度
ctx.setLineCap("round"); //設定線條端點樣式
ctx.strokeStyle = grd;
ctx.stroke(); //對路徑進行描邊,也就是繪制線條。
if( that.data.swiCurrent === that.data.nowNum || that.data.cardIndex !== 1){
//繪制下面黃色小圓
ctx.beginPath();
ctx.arc(w*0.62, 2*h/3*2.54,0.025*w,0,Math.PI*2,true);
ctx.fillStyle=bottomBorder;
ctx.closePath();
ctx.fill();
//繪制下面白色小圓
ctx.beginPath();
ctx.arc(w*0.62, 2*h/3*2.54,0.012*w,0,Math.PI*2,true);
ctx.fillStyle="#FFFFFF";
ctx.closePath();
ctx.fill();
if( that.data.swiCurrent !== 3 ){
//繪制上面黃色小圓
ctx.beginPath();
ctx.arc(w*0.67, 2*h/3*0.73,0.025*w,0,Math.PI*2,true);
ctx.fillStyle=topBorder;
ctx.closePath();
ctx.fill();
//繪制上面白色小圓
ctx.beginPath();
ctx.arc(w*0.67, 2*h/3*0.73,0.012*w,0,Math.PI*2,true);
ctx.fillStyle="#FFFFFF";
ctx.closePath();
ctx.fill();
}
}
ctx.draw(); //開始繪制
}).exec();
},
}
})