微信小程序之圓形進(jìn)度條(自定義組件)

思路

  1. 使用2個(gè)canvas 一個(gè)是背景圓環(huán),一個(gè)是彩色圓環(huán)。
  2. 使用setInterval 讓彩色圓環(huán)逐步繪制。
在看我的文章前,必須先看 ,下面轉(zhuǎn)的文章,因?yàn)楸疚氖窃谒鼈兓A(chǔ)上修改的.

它們的缺點(diǎn)為:
1.組件必須用js實(shí)例化 (如果我有一個(gè)任務(wù)列表,后面會(huì)顯示每個(gè)任務(wù)的進(jìn)度,每個(gè)任務(wù)都必須實(shí)例化)
2.它們js實(shí)例化時(shí),繪圖是用 px繪制,導(dǎo)致頁(yè)面用rpx布局,組件卻用px繪制.
修改后的組件

在components文件加下建立 circle組件,如圖
image.png

circle.js :
/* components/circle/circle.js */
Component({
  options: {
    multipleSlots: true // 在組件定義時(shí)的選項(xiàng)中啟用多slot支持
  },
  properties: {
    draw: {//畫板元素名稱id
      type: String,
      value: 'draw'
    },
    per:{ //百分比 通過(guò)此值轉(zhuǎn)換成step
      type: String,
      value: '0'
    },
    r:{//半徑
      type: String,
      value: '50'   
    }

  },

  data: { /*  私有數(shù)據(jù),可用于模版渲染 */
    step: 1, //用來(lái)算圓的弧度0-2
    size:0, //畫板大小
    screenWidth:750, //實(shí)際設(shè)備的寬度
    txt:0
  },
  methods: {

    /**
     * el:畫圓的元素
     * r:圓的半徑
     * w:圓的寬度
     * 功能:畫背景
     */
    drawCircleBg: function (el, r, w) {
      const ctx = wx.createCanvasContext(el,this);
      ctx.setLineWidth(w);// 設(shè)置圓環(huán)的寬度
      ctx.setStrokeStyle('#E5E5E5'); // 設(shè)置圓環(huán)的顏色
      ctx.setLineCap('round') // 設(shè)置圓環(huán)端點(diǎn)的形狀
      ctx.beginPath();//開始一個(gè)新的路徑
      ctx.arc(r, r, r - w, 0, 2 * Math.PI, false);
      //設(shè)置一個(gè)原點(diǎn)(110,110),半徑為100的圓的路徑到當(dāng)前路徑
      ctx.stroke();//對(duì)當(dāng)前路徑進(jìn)行描邊
      ctx.draw();

    },
        /**
     * el:畫圓的元素
     * r:圓的半徑
     * w:圓的寬度
     * step:圓的弧度 (0-2)
     * 功能:彩色圓環(huán)
     */
    drawCircle: function (el, r, w, step) {
      var context = wx.createCanvasContext(el,this);
      // 設(shè)置漸變
      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();//開始一個(gè)新的路徑
      // step 從0到2為一周
      context.arc(r, r, r - w, -Math.PI / 2, step * Math.PI - Math.PI / 2, false);
      context.stroke();//對(duì)當(dāng)前路徑進(jìn)行描邊
      context.draw()
    }

  },

  lifetimes: {
    // 生命周期函數(shù),可以為函數(shù),或一個(gè)在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; //圓形進(jìn)度
      const r = Number(_this.data.r); //圓形半徑
      
      _this.setData({
        step: (2 * Number(_this.data.per)) / 100,
        txt: _this.data.per
      });


      //獲取屏幕寬度(并把真正的半徑px轉(zhuǎn)成rpx)
      let rpx = (_this.data.screenWidth / 750) * r;
      //計(jì)算出畫板大小
      this.setData({
        size: rpx * 2
      });
      const w = 4;//圓形的寬度

      //組件入口,調(diào)用下面即可繪制 背景圓環(huán)和彩色圓環(huán)。
      _this.drawCircleBg(el + 'bg', rpx, w);//繪制 背景圓環(huán)
      _this.drawCircle(el, rpx, w, _this.data.step);//繪制 彩色圓環(huán)

    }

  }


})

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;
}

調(diào)用 :
在所需頁(yè)面的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 : 進(jìn)度百分比 (1-100)
r: 圓的半徑 (按px,最終轉(zhuǎn)化成rpx)

結(jié)果:

image.png

轉(zhuǎn) :
https://segmentfault.com/a/1190000013219501
https://segmentfault.com/a/1190000013242747?utm_source=tag-newest
參考微信自定義組件講解 : https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容