首先先理解几个方法:
1、save()和restore():这对法宝非常有用,两个配对使用,saved方法用于临时保存画布的坐标系统的状态;restore方法用来恢复save之后保存的状态。可以简单的理解为,save之后的一系列的操作,比如translate和rotate等,在restore后,都会被释放恢复到原来的坐标状态。
eg:
ctx.strokeStyle = '#000';
ctx.strokeRect(10,10,200,100); //空心矩形
ctx.translate(10,10); //改变坐标原点
ctx.strokeStyle = 'red';
ctx.strokeRect(10,10,200,100); //实心矩形
效果:
接下来加上save和restore
ctx.strokeStyle = '#000';
ctx.strokeRect(10,10,200,100); //空心矩形
ctx.save();
ctx.translate(10,10); //改变坐标原点
ctx.restore();
ctx.strokeStyle = 'red';
ctx.strokeRect(10,10,200,100); //实心矩形
效果:
从图一不难发现没加save和restore之前,红色的矩形已经是以(10,10)为原点来绘制了,加了之后画布恢复到translate的操作之前,原点仍然是(0,0),因此图二的红色矩形才会把上一个矩形给覆盖了。
2、translate():默认画布的原点为(0,0),调用此方法可改变画布坐标原点的位置。调用此方法后,x坐标往左的位置以及y坐标往上的位置都为负值。
eg:可以从上面的图一来理解,红色的矩形已经以(10,10)为原点来绘制了。负值的理解如下:假如把原点的位置放到画布的正中间,那么各区间的坐标如下:
3、rotate(angle):此方法用来对画布执行旋转操作,默认旋转的中心点为画布的坐标原点,可以通过translate来改变旋转中心的位置。angle为旋转的角度,以弧度计算,旋转30度的话angle就是20*Math.PI/180。
eg:让一个正方形围绕着自己的中心点旋转30度,
ctx.strokeRect(100,100,200,100);
ctx.save();
ctx.strokeStyle = 'red';
ctx.translate(200,150);
ctx.rotate(30*Math.PI/180);
ctx.strokeRect(-100,-50,200,100);
ctx.restore();
效果:
接下来说下时钟的主要思路:就是每隔一秒把当前的时分秒对应的时针、分针、秒针绘制到画布上就可以了,时针对应12个刻度,因此每个刻度旋转30度,当前小时对应的旋转角度就应该是rotate(hour*30*Math.PI/180);分针和秒针一样对应60个刻度,每个刻度旋转6度,当前分钟和秒对应的旋转角度是rotate(minute*6*Math.PI/180)以及rotate(seconds*6*Math.PI/180)。
具体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>canvas 时钟</title>
<style>
*{margin: 0; padding: 0;}
.main{
width: 1000px;
padding: 50px 0;
border: 1px solid #ccc;
margin: 0 auto;
text-align: center;
}
#canvas{
margin: 50px 0;
background-color: deepskyblue;
}
</style>
</head>
<body>
<div class="main">
<canvas id="canvas" width="600" height="600">您的浏览器不支持canvas</canvas>
</div>
<script>
window.onload = function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
function drawClock(){
//获取当前的时分秒
var now = new Date();
var seconds = now.getSeconds();
var minute = now.getMinutes();
var hour = now.getHours();
//小时必须获取浮点类型,产生偏移(小时+分钟比)
hour = hour+minute/60;
//将24小时转换为12小时
hour = hour>12?hour-12:hour;
//填写标题
ctx.font = '36px 微软雅黑';
var grident = ctx.createLinearGradient(0,0,300,0); //创建渐变
grident.addColorStop(0.5,'yellow');
grident.addColorStop(0.8,'blue');
grident.addColorStop(1,'red');
ctx.fillStyle = grident; //用渐变来填充颜色
ctx.fillText ('canvas 时钟',200,60);
//画圆
ctx.save();
ctx.beginPath();
ctx.lineWidth = 5;
ctx.arc(300,300,200,0,Math.PI*360/180,false);
ctx.strokeStyle = 'blue';
ctx.stroke();
ctx.closePath();
ctx.restore();
//画时钟的刻度 12个刻度,每个刻度旋转30度
for(var i=0;i<=12;i++){
ctx.save();
ctx.strokeStyle = 'black';
ctx.lineWidth = 7;
ctx.translate(300,300); //设置画布的原点
ctx.rotate(i*Math.PI*30/180,300,300); //rotate()后两个参数设置旋转的中心点
ctx.beginPath();
ctx.moveTo(0,-172);
ctx.lineTo(0,-192);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
//画秒钟的刻度 60个刻度,每个刻度旋转6度
for(var i=0;i<=60;i++){
ctx.save();
ctx.strokeStyle = 'black';
ctx.lineWidth = 3;
ctx.translate(300,300); //设置画布的原点
ctx.rotate(i*Math.PI*6/180,300,300); //rotate()后两个参数设置旋转的中心点
ctx.beginPath();
ctx.moveTo(0,-182);
ctx.lineTo(0,-192);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
//标注小时
ctx.save();
ctx.fillStyle = 'deeppink';
ctx.font = '22px 微软雅黑';
ctx.lineWidth = 6;
ctx.fillText(12,286,150);
ctx.fillText(1,370,170);
ctx.fillText(2,430,230);
ctx.fillText(3,456,310);
ctx.fillText(4,430,390);
ctx.fillText(5,380,440);
ctx.fillText(6,295,468);
ctx.fillText(7,215,446);
ctx.fillText(8,158,390);
ctx.fillText(9,132,310);
ctx.fillText(10,156,230);
ctx.fillText(11,210,176);
ctx.restore();
//画时针
ctx.save();
ctx.lineWidth = 7;
ctx.strokeStyle = 'yellow';
ctx.translate(300,300);
ctx.rotate(hour*30*Math.PI/180);
ctx.beginPath();
ctx.moveTo(0,20);
ctx.lineTo(0,-140);
ctx.stroke();
ctx.closePath();
ctx.restore();
//画分针
ctx.save();
ctx.lineWidth = 5;
ctx.strokeStyle = 'blue';
ctx.translate(300,300);
ctx.rotate(minute*6*Math.PI/180);
ctx.beginPath();
ctx.moveTo(0,20);
ctx.lineTo(0,-168);
ctx.stroke();
ctx.closePath();
ctx.restore();
//画秒针
ctx.save();
ctx.lineWidth = 3;
ctx.strokeStyle = 'red';
ctx.translate(300,300);
ctx.rotate(seconds*6*Math.PI/180);
ctx.beginPath();
ctx.moveTo(0,20);
ctx.lineTo(0,-186);
ctx.stroke();
ctx.closePath();
ctx.restore();
//圈出时针,分针,秒针的交叉点
ctx.save();
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle = 'red';
ctx.arc(300,300,5,0,360*Math.PI/180,false);
ctx.fillStyle = '#fff';
ctx.fill();
ctx.stroke();
ctx.closePath();
//装饰秒针
ctx.save();
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle = 'red';
ctx.translate(300,300);
ctx.rotate(seconds*6*Math.PI/180); //让当前的装饰跟着秒针一起转动
ctx.arc(0,-160,5,0,360*Math.PI/180,false);
ctx.fillStyle = '#fff';
ctx.fill();
ctx.stroke();
ctx.restore();
}
drawClock();
setInterval(function(){
ctx.clearRect(0,0,canvas.width,canvas.height);
drawClock();
},1000);
}
</script>
</body>
</html>
效果: