首頁 > 軟體

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

2022-06-30 14:00:15

本文範例為大家分享了微信小程式實現圓心進度條的具體程式碼,供大家參考,具體內容如下

一、建立專案結構

開啟微信開發者工具建立一個專案, 新建 與 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() // 觸發自定義元件事件
  },
  ……
})

最終效果

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com