Canvas 實現一個時鐘
阿新 • • 發佈:2019-02-18
使用canvas實現另一個小時鐘,效果圖如下:
前端html程式碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> body { background: #dddddd; } #canvas { margin: 0 auto; padding: 10px; background:#ffffff; border: thin inset #aaaaaa; } </style> </head> <body> <canvas id="canvas" width="400" height="400"> Canvas not supported </canvas> <script src="./js/example.js"></script> </body> </html>
下面是example.js的具體實現:
var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); var FONT_HEIGHT = 15;// 字型大小 var MARGIN = 35; // 邊距 var HAND_TRUNCATION = canvas.width/12; // 分鐘需要減去的半徑 var HOUR_HAND_TRUNCATION = canvas.width/10;// 小時針需要減去的半徑 var NUMBER_SPACING = 20; // 數字間距 var RADIUS = canvas.width/2 - MARGIN; // 半徑 var HAND_RADIUS = RADIUS + NUMBER_SPACING; // 指標半徑(數字間距) // 繪製圓 function drawCircle(){ context.beginPath(); context.arc(canvas.width/2, canvas.height/2, RADIUS, 0, Math.PI*2, true); context.stroke(); } // 繪製中心點 function drawCenter(){ context.beginPath(); context.arc(canvas.width/2, canvas.height/2, 5, 0, Math.PI*2, true); context.fill(); } // 繪製數字 function drawNumbers(){ var numberals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; var angle = 0; var numeralWidth = 0; numberals.forEach(function(numeral){ angle = Math.PI/6 * (numeral - 3); // 填充文字 numeralWidth = context.measureText(numeral).width; context.fillText(numeral, canvas.width/2 + Math.cos(angle)*(HAND_RADIUS) - numeralWidth/2, canvas.height/2 + Math.sin(angle)*(HAND_RADIUS) + FONT_HEIGHT/3 ); // 繪製刻度 context.moveTo(canvas.width/2 + Math.cos(angle)*(RADIUS -5), canvas.height/2 + Math.sin(angle)*(RADIUS -5)); context.lineTo(canvas.width/2 + Math.cos(angle)*(RADIUS), canvas.height/2 + Math.sin(angle)*(RADIUS)); context.stroke(); }); } // 繪製指標 function drawHand(loc, isHour , isMin){ var angle = (Math.PI * 2) * (loc/60) - Math.PI/2; var handRadius = isHour? RADIUS - HAND_TRUNCATION - HOUR_HAND_TRUNCATION : (isMin ? (RADIUS - HAND_TRUNCATION) : (RADIUS * 0.95)); context.moveTo(canvas.width/2, canvas.height/2); context.lineTo(canvas.width/2 + Math.cos(angle) * handRadius, canvas.height/2 + Math.sin(angle) * handRadius); context.stroke(); } // 繪製所有指標 function drawHands(){ var date = new Date; var hour = date.getHours(); hour = hour >12 ? hour - 12 : hour; // 繪製小時指標 drawHand((hour + date.getMinutes()/60)*5, true,false); // 繪製分鐘指標 drawHand(date.getMinutes(),false,true); // 繪製秒指標 drawHand(date.getSeconds(),false,false); } // 畫鍾 function drawClock(){ context.clearRect(0, 0, canvas.width, canvas.height); drawCircle(); drawCenter(); drawNumbers(); drawHands(); } context.font = FONT_HEIGHT + 'px Arial'; loop = setInterval(drawClock, 1000);
另外,實現時鐘的主要的難點如下:
在刻畫指標的時候採用了這樣的處理方法:
小時取1-12 但是我們會乘以5,因為我們把一個圓分成了60個小刻度,這樣在渲染的時候對於時、分、秒的處理就變得很容易:
時指標的偏移度數(我們取canvas下的偏轉度數)={ [ (小時數 + 當前時間的分鐘/60) * 5] / 60 } * (2 * π) - π/2。
具體理解如下:
首先我們以canvas旋轉座標定義,順時針為+,逆時針為-,這樣我們迴歸到0度數。假設現在需要渲染1:00,小時指標情況,顯然1個小時佔據圓盤的30度的夾角,我們從0開始旋轉30度角成:
但是實際上1:00的錶盤時指標的顯示應該為: