canvas时钟

canvas是HTML5新增的组件,提供了新的javascript API。它最初由苹果内部使用自己MacOS X WebKit推出,供应用程序使用像仪表盘的构件和 Safari 浏览器使用。后来,有人通过Gecko内核的浏览器 (尤其是Mozilla和Firefox),Opera和Chrome和超文本网络应用技术工作组建议为下一代的网络技术使用该元素。canvas就像是页面上的一块画布,而javascript是一支笔,可以在画布上绘制多种多样的图形,丰富了前端开发方式,为前段的发展注入了新的活力。canvas默认宽高是300px * 150px,且必须在行内设置宽高。步入正题:

 

最近几天研究了下如何用canvas绘制时钟,github地址:https://github.com/lishuai336/canvasClock

首先创建画布:Mozilla 程序从 Gecko 1.8 (Firefox 1.5)开始支持 <canvas>, Internet Explorer 从IE9开始<canvas> 。Chrome和Opera 9+ 也支持 ,canvas标签的内容在不支持canvas的浏览器才会显示。

<div>
    <canvas id="clock" width="300" height="300">您的浏览器不支持canvas,请升级浏览器        
    </canvas>
</div>

1.  getContext("2d")获得2d上下文

canvas本身并没有提供太多的API,绘图的各种API主要来自getContext对象。"2d", 是建立一个 CanvasRenderingContext2D 二维渲染上下文。在未来,如果 canvas 标签扩展到支持 3D 绘图,getContext() 方法可能允许传递一个 "3d" 字符串参数。不过越来越多的浏览器开始支持webGL,也就是浏览器端的3D标准,它直接借助系统显卡来渲染 3D 场景,所以getContext(“3d”)的时代很可能不会出现。不过,利用透视现象可以用getContext(“2d”)绘制出3D的视觉效果,emmm,这个有点厉害。 

 

	var canvasClock = document.getElementById("clock");
	var canvasContext = canvasClock.getContext("2d");		//getContext返回一个对象,该对象提供了用于在画布上绘图的方法和属性
	var canvasWidth = canvasContext.canvas.width;
	var canvasHeight = canvasContext.canvas.height;
	var radius = canvasWidth / 2;                        //圆的半径

2. 绘制时钟的外围圆形

translate(x,y)设置画布的原点,也就是画画起笔的位置,lineWidth线条宽度,arc(x,y,r,sAngle,eAngle,counterclockwise),绘制圆形,里面几个参数分别代表:圆心坐标,圆半径,起始角(以弧度计,弧的圆形的三点钟位置是 0 度),结束角,顺时针还是逆时针。stroke()绘制定义的路径。

canvasContext.translate(radius, radius);        					//移动画布原点到中心点
canvasContext.beginPath();										//beginPath 开始一条路径,或者重置一条路径
canvasContext.lineWidth = 8;									//线条宽度
canvasContext.arc(0, 0, radius - canvasContext.lineWidth / 2, 0, 2*Math.PI, false); 		//创建圆形路径s
canvasContext.stroke();      									//绘制已定义的路径

 3.  绘制12个数字

1个小时的弧度是2π / 12 ,起始角是在3点处,所以数组第一个数从3开始。知道圆的半径,和每个点的弧度数,就可以通过sin和cos计算出每个数字的坐标。textAlign文字水平对齐方式,textBaseline设置文字基线(可以理解为文字垂直对齐方式)。

		var hourNumber = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
		canvasContext.font = 18  + "px Microsoft YaHei";			//设置文本大小
		canvasContext.textAlign = "center";						//设置文本水平对其方式
		canvasContext.textBaseline = "middle";					//设置文本垂直对齐方式
		hourNumber.forEach(function(number, i){
			var radian = 2 * Math.PI / 12 * i;            		    //每个小时的弧度
			var radianX = (radius - 30) * Math.cos(radian);		//每个小时X坐标
			var radianY = (radius - 30) * Math.sin(radian);     //每个小时Y坐标
			canvasContext.fillText(number, radianX, radianY);	    //绘制“被填充的”文本
		});

 4.  绘制60个刻度

 这和绘制12个数字一样,不过每个刻度的弧度是2π / 60,12个时刻点的颜色做个区分。fillStyle填充绘画的颜色。

       for(var i = 0; i < 60; i++){
			var radian = 2 * Math.PI / 60 * i;
			var x = (radius - 16) * Math.cos(radian);
			var y = (radius - 16) * Math.sin(radian);
			canvasContext.beginPath();
			if(i % 5 == 0){
				canvasContext.fillStyle = "#000";
			}
			else{
				canvasContext.fillStyle = "#ccc";
			}
			canvasContext.arc(x, y, 2, 0, 2 * Math.PI, false);
			canvasContext.fill();
		}

 5.  绘制时针

 时针运动时的旋转角度=当前时间的小时数+分针数+秒针数。由于时钟每秒变动一次,实则每一秒都要重新绘制一次画布内容。所以每次在执行之前都要保存下最开始的画布环境save();绘制完成后还原画布环境restore()。


	function drawHour(hour, minutes, seconds){
		canvasContext.save();                        //保存绘画前的画布环境
		canvasContext.beginPath();
		var radianHour = 2 * Math.PI / 12 * hour;
		var radianMinutes = 2 * Math.PI / 12 / 60 * minutes
		var radianSeconds = 2 * Math.PI / 12 / 60 / 60 * seconds;
		canvasContext.rotate(radianHour + radianMinutes + radianSeconds);
		canvasContext.lineWidth = 6 * rem;
		canvasContext.lineCap = "round";
		canvasContext.moveTo(0, 10 * rem);
		canvasContext.lineTo(0, -radius / 2);
		canvasContext.stroke();
		canvasContext.restore();					//还原初始画布环境
	}

  6.  绘制分针

 分针同理,rotate()画布旋转角度。

function drawMinute(minutes, seconds){
		canvasContext.save();
		canvasContext.beginPath();
		var radianMinutes = 2 * Math.PI / 60 * minutes;
		var radianSeconds = 2 * Math.PI / 60 / 60 * seconds;
		canvasContext.rotate(radianMinutes + radianSeconds);
		canvasContext.lineWidth = 4 * rem;
		canvasContext.lineCap = "round";
		canvasContext.moveTo(0, 12 * rem);
		canvasContext.lineTo(0, -radius + 30 * rem);
		canvasContext.stroke();
		canvasContext.restore();
	}

  7.  绘制秒针

秒针绘制成头尖尾宽的红色梯形。 

	function drawSeconds(seconds){
		canvasContext.save();
		canvasContext.beginPath();
		canvasContext.fillStyle = "#c14543";
		var radian = 2 * Math.PI / 60 * seconds;
		canvasContext.rotate(radian);
		canvasContext.moveTo(2 * rem, 20 * rem);
		canvasContext.lineTo(-2 * rem, 20 * rem);
		canvasContext.lineTo(-1 * rem, -radius + 18 * rem);
		canvasContext.lineTo(1 * rem, -radius + 18 * rem);
		canvasContext.fill();
		canvasContext.restore();
	}

8.  仿螺丝

在时针中心绘制一个白点,用于模仿固定钟表指针的螺丝。 

	function drawDot(){
		canvasContext.save();
		canvasContext.beginPath();
		canvasContext.fillStyle = "#fff";
		canvasContext.arc(0, 0, 2 * rem, 0, 2 * Math.PI, false);
		canvasContext.fill();
		canvasContext.restore();
	}

9.  绘制函数

clearRect() 清空给定矩形内的指定像素,每次绘制的画面都不相同,避免画面叠加。

	function draw(){
		canvasContext.clearRect(0, 0, canvasWidth, canvasHeight);
		var now = new Date();
		var hour = now.getHours();
		var minutes = now.getMinutes();
		var seconds = now.getSeconds();
		drawBackground();
		drawHour(hour, minutes, seconds);
		drawMinute(minutes, seconds);
		drawSeconds(seconds);
		drawDot();
		canvasContext.restore();
	}

10.  执行绘制函数

实际上这种方法的绘制总会比系统时间慢一点,因为还有毫秒的误差没有处理。

	draw();
	setInterval(draw, 1000);

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值