柚子快報(bào)激活碼778899分享:微信小程序制作圓形進(jìn)度條
柚子快報(bào)激活碼778899分享:微信小程序制作圓形進(jìn)度條
微信小程序制作圓形進(jìn)度條
1. 建立文件夾
選擇一個(gè)目錄建立一個(gè)文件夾,比如 mycircle 吧,另外把對應(yīng) page 的相關(guān)文件都建立出來,包括 js,json,wxml 和 wxcc。
2. 開啟元件屬性
在 mycircle.json中開啟 component 屬性,確定我們這個(gè)頁面是一個(gè)可被調(diào)用的元件。
{
"component": true,
"usingComponents": {}
}
3. 建立 XML 樣式
在 mycircle.wxml文件中設(shè)計(jì)空間的樣式及接口參數(shù),也要注意一下 wxss 文件的樣式配合。
wxml 文件內(nèi)容為:
4. 在 js 文件中實(shí)現(xiàn)代碼
js 文件中先要定義出空間的屬性,設(shè)定默認(rèn)值以及對應(yīng)的方法,以便于在參數(shù)被修改后直接更新畫圖。
Component({
options: {
multipleSlots: true // 在組件定義時(shí)的選項(xiàng)中啟用多slot支持
},
properties: { //定義屬性,對外可以被調(diào)用和設(shè)置的屬性
draw: {//畫板元素名稱id
type: String,
value: 'draw',
observer:function(newVal,oldVal,change){
console.log(newVal, oldVal, change);
this.onreset(); //數(shù)值變化是所有重繪
}
},
per:{ //百分比 通過此值轉(zhuǎn)換成step
type: String,
value: '0',
observer:function(newVal,oldVal,change){
console.log(newVal, oldVal, change);
this.onreset();//數(shù)值變化是所有重繪
}
},
r:{//半徑
type: String,
value: '50',
observer:function(newVal,oldVal,change){
console.log(newVal, oldVal, change);
this.onreset();//數(shù)值變化是所有重繪
}
}
},
其中,observer 函數(shù)會(huì)在組件的屬性發(fā)生變化時(shí)被調(diào)用,調(diào)用后會(huì)打印一些調(diào)試信息,最終調(diào)用的是 onreset 函數(shù)。
接下來看看 onreset 函數(shù)的內(nèi)容:(這個(gè)在生命周期函數(shù)中也需要調(diào)用來刷新界面)
onreset: function () {
const _this = this;
//獲取屏幕寬度
wx.getSystemInfo({
success: function (res) {
_this.setData({
screenWidth: res.windowWidth
});
},
});
//初始化
const el = _this.data.draw; //畫板元素
const per = _this.data.per; //圓形進(jìn)度
const r = Number(_this.data.r); //圓形半徑
_this.setData({
step: (2 * Number(_this.data.per)) / 100, //這里將 0-100 轉(zhuǎn)換為 0-2
txt: _this.data.per
});
//獲取屏幕寬度(并把真正的半徑px轉(zhuǎn)成rpx)
let rpx = (_this.data.screenWidth / 750) * r; //真正的半徑
//計(jì)算出畫板大小
this.setData({
size: rpx * 2 //實(shí)際窗口的大小
});
const w = 10;//圓形的寬度
//組件入口,調(diào)用下面即可繪制 背景圓環(huán)和彩色圓環(huán)。
_this.drawCircleBg(el + 'bg', rpx, w);//繪制 背景圓環(huán)
_this.drawCircle(el, rpx, w, _this.data.step);//繪制 彩色圓環(huán)
}
onreset 函數(shù)主要功能是根據(jù)組件屬性的新值來重新繪制 canvas,首先獲取屏幕寬度,以便于計(jì)算相對的組件大小,從而適應(yīng)更多種類的屏幕。
最后將參數(shù)進(jìn)行轉(zhuǎn)換,比如百分比轉(zhuǎn)換成 0-2 之間的浮點(diǎn)數(shù)等。
最終設(shè)定圓形的寬度后調(diào)用 drawCircle 和 drawCircleBg 兩個(gè)函數(shù)來分別繪制前景圖和背景圖。
背景圖的繪制只是繪制一個(gè)灰色的圓環(huán),代碼相對簡單,這里使用了最新的 canvas API 接口:
drawCircleBg: function (el, r, w) {
const query = wx.createSelectorQuery().in(this);
//wx.createSelectorQuery()
query.select('#' + el) // 在 WXML 中填入的 id
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
// Canvas 畫布的實(shí)際繪制寬高
const width = res[0].width
const height = res[0].height
// 初始化畫布大小
const dpr = wx.getWindowInfo().pixelRatio
canvas.width = width * dpr
canvas.height = height * dpr
ctx.scale(dpr, dpr)
//繪制前清空畫布,原點(diǎn) + 長和寬,這里畫圓,因此清零 2r 的方塊
ctx.clearRect(0, 0, 2 * r, 2 * r);
ctx.lineWidth = w; // 設(shè)置圓環(huán)的寬度
ctx.strokeStyle = '#E5E5E5'; // 設(shè)置圓環(huán)的顏色
ctx.lineCap = 'round'; // 設(shè)置圓環(huán)端點(diǎn)的形狀
ctx.beginPath(); //開始一個(gè)新的路徑
// r,r為原點(diǎn),r-w 為半徑,從 0 弧度到 2pi 弧度,順時(shí)針(false)畫弧度。
ctx.arc(r, r, r - w, 0, 2 * Math.PI, false); //設(shè)定路徑
ctx.stroke();//對當(dāng)前路徑進(jìn)行描邊,真正的畫
}); // */
},
這里一下幾點(diǎn)注意:
查找組件要是用‘#’開頭 ,這是新的屬性定義的。query = wx.createSelectorQuery().in(this); 這里要是用 in(this)確保在 ready 期間可以找到組件。一定要初始化畫布大小,否則按照默認(rèn)大小畫出來的會(huì)變形。canvas 的一些方法變成了屬性,比如原來的 SetLineWidth 變成了 lineWidth,注意大小寫。
最后我們看一下前景圖的繪制
drawCircle: function (el, r, w, step) {
const query = wx.createSelectorQuery().in(this);
//wx.createSelectorQuery()
query.select('#' + el) // 在 WXML 中填入的 id
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node;
const context = canvas.getContext('2d');
// Canvas 畫布的實(shí)際繪制寬高
const width = res[0].width
const height = res[0].height
// 初始化畫布大小
const dpr = wx.getWindowInfo().pixelRatio
canvas.width = width * dpr
canvas.height = height * dpr
context.scale(dpr, dpr)
context.clearRect(0, 0, 2 * r, 2 * r);
// 設(shè)置漸變
var gradient = context.createLinearGradient(2 * r,2 * r, 0,0);
gradient.addColorStop("0", "#2661DD");
gradient.addColorStop("0.5", "#40ED94");
gradient.addColorStop("1.0", "#5956CC");
context.lineWidth = w; // 設(shè)置現(xiàn)線的寬度
context.strokeStyle = gradient; //設(shè)置顏色為漸變
context.lineCap = 'round'; //設(shè)置端點(diǎn)形狀
context.beginPath();//開始一個(gè)新的路徑
// step 從0到2為一周,注意 canvas 的坐標(biāo)方向,從-90°劃到正的 270°
context.arc(r, r, r - w, -Math.PI / 2, step * Math.PI - Math.PI / 2, false);
//context.stroke(); //對當(dāng)前路徑進(jìn)行描邊
step ? context.stroke() : ''; //當(dāng)step為空的時(shí)候不畫(0%)
})// */
},
前景圖的繪制區(qū)別于背景圖,它使用了漸變顏色,同時(shí)我們會(huì)根據(jù)參數(shù)中的 step 來進(jìn)行特定角度的弧線的繪制。
柚子快報(bào)激活碼778899分享:微信小程序制作圓形進(jìn)度條
好文鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。