在本篇文章中,我们将利用canvas的知识来绘制一个时钟动画。
1、布局篇
1.1基础布局
首先我们在页面中放置一个canvas画布,将画布的颜色设置成#eee,宽高为400px。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>canvas绘制矩形</title> <style type="text/css"> #canvas{ background: #eee; } </style> </head> <body> <canvas id="canvas" width="400" height="400">您的浏览器out了</canvas> </body> </html>
1.2、获取canvas绘图环境
window.onload=function(){ var canvas=document.getElementById('canvas'); var context=canvas.getContext('2d'); }
1.3、绘制时钟表盘
首先我们利用arc方法在画布上绘制一个半径为100的圆,圆心的横坐标为200,纵坐标也为200
var originx=200; var originy=200; var radius=100; context.beginPath(); context.arc(originx,originy,radius,0,2*Math.PI); context.stroke();
效果预览:
1.4、修饰时钟表盘
由上图可以看出,如果仅仅是绘制一个圆,表盘显得有点生硬,所以接下来我们通过以下代码给表盘添加一点阴影以及填充一个渐变色:
/*阴影*/ context.shadowColor='#888'; context.shadowOffsetX=1; context.shadowOffsetY=1; context.shadowBlur=3; /*渐变色*/ var oColor=context.createRadialGradient(originx,originy,1,originx,originy,100); oColor.addColorStop(0,"#efefef"); oColor.addColorStop(1,"#cecece"); context.fillStyle=oColor; context.lineWidth=8; context.beginPath(); context.strokeStyle=oColor; //边框设置成渐变 context.arc(originx,originy,radius,0,2*Math.PI); context.stroke(); context.fill();
效果预览:
1.5、绘制表盘刻度
如何绘制表盘的刻度,接下来我们利用一张图来做一个讲解:
step1:首先我们来画出三点钟方向的刻度,设置刻度的颜色为#888,宽度为2,我们知道三点钟方向的角度为0度,那么由上面公式推导我们知道,三点钟方向刻度线的起点横坐标为originx+radius*Math.cos(0),纵坐标为originy+radius*Math.sin(0),假设线的长度为8px,那么刻度线的终点横坐标为originx+(radius-8)*Math.cos(0),纵坐标为
originy+(radius-8)*Math.sin(0)。如下代码:
//绘制1个刻度 context.strokeStyle="#888"; context.lineWidth=2; context.beginPath(); context.moveTo(originx+radius*Math.cos(0),originy+radius*Math.sin(0)); context.lineTo(originx+(radius-8)*Math.cos(0),originy+(radius-8)*Math.sin(0)); context.stroke();
效果如下:
step2:时钟一共有60个刻度,圆的总的角度是360度,那么每个刻度的角度则为6度,如果利用for循环60次,实现60个刻度的绘制,那么每个刻度的角度则为i*6,之前已经说过,javascript的sin方法只接收弧度,不接收角度,所以我们利用之前学过的方法,将弧度转换为角度,具体代码如下:
function drawMark(){ for (var i=0;i<60;i++) { //绘制1个刻度 context.strokeStyle="#888"; context.lineWidth=2; context.beginPath(); context.moveTo(originx+radius*Math.cos(i*6*Math.PI/180),originy+radius*Math.sin(i*6*Math.PI/180)); //i*6是每个刻度的角度*Math.PI/180转换为弧度 context.lineTo(originx+(radius-4)*Math.cos(i*6*Math.PI/180),originy+(radius-4)*Math.sin(i*6*Math.PI/180)); context.stroke(); }; }; /*去掉阴影*/ context.shadowColor='#888'; context.shadowOffsetX=0; context.shadowOffsetY=0; context.shadowBlur=0; drawMark();
效果如下:
step3:我们知道,时钟的表盘凡是遇到5的整数刻度会比正常的刻度会长一点,并且粗一点,所以我们接下来将代码做以下更改,来实现这个效果
function drawMark(){ for (var i=0;i<60;i++) { //绘制1个刻度 var angle=i*6*Math.PI/180; var radius1=radius-4; var lw=2; if(i%5==0){ radius1=radius-8; lw=4; } context.strokeStyle="#888"; context.lineWidth=lw; context.beginPath(); context.moveTo(originx+radius*Math.cos(angle),originy+radius*Math.sin(angle)); //i*6是每个刻度的角度*Math.PI/180转换为弧度 context.lineTo(originx+(radius1)*Math.cos(angle),originy+(radius1)*Math.sin(angle)); context.stroke(); }; };
效果预览:
1.6绘制时针分钟秒针
step1:因为时针分秒针三个针的绘制方法都是一样的,不同的是长度,角度,宽度以及颜色不一样,所以我们接下来会封装一个函数,实现三个针的绘制
/*时针*/ drawPoint(55,20,4,"#000"); /*分针*/ drawPoint(65,30,3,"#888"); /*秒针*/ drawPoint(75,40,2,"red"); /*小圆*/ context.fillStyle="#aaa" context.beginPath(); context.arc(originx,originy,4,0,2*Math.PI); context.stroke(); context.fill(); /*绘制指针*/ function drawPoint(radius,angle,width,color){ context.lineWidth=width; context.strokeStyle=color; context.beginPath(); context.moveTo(originx,originy); context.lineTo(originx+radius*Math.cos(angle*Math.PI/180),originy+radius*Math.sin(angle*Math.PI/180)); context.stroke(); }
效果预览:
2、让时钟动起来
function clock(){ context.clearRect(0,0,400,400); /*阴影*/ context.shadowColor="#888"; context.shadowOffsetX=1; context.shadowOffsetY=1; context.shadowBlur=3; /*渐变色*/ var oColor=context.createRadialGradient(originx,originy,1,originx,originy,100); oColor.addColorStop(0,"#efefef"); oColor.addColorStop(1,"#cecece"); context.fillStyle=oColor; context.lineWidth=8; context.beginPath(); context.strokeStyle=oColor; //边框设置成渐变 context.arc(originx,originy,radius,0,2*Math.PI); context.stroke(); context.fill(); /*去掉阴影*/ context.shadowColor='#888'; context.shadowOffsetX=0; context.shadowOffsetY=0; context.shadowBlur=0; drawMark(); var oDate=new Date(); var ha=oDate.getHours()*30+(oDate.getMinutes()*6/12)-90; var ma=oDate.getMinutes()*6-90; var sa=oDate.getSeconds()*6-90; /*时针*/ drawPoint(45,ha,4,"#000"); /*分针*/ drawPoint(60,ma,3,"#888"); /*秒针*/ drawPoint(75,sa,2,"red"); /*小圆*/ context.shadowColor='#888'; context.shadowOffsetX=1; context.shadowOffsetY=1; context.shadowBlur=1; context.fillStyle="#aaa" context.beginPath(); context.arc(originx,originy,4,0,2*Math.PI); context.stroke(); context.fill(); } clock(); setInterval(clock,1000)
效果演示: