使用canvas繪制一個時鍾


  周末學習canvas的一些基礎功能,順帶寫了一個基礎的時鍾。現在加工一下,做的更好看一點,先放上效果圖:

    

  談一些自己的理解:

    (1)、要繪制一個新的樣式(不想被其他樣式影響,或者影響到其他樣式),那么一定記得先用beginPath(),beginPath()可以新建一個子路徑,接下來的繪制,都是針對該子路徑進行的。如果不適用該方法,那么默認和之前路徑為同一路徑設置,在接下來的繪制中,前面設置的路徑會被重復繪制(打個比方,如果不用beginPath(),上面我繪制了一個長方形,邊框寬度為1,下面我又繪制了一個長方形,邊框寬度為5,那么上面的長方形會被重新繪制,且邊框寬度也變為5)。相對的還有一個closePath()方法,如果前面設置的路徑是開放的,該方法會自動用直線連接終點和起點。

    (2)、因為時、分、秒針都是通過循環並且旋轉來做出移動效果,所以需要在每次旋轉前,通過save()方法保存下當前狀態,並在旋轉后restore()恢復到之前狀態,否則每次旋轉都會在上一次旋轉的基礎上進行。

    (3)、仔細看的話可以發現秒針的尾端是一個弧線,canvas里有很多曲線的繪制方法,且大多與切線(切點)有關,具體可以搜索下,網上有很多詳解文章了。

    (4)、lineTo()、arc()、arcTo()這些都僅僅是繪制路徑,最后要通過fill()或者stroke()來完成繪制。

  下面給出完整代碼,補上了注釋:

<!doctype html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<style>
</style>
</head>
<body>
<canvas id="my_clock" width="1200" height="900">不支持canvas</canvas>
<script>
	var myClock = document.getElementById('my_clock');
	var ctx = myClock.getContext('2d');
	var clockImg = new Image();
	clockImg.src = 'clock.png';
	ctx.translate(600, 400);

	var startTime = new Date().getTime(),
		count = 0;

	function clock() {
		ctx.clearRect(-600, -400, 1200, 900);

		// 裁剪鍾面圖,只留下圓的鍾面
		ctx.beginPath();
		ctx.arc(0, 0, 250, 0, 2 * Math.PI);
		ctx.clip();

		// 鍾面圖有點歪,需要差不多順時針旋轉1/3度
		ctx.save()
		ctx.rotate(1 / 3 * 2 * Math.PI / 60);
		ctx.drawImage(clockImg, - 250, -250, 500, 500);
		ctx.restore();
		
		// 這里注釋的部分的是繪制的一個簡單的鍾面,如果不用圖片可以打開下面的注釋
		// ctx.beginPath();
		// ctx.arc(0, 0, 200, 0, 2 * Math.PI, false);

		// ctx.moveTo(195, 0);
		// ctx.arc(0, 0, 195, 0, 2 * Math.PI, false);
		// ctx.stroke();
		// ctx.closePath();

		// ctx.font = '16px Arial';
		// ctx.textAlign = 'center';
		// ctx.textBaseline = 'middle';

		// ctx.fillText('12', 0, -180);
		// ctx.fillText('3', 180, 0);
		// ctx.fillText('6', 0, 180);
		// ctx.fillText('9', -180, 0);

	
		var nowTime = new Date(),
			sec = nowTime.getSeconds(),
			min  = nowTime.getMinutes() + sec / 60,
			hour12 = nowTime.getHours() >= 12 ? nowTime.getHours() - 12 : nowTime.getHours(),
			hour = hour12 + min / 60;
		
		// 實時時間轉換成角度,一圈是360度,也就是2PI,一圈有60小格,一小格就是(2 * Math.PI / 60)
		var angle = 2 * Math.PI / 60,
			secHandAngle = sec * angle,
			minHandAngle = min * angle,
			hourHandAngle = hour * 5 * angle;

		// 秒針
		ctx.save();
		ctx.beginPath();
		ctx.rotate(secHandAngle)
		ctx.moveTo(-2, 10);   
		ctx.lineTo(0, -240);	
		ctx.lineTo(2, 10);
		ctx.moveTo(-2, 10);
		ctx.arcTo(0, -240, 2, 10, 2);
		ctx.stroke();
		ctx.restore();
		
		// 分針
		ctx.save();
		ctx.beginPath();
		ctx.rotate(minHandAngle)
		ctx.moveTo(0, 0);   
		ctx.lineTo(0, -170);
		ctx.lineWidth = 2;
		ctx.stroke();
		ctx.restore();

		// 時針
		ctx.save();
		ctx.beginPath();
		ctx.rotate(hourHandAngle)
		ctx.moveTo(-5, 0);   
		ctx.lineTo(0, -120);	
		ctx.lineTo(5, 0);
		ctx.strokeStyle = '#fff'
		ctx.fillStyle = 'rgba(0, 0, 0, .3)';
		ctx.lineWidth = 1;
		ctx.stroke();
		ctx.fill();
		ctx.restore();

		// 減少setTimeout誤差
		count++;
		var diff = new Date().getTime() - (startTime + count * 1000);
		var nextStart = (1000 - diff) < 0 ? 0 : 1000 - diff;
		setTimeout(clock, nextStart);
	}

	// 占用線程
	// setInterval(function(){ 
	//  	var j = 0; 
	//  	while (j++ < 100000000); 
	// }, 0); 
	// setInterval(function(){ 
	//  	var j = 0; 
	//  	while (j++ < 100000000); 
	// }, 0); 
	// setInterval(function(){ 
	//  	var j = 0; 
	//  	while (j++ < 100000000); 
	// }, 0); 

	setTimeout(clock, 1000);
	// setInterval(clock, 1000)

	
</script>
</body>
</html>

  然后給上我用的鍾面圖:

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM