超詳細,用canvas在微信小程序上畫時鐘教程

最近開始學習canvas,看了慕課網的一個視頻,開始本身動手在微信小程序上畫個時鐘,html

首先咱們能夠先看如下微信小程序的官方文檔:https://mp.weixin.qq.com/debug/wxadoc/dev/api/canvas/reference.htmlcanvas

和canvas的手冊對比:http://www.w3school.com.cn/tags/html_ref_canvas.asp小程序

我以爲其實除了刪減一些內容以外沒什麼太大的區別微信小程序

 

直接貼代碼: api

wxml微信

<!--index.wxml-->
<view class="container">
<canvas canvas-id="clock"/>
</view>

wxssapp

/**index.wxss**/

.container {
  height: 100%;
  width: 100%;
}

canvas {
  height: 100%;
  width: 100%;
}

/*有些人會有疑問爲何設置了100%卻沒有100%,其實要到app.wxss裏設置一下*/
/**app.wxss**/
page{
  width:100%;
  height:100%;
}

jsiphone

Page({
  data: {
    width: 0,
    height: 0
  },
  onLoad: function (options) {
    var that = this
    //獲取系統信息  
    wx.getSystemInfo({
      //獲取系統信息成功,將系統窗口的寬高賦給頁面的寬高  
      success: function (res) {
        that.width = res.windowWidth
        // console.log(that.width)   375
        that.height = res.windowHeight
        // console.log(that.height)  625
        // 這裏的單位是PX,實際的手機屏幕有一個Dpr,這裏選擇iphone,默認Dpr是2
      }
    })
  },

  onReady: function () {
    this.drawClock();
    // 每40ms執行一次drawClock(),人眼看來就是流暢的畫面
    this.interval = setInterval(this.drawClock, 40);
  },


  // 全部的canvas屬性以及Math.sin,Math.cos()等涉及角度的參數都是用弧度表示
  // 時鐘
  drawClock: function () {
    const ctx = wx.createCanvasContext('clock');
    var height = this.height;
    var width = this.width;
    // 設置文字對應的半徑
    var R = width / 2 - 60;
    // 把原點的位置移動到屏幕中間,及寬的一半,高的一半
    ctx.translate(width / 2, height / 2);

    // 畫外框
    function drawBackground() {
      // 設置線條的粗細,單位px
      ctx.setLineWidth(8);
      // 開始路徑
      ctx.beginPath();
      // 運動一個圓的路徑
      // arc(x,y,半徑,起始位置,結束位置,false爲順時針運動)
      ctx.arc(0, 0, width / 2 - 30, 0, 2 * Math.PI, false);
      ctx.closePath();
      // 描出點的路徑
      ctx.stroke();
    };

    // 畫時鐘數
    function drawHoursNum() {
      ctx.setFontSize(20);
      // 圓的起始位置是從3開始的,因此咱們從3開始填充數字
      var hours = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
      hours.forEach(function (hour, i) {
        var rad = (2 * Math.PI / 12) * i;
        var x = R * Math.cos(rad);
        var y = R * Math.sin(rad);
          // 由於微信小程序不支持BaseLine這個屬性,因此這裏咱們只能本身手動調整位置
        if (hour == 12) {
          ctx.fillText(hour, x - 11, y + 6);
        } else if (hour == 6) {
          ctx.fillText(hour, x - 5, y + 6);
        } else {
          ctx.fillText(hour, x - 6, y + 6);
        }
      })
    };

    // 畫數字對應的點
    function drawdots() {
      for (let i = 0; i < 60; i++) {
        var rad = 2 * Math.PI / 60 * i;
        var x = (R + 15) * Math.cos(rad);
        var y = (R + 15) * Math.sin(rad);
        ctx.beginPath();
        // 每5個點一個比較大
        if (i % 5 == 0) {
          ctx.arc(x, y, 2, 0, 2 * Math.PI, false);
        } else {
          ctx.arc(x, y, 1, 0, 2 * Math.PI, false);
        }
        ctx.setFillStyle('black');
        ctx.fill();
      }
      ctx.closePath();
    }

    // 畫時針
    function drawHour(hour, minute) {
      // 保存畫以前的狀態
      ctx.save();
      ctx.beginPath();
      // 根據小時數肯定大的偏移
      var rad = 2 * Math.PI / 12 * hour;
      // 根據分鐘數肯定小的偏移
      var mrad = 2 * Math.PI / 12 / 60 * minute;
      // 作旋轉
      ctx.rotate(rad + mrad);
      ctx.setLineWidth(8);
      // 設置線條結束樣式爲圓
      ctx.setLineCap('round');
      // 時針向後延伸8個px;
      ctx.moveTo(0, 8);
      // 一開始的位置指向12點的方向,長度爲R/2
      ctx.lineTo(0, -R / 2);
      ctx.stroke();
      ctx.closePath();
      // 返回畫以前的狀態
      ctx.restore();
    }

    // 畫分針
    function drawMinute(minute, second) {
      ctx.save();
      ctx.beginPath();
      // 根據分鐘數肯定大的偏移
      var rad = 2 * Math.PI / 60 * minute;
      // 根據秒數肯定小的偏移
      var mrad = 2 * Math.PI / 60 / 60 * second;
      ctx.rotate(rad + mrad);
      // 分針比時針細
      ctx.setLineWidth(6);
      ctx.setLineCap('round');
      ctx.moveTo(0, 10);
      // 一開始的位置指向12點的方向,長度爲3 * R / 4
      ctx.lineTo(0, -3 * R / 4);
      ctx.stroke();
      ctx.closePath();
      ctx.restore();
    }

    // 畫秒針
    function drawSecond(second, msecond) {
      ctx.save();
      ctx.beginPath();
      // 根據秒數肯定大的偏移
      var rad = 2 * Math.PI / 60 * second;
      // 1000ms=1s因此這裏多除個1000
      var mrad = 2 * Math.PI / 60 / 1000 * msecond;
      ctx.rotate(rad + mrad);
      ctx.setLineWidth(4);
      // 設置線條顏色爲紅色,默認爲黑色
      ctx.setStrokeStyle('red');
      ctx.setLineCap('round');
      ctx.moveTo(0, 12);
      ctx.lineTo(0, -R);
      ctx.stroke();
      ctx.closePath();
      ctx.restore();
    }

    //畫出中間那個灰色的圓
    function drawDot() {
      ctx.beginPath();
      ctx.arc(0, 0, 8, 0, 2 * Math.PI, false);
      ctx.setFillStyle('lightgrey');
      ctx.fill();
      ctx.closePath();
    }

    function Clock() {
      // 實時獲取各個參數
      var now = new Date();
      var hour = now.getHours();
      var minute = now.getMinutes()
      var second = now.getSeconds();
      var msecond = now.getMilliseconds();
      // 依次執行各個方法
      drawBackground();
      drawHoursNum();
      drawdots();
      drawHour(hour, minute);
      drawMinute(minute, second);
      drawSecond(second, msecond);
      drawDot();
      // 微信小程序要多個draw纔會畫出來,因此在最後畫出
      ctx.draw();
    }
    // 執行Clock這個方法,實際上執行了全部步驟
    Clock();
  }
})

最後出來是這個樣子(比較遺憾的是小程序好像不支持設置canvas的文字樣式):xss


 

最後有一個疑問,小程序不用像網頁同樣在執行先後加一個ctx.clearRect()和ctx.restore(),是否小程序每執行一次都會推倒重畫?學習

相關文章
相關標籤/搜索