這個案例是逛帖子發現的一個面試題,原題是讓用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,繪製圓盤的方法其實很簡單,因爲繪製的圓較多,能夠封裝這樣一個專門繪製圓盤的函數
// 繪製圓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()
}
複製代碼
這裏用到一些三角函數的知識,掌握這些知識看圖便可明白,理解後,翻譯成代碼就容易的多了,只需計算出對應的x、y座標,調用前面封裝的drawArc
方法便可。
// 繪製刻度
drawPoint() {
for (let i = 0; i < 60; i++) {
let x, y = ...
this.drawArc(...)
}
}複製代碼
小時刻度共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複製代碼
與drawPane相同就不贅述了
有個地方還不滿意,開始的動畫是定義一個計時器實現的,由於不在開始設計構思內,寫完後臨時添加的(爲了顯示繪製過程),感受有點low,還有想好怎麼更好的實現這個功能,有知道的歡迎留言探討
但願看完本篇文章能對你有幫助
文中若有錯誤,歡迎在評論區指正,若是這篇文章幫助到了你,歡迎點贊和關注。
想閱讀更多優質文章、可關注個人github博客,你的star✨、點贊和關注是我持續創做的動力
詳細代碼參考,canvas真實時鐘