html5之canvas实现模拟简易时钟

本文介绍如何使用HTML5 Canvas API绘制一个动态更新的时钟,并详细解释了关键代码段的功能及其实现原理,如路径绘制、文字标记等。

个人理解:

moveTo 类似于提笔去另一个新地方

translate类似于把整张画布移位


如果画一条新路径不使用beginPath(),则stroke()会把之前画过的(即已经执行的stroke()重新再画一遍,相当于描粗了)


画背景的函数中不能使用restore(),因为画时分秒是基于开始已经translate()的画布上的

但画时分秒的函数中需要开始和结尾分别save和restore,否则旋转的角度会叠加


<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>模拟时钟</title>
	<style>
	#draw{
		margin-top: 100px;
		width: 120px;
		height: 120px;
		margin-right: auto;
		margin-left: auto;
		
	}
	#clock{
		width: 120px;
		height: 120px;
	}
	</style>
</head>
<body>
	<div id="draw">
		<canvas id="clock" width="120px" height="120px"></canvas>
	</div>
	<script type="text/javascript">
	var clock=document.getElementById("clock");
	var cxt=clock.getContext("2d");
	//真正内容宽度:80
	var r=(cxt.canvas.width)/2;
	//包括边框等一系列宽度:82
	//var r=document.getElementById("draw").offsetWidth;
	//在style属性里写了的才能显示:80px
	//var r=document.getElementById("draw").style.width;
	//console.log(r);

	function drawbg(){
	cxt.save();
	cxt.translate(r,r);
	cxt.beginPath();
	cxt.lineWidth=10;
	//注意,半径的算法是圆心到线条的中间
	cxt.arc(0,0,r-5,0,2*Math.PI,false);
	cxt.stroke();
	//cxt.beginPath();	
	cxt.font="12px Arial";
	var smallr=r-25;
	cxt.textAlign="center";
	cxt.textBaseline="middle";
	var hours=[3,4,5,6,7,8,9,10,11,12,1,2];
	hours.forEach(function(hour,i){
		var x=smallr*Math.cos(i*30*Math.PI/180);
		var y=smallr*Math.sin(i*30*Math.PI/180);
		//注意,这儿不能用strokeText()
		cxt.fillText(hour,x,y);
	});
	var dotr=r-18;
	cxt.textAlign="center";
	//基线这儿不怎么懂!
	cxt.textBaseline="alphabetic";
	for(var i=0;i<60;i++){
		var x=dotr*Math.cos(i*Math.PI/30);
		var y=dotr*Math.sin(i*Math.PI/30);
		if(i%5!=0)
		cxt.fillText(".",x,y);
	}
}
	function drawhour(Hour,Minute){
	cxt.save();
	var rad1=(2*Math.PI/12/5/60)*Minute;
	var rad2=(2*Math.PI/12)*Hour;
	cxt.beginPath();
	cxt.rotate(rad1+rad2);
	cxt.lineWidth=4;
	cxt.lineCap="round";
	cxt.moveTo(0,1);
	cxt.lineTo(0,-19);
	cxt.stroke();
	cxt.restore();
	}

	function drawminutes(Minute){
	cxt.save();
	var rad=(2*Math.PI/60)*Minute;
	cxt.beginPath();
	cxt.rotate(rad);
	cxt.lineWidth=3;
	cxt.lineCap="round";
	cxt.moveTo(0,3);
	cxt.lineTo(0,-21);
	cxt.stroke();
	cxt.restore();
	}
	function drawsecond(Second){
	cxt.save();
	var rad=(2*Math.PI/12/5)*Second;
	cxt.beginPath();
	cxt.rotate(rad);
	cxt.lineWidth=2;
	cxt.lineCap="round";
	cxt.moveTo(0,5);
	cxt.lineTo(0,-24);
	cxt.stroke();
	cxt.restore();
	}
	function drawtime(){
		cxt.clearRect(0,0,r*2,r*2);
		var now=new Date();
		var Hour=now.getHours();
		var Minute=now.getMinutes();
		var Second=now.getSeconds();
		drawbg();
		drawhour(Hour,Minute);
		drawminutes(Minute);
		drawsecond(Second);
		cxt.restore();
	}
	setInterval(drawtime,1000);
	</script>
</body>
</html>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值