首頁  >  文章  >  web前端  >  canvas動畫時鐘

canvas動畫時鐘

高洛峰
高洛峰原創
2016-11-08 14:38:451436瀏覽

最近在學canvas,然後根據MDN上的例子做了個動畫時鐘(為什麼要造個輪子,因為醜。。)

這是MDN上的例子,怎麼說呢,比較復古吧。

canvas動畫時鐘

首先,找一張時鐘的圖片,就是下面這張了。

canvas動畫時鐘

——來自bigger than bigger的dribbble網站,圖片來源(侵刪)

然後就開始用canvas實現這個逼格滿滿的時鐘吧。在html程式碼中插入canvas標籤

<canvas id="canvas" width="400" height="400"></canvas>

在js檔案中建立畫布(假設我們使用的都是現代瀏覽器)。

function clock() {
  var ctx = document.getElementById(&#39;canvas&#39;).getContext(&#39;2d&#39;);
}

先來繪製時鐘錶盤,我們看到這張圖是帶有光線陰影效果的,畫成一樣難度太高。於是就用顏色的漸層來讓時鐘看起來稍微立體一點。在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, &#39;#242f37&#39;);
lingrad.addColorStop(1, &#39;#48585c&#39;);
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迴圈來畫出小時的刻度。

for (var i = 0; i < 12; i++) {
  ctx.beginPath();
  ctx.strokeStyle = &#39;#fff&#39;;
  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 = &#39;#536b7a&#39;;
    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了 效果圖如下:

canvas動畫時鐘

演示地址http://codepen.io/lifeng1893/pen/ALPamR


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn