最近在學canvas,而後根據MDN上的例子作了個動畫時鐘(爲何要造個輪子,由於醜。。)html
這是MDN上的例子,怎麼說呢,比較復古吧。git
首先,找一張時鐘的圖片,就是下面這張了。github
——來自bigger than bigger的dribbble網站,圖片來源(侵刪)canvas
而後就開始用canvas實現這個逼格滿滿的時鐘吧。在html
代碼中插入canvas
標籤瀏覽器
<canvas id="canvas" width="400" height="400"></canvas>
在js
文件中建立畫布(假設咱們使用的都是現代瀏覽器)。函數
function clock() { var ctx = document.getElementById('canvas').getContext('2d'); }
先來繪製時鐘錶盤,咱們看到這張圖是帶有光線陰影效果的,畫成同樣難度過高。因而就用顏色的漸變來讓時鐘看起來稍微立體一點。在canvas
中用createLinearGradient
來建立一個新的漸變,並用addColorStop上色,最後把顏色賦給strokeStyle
。詳見運用樣式與顏色 by MDN動畫
//繪製錶盤底色 ctx.translate(200, 200); //將座標原點移到畫布中心 ctx.rotate(-Math.PI/2); //將座標軸逆時針旋轉90度,x軸正方向對準12點方向 var lingrad = ctx.createLinearGradient(150, 0, -150, 0); lingrad.addColorStop(0, '#242f37'); lingrad.addColorStop(1, '#48585c'); ctx.fillStyle = lingrad; ctx.beginPath(); ctx.arc(0, 0, 150, 0, Math.PI * 2, true); ctx.fill();
比較關鍵的一點是畫布的座標軸x軸正方向是時鐘3點鐘方向,爲了方便起見,咱們把它逆時針旋轉90度讓它指向十二點鐘方向。網站
繪製刻度要用到旋轉rotate
(變形 Transformations by MDN),小時刻度有12個,相鄰兩個刻度與圓心連線的角度就是Math.PI/6,這裏用的是弧度表示,也就是30度。那麼咱們就用for循環來畫出小時的刻度。spa
for (var i = 0; i < 12; i++) { ctx.beginPath(); ctx.strokeStyle = '#fff'; ctx.lineWidth = 3; ctx.rotate(Math.PI / 6); ctx.moveTo(140, 0); ctx.lineTo(120, 0); ctx.stroke(); }
同理,分鐘的刻度也同樣。指針
ctx.beginPath(); for (i = 0; i < 60; i++) { if (i % 5 !== 0) { //去掉與小時刻度重疊的部分 ctx.beginPath(); ctx.strokeStyle = '#536b7a'; ctx.lineWidth = 2; ctx.moveTo(140, 0); ctx.lineTo(130, 0); ctx.stroke(); } ctx.rotate(Math.PI / 30); }
錶盤大體畫好了,刻度也畫好了,接下來就是繪製指針並讓它指向正確的時間,是否是?不就就是畫一條直線麼。關鍵是指針rotate的角度是多少呢?其實也是比較簡單的。先獲取當前的時間,把小時轉換爲12小時制的。
var now = new Date(), sec = now.getSeconds(), min = now.getMinutes(), hr = now.getHours(); hr = hr > 12 ? hr - 12 : hr;
那麼,時針的位置就是(相對於x軸正方向轉過的角度):
ctx.rotate(hr * (Math.PI / 6) + min * (Math.PI / 360) + sec * (Math.PI / 21600));
同理,分針和秒針的位置:
ctx.rotate(min * (Math.PI / 30) + sec * (Math.PI/1800)); //分針 ctx.rotate(sec * (Math.PI /30)); //秒針
最後,最關鍵的讓指針轉動起來,這裏要用到的是requestAnimationFrame
方法,用來重繪頁面,獲得連貫逐幀的動畫,實現最佳的動畫效果。
window.requestAnimationFrame(callback);
這個callback就是咱們的繪製時鐘的clock()函數。須要注意的是每次執行完requestAnimationFrame
後須要清除畫布,否則出現重疊交錯的現象,咱們把它放在clock函數開始的地方。
ctx.clearRect(0, 0, canvas.width, canvas.height);
到這裏,動畫時鐘就OK了 效果圖以下: