详细解释都在代码中,如下:
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clock</title>
<style>
body{background: #dddddd;}
#canvas{margin: 20px;padding:20px;background: #ffffff;border: thin inset #aaaaaa;}
</style>
</head>
<body>
<canvas id=canvas height="300" width="600"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
/** 定义字体高度 */
var FONT_HEIGHT = 15,
/** 偏移量 */
MARGIN = 35,
/** 指针长度 */
HAND_TRUNCATION = canvas.width/25,
/** 小时指针长度 */
HOUR_HAND_TRUNCATION = canvas.height/10,
/** 指示器 */
NUMERAL_SPACING = 20,
/** 半径 */
RADIUS = canvas.height/2 - MARGIN,
/** 指针半径 */
HAND_RADIUS = RADIUS + NUMERAL_SPACING;
/** 画圆 */
function drawCircle(){
context.beginPath();
//画圆
context.arc(canvas.width/2,canvas.height/2,RADIUS,0,Math.PI*2,true);
//执行绘画 stroke是画线
context.stroke();
}
function drawNumerals(){
var numerals = [1,2,3,4,5,6,7,8,9,10,11,12];
var angle = 0;
var numeralWidth = 0;
for(var i in numerals){
angle = Math.PI/6 * (numerals[i]-3);
numeralWidth = context.measureText(numerals[i]).width;
context.fillText(numerals[i],canvas.width/2+Math.cos(angle)*(HAND_RADIUS) - numeralWidth/2,
canvas.height/2 + Math.sin(angle)*(HAND_RADIUS)+FONT_HEIGHT/3);
}
}
//画中心圆点
function drawCenter(){
context.beginPath();
context.arc(canvas.width/2,canvas.height/2,5,0,Math.PI*2,true);
//fill是画实心圆,填充
context.fill();
}
//绘画指针
function drawHand(loc,isHour){
var angle = (Math.PI*2)*(loc/60) - Math.PI/2,
handRadius = isHour ? RADIUS - HAND_TRUNCATION - HOUR_HAND_TRUNCATION : RADIUS - HAND_TRUNCATION;
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,hour = date.getHours();
//将24小时制转换为12小时制
hour = hour > 12 ? hour - 12 : hour;
drawHand(hour*5 + (date.getMinutes()/60)*5,true,0.5);
drawHand(date.getMinutes(),false,0.5);
drawHand(date.getSeconds(),false,0.2);
}
function drawClock(){
//每次清除一次canvas
context.clearRect(0,0,canvas.width,canvas.height);
//重新画,形成动画效果
drawCircle();
drawCenter();
drawHands();
drawNumerals();
}
context.font = FONT_HEIGHT + 'px Arial';
loop = setInterval(drawClock, 1000);
</script>
</body>
</html>
setInterval 和 setTimeout方法均可实现动画效果,但是HTML5为了实现canvas动画,专提供了一个实现动画的函数requestAnimationFrame(callback);此函数实现原理和前两者差不多,但是web性能方面更优秀。