微信小程序實現圓心進度條

本文實例為大傢分享瞭微信小程序實現圓心進度條的具體代碼,供大傢參考,具體內容如下

一、創建項目結構

打開微信開發者工具創建一個項目, 新建 與 pages 同級目錄 components,在 components 中新建一個目錄 circle ,circle 中新建 Component 命名為 circle,此時將自動生成 json、wxml、wxss、js 4 個文件。結構如下:

二、編寫組件

首先需要在 json 文件中進行自定義組件聲明(將 component 字段設為 true,可將這一組文件設為自定義組件)。

{
"component": true
}

同時,還要在 wxml 文件中編寫組件模版,在 wxss 文件中加入組件樣式,這裡編寫圓環進度條的模板和樣式,參見微信小程序之圓形進度條。

要註意 canvas 繪制的是 px 為單位的,所以這裡統一用 px 單位;其中 size 是根據 canvas 繪制的圓環的直徑,後面在 js 中會提到。

在組件的 wxml 中可以包含 slot 節點,用於承載組件使用者提供的 wxml 結構。

<!-- components/circle/circle.wxml -->
<view class="circle_box" style="width:{{size}}px;height:{{size}}px">
          <canvas class="circle_bg" canvas-id="{{bg}}" style="width:{{size}}px;height:{{size}}px"></canvas> 
          <canvas class="circle_draw" canvas-id="{{draw}}" style="width:{{size}}px;height:{{size}}px"></canvas> 
          <slot></slot> 
</view>

註意:在組件 wxss 中不應使用 ID 選擇器、屬性選擇器和標簽名選擇器。

/* components/circle/circle.wxss */
.circle_box,.circle_draw{ position: relative; }
.circle_bg{position: absolute;}

編寫 js

在自定義組件的 js 文件中,需要使用 Component() 來註冊組件,並提供組件的屬性定義、內部數據和自定義方法。

組件的屬性值和內部數據將被用於組件 wxml 的渲染,其中,屬性值是可由組件外部傳入的。更多細節參考 Component 構造器。

/* components/circle/circle.js */
Component({
  ……
  methods: {
    /* id : canvas 組件的唯一標識符 canvas-id ,x : canvas 繪制圓形的半徑, w : canvas 繪制圓環的寬度  */
    drawCircleBg: function (id, x, w) {
      // 設置圓環外面盒子大小 寬高都等於圓環直徑
      this.setData({
        size: 2 * x
      });
      // 使用 wx.createContext 獲取繪圖上下文 ctx  繪制背景圓環
      var ctx = wx.createCanvasContext(id)
      ctx.setLineWidth(w / 2); ctx.setStrokeStyle('#20183b'); ctx.setLineCap('round')
      ctx.beginPath();//開始一個新的路徑
      //設置一個原點(x,y),半徑為r的圓的路徑到當前路徑 此處x=y=r
      ctx.arc(x, x, x - w, 0, 2 * Math.PI, false);
      ctx.stroke();//對當前路徑進行描邊
      ctx.draw();
    },
    drawCircle: function (id, x, w, step) {
      // 使用 wx.createContext 獲取繪圖上下文 context  繪制彩色進度條圓環
      var context = wx.createCanvasContext(id);
      // 設置漸變
      var gradient = context.createLinearGradient(2 * x, x, 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(x, x, x - w, -Math.PI / 2, step * Math.PI - Math.PI / 2, false);
      context.stroke();//對當前路徑進行描邊
      context.draw()
    },
    _runEvent() {
      //觸發自定義組件事件
      this.triggerEvent("runEvent")
    }
  },
  ……
})

自定義組件圓形進度條到此已經完成。

使用自定義組件

下面我們在 index 中使用自定義組件圓形進度條。

一、json 文件中進行引用聲明

使用已註冊的自定義組件前,首先要在頁面的 json 文件中進行引用聲明。此時需要提供每個自定義組件的標簽名和對應的自定義組件文件路徑:

{
  "usingComponents": {
    "circle": "/components/circle/circle"
  }
}

二、wxml 文件中使用自定義組件

這樣,在頁面的 wxml 中就可以像使用基礎組件一樣使用自定義組件。節點名即自定義組件的標簽名,節點屬性即傳遞給組件的屬性值。

  • 節點名即自定義組件的標簽名:circle;
  • 節點屬性即傳遞給組件的屬性值:bg,draw;
  • 當自定義組件觸發 runEvent 事件時,調用_runEvent 方法。
<!--index.wxml-->
<view class="container">
    <circle id='circle1'
      bg='circle_bg1'
      draw='circle_draw1'
      bind:runEvent="_runEvent" >
        <!-- 這部分內容將被放置在組件 <slot> 的位置上 -->
        <view class="circle_info" bindtap="changeTime">
             <view class="circle_dot"></view>
             <text class='circle_txt'> {{txt}} </text>
       </view>
    </circle>
</view>

自定義組件的 wxml 節點結構在與數據結合之後,將被插入到引用位置內。在 wxss 給 slot 位置上的內容添加一些樣式。

/**index.wxss**/
/*圓環進度條文字*/
.circle_info{
  position: absolute; 
  width: 100%;
  left: 50%;
  top: 50%; 
  transform: translate(-50%,-50%); 
  display: flex;  
  align-items: center;
  justify-content: center
}
.circle_dot{
  width:16rpx;
  height: 16rpx;  
  border-radius: 50%;
  background-color: #fb9126;
} 
.circle_txt{
  padding-left: 10rpx;
  color: #fff;
  font-size: 36rpx; 
  letter-spacing: 2rpx;
}

三、js 文件中調用自定義組件中的方法

在 wxml 中我們用到一個數據 {{txt}},我們需要在 js 中設置一下 data,然後在 onReady 中使用 selectComponent 選擇組件實例節點。

//index.js
 data: { 
    txt: "正在匹配中..." 
  },
 onReady: function () {
   // 獲得circle組件
    this.circle = this.selectComponent("#circle1");
    // 繪制背景圓環
    this.circle.drawCircleBg('circle_bg1', 100, 8)
    // 繪制彩色圓環 
    this.circle.drawCircle('circle_draw1', 100, 8, 2);  
  },

效果如下:

this.circle.drawCircle('circle_draw1', 100, 8, 0.5);

this.circle.drawCircle('circle_draw1', 100, 8, 1);

this.circle.drawCircle('circle_draw1', 100, 8, 2);

接下來要寫定時器方法瞭,在定時器中每隔一段時間調用一次 this.circle.drawCircle(id, x, w, step),通過改變 step 的值來動態繪制圓環。

1.在 data 中設置幾個初始值
2.定義一個定時器方法 countInterval,假設每隔 100 毫秒 count 遞增
+1,當 count 遞增到 100 的時候剛好是一個圓環,然後改變 txt 值並且清除定時器
3.在 onReady 中調用這個定時器方法

data: { 
    txt: "正在匹配中...",
    count: 0,//計數器,初始值為0
    maxCount: 100, // 繪制一個圓環所需的步驟 
    countTimer: null,//定時器,初始值為null
  },
   countInterval: function () {
    // 設置倒計時 定時器 假設每隔100毫秒 count遞增+1,當 count遞增到兩倍maxCount的時候剛好是一個圓環( step 從0到2為一周),然後改變txt值並且清除定時器
    this.countTimer = setInterval(() => {   
      if (this.data.count <= 2 * this.data.maxCount) {        
        // 繪制彩色圓環進度條
        this.circle.drawCircle('circle_draw1', 100, 8, this.data.count / this.data.maxCount)
        this.data.count++;
        } else {
        this.setData({
          txt: "匹配成功"
        });
         clearInterval(this.countTimer); 
      }
    }, 100)
  },
 onReady: function () {
   // 獲得circle組件
    this.circle = this.selectComponent("#circle1");
    // 繪制背景圓環
    this.circle.drawCircleBg('circle_bg1', 100, 8)
    // 繪制彩色圓環 
    // this.circle.drawCircle('circle_draw1', 100, 8, 2);  
    this.countInterval()
  },

最終效果

再次使用自定義組件做倒計時

count 可以遞增,當然可以遞減。這裡就不在贅述,直接上代碼:

wxml

<circle id='circle'
bg='circle_bg'
draw='circle_draw'
bind:runEvent="_runEvent" >
  <view class="circle_text" bindtap="changeTime">
  <text class='circle_time'> {{time}} s</text></view>
</circle>

wxss

/*圓環倒計時*/
.circle_text{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.circle_time{
color: #fff;
font-size: 32rpx;
padding-left: 16rpx;
}

js

const app = getApp()
Page({
  ……
  stepInterval: function () {
    var n = this.data.num / 2  // 設置倒計時 定時器
    this.stepTimer = setInterval(() => {
      if (this.data.num >= 0) {
        this.data.step = this.data.num / n;
        this.circle.drawCircle('circle_draw', 40, 4, this.data.step)// 繪制彩色圓環進度條
        if ((/(^[1-9]\d*$)/.test(this.data.num / 10))) {
          this.setData({ // 當時間為整數秒的時候 改變時間
            time: this.data.num / 10
          });
        }
        this.data.num--;
      } else {
        this.setData({
          time: 0
        });
      }
    }, 100)
  },
  changeTime: function () {
    clearInterval(this.stepTimer);
    this.setData({
      num: 100
    });
    this.stepInterval() // 重新開啟倒計時
    this._runEvent() // 觸發自定義組件事件
  },
  ……
})

最終效果

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: