canvas时钟案例

228 阅读1分钟

绘制完静态样式之后,用计时器刷新时间即可,要注意会改变坐标的方法,有涉及改变坐标的方法,都要保存之前的状态并重置,才不会影响下一图形的绘制

.clock {
	width: 500px;
	height: 500px;
	background-color: #222;
	margin: 50px auto;
	border-radius: 100px;
}

最外面的黑色盒子直接用div做就可以了

<div class="clock">
	<canvas id="clock" width="500" height="500"></canvas>
</div>

插件化写法,可配置项

new Clock({
	panelBgColor: '#6fa698'
}).init();

;(function() {
	var canvas = document.getElementById('clock'),
		ctx = canvas.getContext('2d'),
		sWidth = ctx.canvas.width,
		sHeight = ctx.canvas.height,
		r = sWidth / 2, //中心点
		t = null;

	var Clock = function(opt) {
		this.panelBgColor = opt.panelBgColor;
	}

	Clock.prototype = {
		hours: [3,4,5,6,7,8,9,10,11,12,1,2],

		init: function() {
			this.draw();

			t = setInterval(this.draw.bind(this), 1000);
		},

		// 绘制方法
		draw: function() {
			ctx.clearRect(0, 0, sWidth, sHeight);
			var hours = getTime().hours,
				minutes = getTime().minutes,
				seconds = getTime().seconds;

			ctx.save();
			this.drawPanel();
			this.drawHoursNum();
			this.drawHourIndicator(hours, minutes);
			this.drawMinuteIndicator(minutes);
			this.drawSecondIndicator(seconds);
			this.drawCentralPoint();
			ctx.restore();
		},

		// 表盘
		drawPanel: function() {
			ctx.translate(r, r);// 圆心变换
			ctx.beginPath();
			ctx.fillStyle = this.panelBgColor;
			ctx.arc(0, 0, r - 25, 0, 2 * Math.PI);
			ctx.fill();
		},

		// 数字
		drawHoursNum: function() {
			var hours = this.hours;

			ctx.font = '40px Arial';
			ctx.textAlign = 'center';
			ctx.textBaseline = 'middle';
			ctx.fillStyle = '#424242';

			hours.forEach(function(elem, idx) {
				var hNumAngle = 2 * Math.PI / 12 * idx, //角度
					x = Math.cos(hNumAngle) * (r - 60),
					y = Math.sin(hNumAngle) * (r - 60);

				ctx.beginPath();
				ctx.fillText(elem, x, y);
			})
		},

		// 中心圆点
		drawCentralPoint: function() {
			// translate(r, r);不需要重新移
			ctx.beginPath();
			ctx.fillStyle = '#424242';
			ctx.arc(0, 0, 13, 0, 2 * Math.PI);
			ctx.fill();

			ctx.beginPath();
			ctx.fillStyle = '#999';
			ctx.arc(0, 0, 6, 0, 2 * Math.PI);
			ctx.fill();
		},

		// 时针
		drawHourIndicator: function(hours, minutes) {
			var hAngle = 2 * Math.PI / 12 * hours,
				mAngle = 2 * Math.PI / 12 / 60 * minutes;

			ctx.save();
			ctx.beginPath();
			ctx.lineWidth = 10;
			ctx.lineCap = 'round';
			ctx.strokeStyle = '#424242';

			ctx.rotate(hAngle + mAngle);
			ctx.moveTo(0, 0);
			ctx.lineTo(0, -r * 0.55);
			ctx.stroke();
			ctx.restore(); //为了不影响分针,因为旋转会改变坐标轴
		},

		// 分针
		drawMinuteIndicator: function(minutes) {
			var mAngle = 2 * Math.PI / 60 * minutes;

			ctx.save();
			ctx.beginPath();
			ctx.lineWidth = 10;
			ctx.lineCap = 'round';
			ctx.strokeStyle = '#424242';

			ctx.rotate(mAngle);
			ctx.moveTo(0, 0);
			ctx.lineTo(0, -r * 0.75);
			ctx.stroke();
			ctx.restore();
		},

		// 秒针
		drawSecondIndicator: function(seconds) {
			var sAngle = 2 * Math.PI / 60 * seconds;

			ctx.save();
			ctx.beginPath();
			ctx.lineWidth = 10;
			ctx.lineCap = 'round';
			ctx.strokeStyle = '#e08946';

			ctx.rotate(sAngle);
			ctx.moveTo(0, 0);
			ctx.lineTo(0, -r * 0.75);
			ctx.stroke();
			ctx.restore();
		}
	}

	function getTime() {
		var d = new Date();

		return {
			hours: d.getHours(),
			minutes: d.getMinutes(),
			seconds: d.getSeconds()
		}
	}

	window.Clock = Clock;
})();