【微信小程序】自適應Canvas 環形進度條 內附代碼和詳解

本人之前也從來沒接觸過canvas,但是由於對canvas寫出來的各種酷炫效果非常仰慕,所以對canvas抱有濃厚的興趣。今天嘗試用canvas寫一個最常用的環形進度條,算是我對於canvas的入門。

下面先看效果圖:

直接上代碼:

wxml:

 <view class='content'> 
  <canvas canvas-id='bgCanvas' id='canvas-one'  class='canvasI'></canvas>
  <canvas canvas-id="runCanvas" class='canvasII'></canvas>
  <button size='mini' type='default' class='btn' style='padding:0;' catchtap='canvasTap'>點擊繪製</button>
 </view>   

wxss:

.content{
  width: 90%;
  height: 600rpx;
  background-color: #666;
  margin: 0 auto;
  margin-top: 100rpx;
  position: relative;
}
.canvasI{
  width: 400rpx;
  height: 400rpx;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  margin: auto auto;
}
.canvasII{
  width: 400rpx;
  height: 400rpx;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  margin: auto auto;
}
.btn{
  position: absolute;
  width: 200rpx;
  bottom: 30rpx;
  left: 0;
  right: 0;
  margin: 0 auto;
  text-align: center;
}

js:

const ctx = wx.createCanvasContext("bgCanvas"); //創建一個全局的canvas繪圖上下文
const ctx2 = wx.createCanvasContext("runCanvas");
let mytime = "";
let n = 0;
var w = "";
var h = "";
Page({

  /**
   * 頁面的初始數據
   */
  data: {
    score: 100, //傳入的進度, 0~100,繪製到此參數處停止。
  },
  run(e) {
    let that = this;
    let src = that.data.src; //每個間隔所需繪製的弧度
    let allSrc = that.data.allSrc; //總共需要繪製的弧度
    n++;
    if (src * n > allSrc) {
      clearInterval(mytime); //如果繪製完成,停掉計時器,繪製結束
      n = 0;
      return;
    }
    console.log(n);
    let grade = Math.round(src * n / 1.5 * 100); //百分數
    ctx2.arc(w, h, w - 8, 0.75 * Math.PI, (0.75 + src * n) * Math.PI); //每個間隔繪製的弧度
    ctx2.setStrokeStyle("#84D944");
    ctx2.setLineWidth("8");
    ctx2.setLineCap("round");
    ctx2.stroke();
    ctx2.beginPath();
    ctx2.setFontSize(40); //注意不要加引號
    ctx2.setFillStyle("#84D944");
    ctx2.setTextAlign("center");
    ctx2.setTextBaseline("middle");
    ctx2.fillText(grade + "%", w, h);


    ctx2.draw();
  },
  canvasTap() {
    let that = this;
    clearInterval(mytime);
    mytime = setInterval(that.run, 50)
  },

  /**
   * 生命週期函數--監聽頁面加載
   */
  onLoad: function (e) {
    let that = this;
    let allSrc = 0.015 * that.data.score; //應該繪製的弧度
    let src = allSrc / 100 //計算出每個間隔應該繪製多少弧度。 
    that.setData({
      src: src,
      allSrc: allSrc
    })
  },

  /**
   * 生命週期函數--監聽頁面初次渲染完成
   */
  onReady: function () {
    wx.createSelectorQuery().select('#canvas-one').boundingClientRect(function (rect) {//監聽canvas的寬高
      console.log(rect);
      w = parseInt(rect.width / 2); //獲取canvas寬的的一半
      h = parseInt(rect.height / 2); //獲取canvas高的一半,
      //獲取寬高的一半是爲了便於找到中心點

      ctx.arc(w, h, w - 8, 0.75 * Math.PI, 2.25 * Math.PI); //繪製圓形弧線
      ctx.setStrokeStyle("#dddddd"); //設置填充線條顏色
      ctx.setLineWidth("8");     //設置線條寬度
      ctx.setLineCap("round");        //設置線條端點樣式
      ctx.stroke();     //對路徑進行描邊,也就是繪製線條。

      ctx.draw();       //開始繪製
    }).exec()



  }
})

代碼思路:

1、創建兩個canvas,一個作爲背景,繪製灰色的進度條,一個作爲進度採用亮色的進度條對進度進行繪製。

2、用定位使兩個畫布重合。採用定時器讓畫布進行逐幀繪製。

注意:

1、利用arc繪製圓形,arc的參數依次爲(圓心X座標,圓心Y座標,半徑,起始位置,終點位置);

      起始點和終止點可以參考下圖:

2、讓canvas中繪製的文字居中的方法:

 

ctx2.setTextAlign("center"); 讓創建的文字水平居中

ctx2.setTextBaseline("middle"); 讓創建的文字垂直居中

ctx2.fillText("文字", 100,100);

在設置好文字水平垂直居中後,最重要的一步,要在fillText中的後兩個位置參數中寫上canvas的中心座標。

 

很粗糙的一篇文章,希望能幫到大家,希望大家能給我點個贊~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章