[Canvas] JS 繪製真實時鐘

導讀

這個案例是逛帖子發現的一個面試題,原題是讓用html元素完成,當時剛好是在作關於canvas方面的東西,想着那樣太簡單了,就用canvas來實現一下,挑戰一下本身。javascript

案例須要掌握的html

  • canvas基本使用,arc、fillRect等java

  • ES6 class語法git

  • 一些三角函數知識github

效果如圖所示面試


githubcanvas

分析

這個圖形較爲簡單,都是比較規整的圖形,一圖勝千言,大概須要寫下面幾個功能。或許到這裏,聰明的你已經能夠完成這個案例了。api


邏輯結構

這裏理一下結構,我喜歡使用下面的結構bash

  • constructor 處理實例化對象時傳入的參數函數

  • init 初始化默認參數,減小constructor的臃腫

  • render 集中處理渲染函數

  • update 集中處理更新的數據

class Scene {
  constructor() { ... }
  init() { ... }
  render() { ... }
  update() { ... }
  // other method...
}複製代碼

實現

圓盤 drawPane

外圓盤繪製 drawPane,繪製圓盤的方法其實很簡單,因爲繪製的圓較多,能夠封裝這樣一個專門繪製圓盤的函數

// 繪製圓apiarc(x, y, r, 0, 2*PI)
// 依次繪製3個圓

drawArc(200, 200, 200, '#ff1515')
drawArc(200, 200, 190, '#b70d0d')
drawArc(200, 200, 180, '#ffffff')

drawArc(x, y, r, color='#000') {
  ctx.beginPath()
  ctx.fillStyle = color
  ctx.arc(x, y, r, 0, 6.28)
  ctx.fill()  
}
複製代碼

繪製分鐘刻度 drawPoint

這裏用到一些三角函數的知識,掌握這些知識看圖便可明白,理解後,翻譯成代碼就容易的多了,只需計算出對應的x、y座標,調用前面封裝的drawArc方法便可。

// 繪製刻度
drawPoint() {
  for (let i = 0; i < 60; i++) {
    let x, y = ...
    this.drawArc(...)
  }
}複製代碼

繪製小時刻度 drawRect

小時刻度共12個,圓環共360度,每刻度360/12,小時刻度看似和分鐘刻度差很少,其實難度仍是比較大的,由於默認的旋轉中心在(0,0),每次繪製須要手動的修改旋轉中心。

注意點

  • 調用Canvas的平移、放縮、旋轉、錯切、裁剪等操做時通常要使用save、restore來保存和重置狀態

  • rotate的角度要加90度

drawScale() {
	ctx.save()
  // ...
  ctx.restore()
}複製代碼

繪製指針

有了前面的基礎,繪製指針就會簡單不少,因爲繪製時分秒指針類似,這裏把它抽出來,作成單獨的函數

drawScale(x, y, w, h, angle, color) {...}複製代碼

計算指針的角度,這個看似難,其實很是簡單

舉個例子

  • 秒針、分針共60刻度,均分360度 -> 360/60

  • 時針共12刻度,均分360度 -> 360/12

這樣作仍是不夠的,還有考慮秒對分的影響、秒分對時的影響,因此能夠這樣換算

// 偏移角度 = 折算的當前時刻數 * 單位角度​

sec * 360/60
(min + sec/60) * 360/60
(hour + min/60 + sec/60/60) * 360/12複製代碼

drawPane2

與drawPane相同就不贅述了

探討

有個地方還不滿意,開始的動畫是定義一個計時器實現的,由於不在開始設計構思內,寫完後臨時添加的(爲了顯示繪製過程),感受有點low,還有想好怎麼更好的實現這個功能,有知道的歡迎留言探討


小結

但願看完本篇文章能對你有幫助

文中若有錯誤,歡迎在評論區指正,若是這篇文章幫助到了你,歡迎點贊和關注。

想閱讀更多優質文章、可關注個人github博客,你的star✨、點贊和關注是我持續創做的動力

詳細代碼參考,canvas真實時鐘

相關文章
相關標籤/搜索