思路
- 使用2個canvas 一個是背景圓環,一個是彩色圓環。
- 使用setInterval 讓彩色圓環逐步繪制。
在看我的文章前,必須先看 ,下面轉的文章,因為本文是在它們基礎上修改的.
它們的缺點為:
1.組件必須用js實例化 (如果我有一個任務列表,后面會顯示每個任務的進度,每個任務都必須實例化)
2.它們js實例化時,繪圖是用 px繪制,導致頁面用rpx布局,組件卻用px繪制.
修改后的組件
在components文件加下建立 circle組件,如圖
circle.js :
/* components/circle/circle.js */ Component({ options: { multipleSlots: true // 在組件定義時的選項中啟用多slot支持 }, properties: { draw: {//畫板元素名稱id type: String, value: 'draw' }, per:{ //百分比 通過此值轉換成step type: String, value: '0' }, r:{//半徑 type: String, value: '50' } }, data: { /* 私有數據,可用於模版渲染 */ step: 1, //用來算圓的弧度0-2 size:0, //畫板大小 screenWidth:750, //實際設備的寬度 txt:0 }, methods: { /** * el:畫圓的元素 * r:圓的半徑 * w:圓的寬度 * 功能:畫背景 */ drawCircleBg: function (el, r, w) { const ctx = wx.createCanvasContext(el,this); ctx.setLineWidth(w);// 設置圓環的寬度 ctx.setStrokeStyle('#E5E5E5'); // 設置圓環的顏色 ctx.setLineCap('round') // 設置圓環端點的形狀 ctx.beginPath();//開始一個新的路徑 ctx.arc(r, r, r - w, 0, 2 * Math.PI, false); //設置一個原點(110,110),半徑為100的圓的路徑到當前路徑 ctx.stroke();//對當前路徑進行描邊 ctx.draw(); }, /** * el:畫圓的元素 * r:圓的半徑 * w:圓的寬度 * step:圓的弧度 (0-2) * 功能:彩色圓環 */ drawCircle: function (el, r, w, step) { var context = wx.createCanvasContext(el,this); // 設置漸變 var gradient = context.createLinearGradient(2 * r, r, 0); gradient.addColorStop("0", "#2661DD"); gradient.addColorStop("0.5", "#40ED94"); gradient.addColorStop("1.0", "#5956CC"); context.setLineWidth(w); context.setStrokeStyle(gradient); context.setLineCap('round') context.beginPath();//開始一個新的路徑 // step 從0到2為一周 context.arc(r, r, r - w, -Math.PI / 2, step * Math.PI - Math.PI / 2, false); context.stroke();//對當前路徑進行描邊 context.draw() } }, lifetimes: { // 生命周期函數,可以為函數,或一個在methods段中定義的方法名 attached: function () { const _this = this; //獲取屏幕寬度 wx.getSystemInfo({ success: function(res) { _this.setData({ screenWidth: res.windowWidth }); }, }); //初始化 const el = _this.data.draw; //畫板元素 const per = _this.data.per; //圓形進度 const r = Number(_this.data.r); //圓形半徑 _this.setData({ step: (2 * Number(_this.data.per)) / 100, txt: _this.data.per }); //獲取屏幕寬度(並把真正的半徑px轉成rpx) let rpx = (_this.data.screenWidth / 750) * r; //計算出畫板大小 this.setData({ size: rpx * 2 }); const w = 4;//圓形的寬度 //組件入口,調用下面即可繪制 背景圓環和彩色圓環。 _this.drawCircleBg(el + 'bg', rpx, w);//繪制 背景圓環 _this.drawCircle(el, rpx, w, _this.data.step);//繪制 彩色圓環 } } })
circle.wxml :
<!-- components/circle/circle.wxml --> <view class="circle_box" style="width:{{size}}px;height:{{size}}px"> <canvas class="circle_bg" canvas-id="{{draw}}bg" style="width:{{size}}px;height:{{size}}px"></canvas> <canvas class="circle_draw" canvas-id="{{draw}}" style="width:{{size}}px;height:{{size}}px"></canvas> <text class='circle_txt'> {{txt}}% </text> </view>
circle.json :
{ "component": true, "usingComponents": {} }
circle.wxss :
.circle_box,.circle_draw{ position: relative; } .circle_bg{position: absolute;} .circle_box{ display: flex; flex-direction: row; justify-content: center; align-items: center; } .circle_txt{ position: absolute; font-size: 28rpx; }
調用 :
在所需頁面的XXX.json 先引入 組件
{ "usingComponents": { "circle": "/components/circle/circle" } }
wxml 使用組件
<circle draw='circwewle1' per = '40' r = '50'/> <circle draw='circwewle2' per = '10' r = '30'/> <circle draw='circwewle3' per = '20' r = '100'/> <circle draw='circwewle' per = '50' r = '60'/> <circle draw='circwewle' per = '90' r = '120'/> draw : 確定 canvas的id per : 進度百分比 (1-100) r: 圓的半徑 (按px,最終轉化成rpx)
結果:
轉 :
https://segmentfault.com/a/1190000013219501
https://segmentfault.com/a/1190000013242747?utm_source=tag-newest
參考微信自定義組件講解 : https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/