画钟表前,我们需要弄清楚钟表的构造和各个元素间的关系
同时还要学会弧度的运用
难点还是在于对context.save()和context.restore()的理解
把思路理清,写起来也会变得简单
效果图:
下面来看一下代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
#div{
text-align: center;
}
#canvas{
border: 1px solid #000;
}
</style>
</head>
<body>
<div id="div">
<canvas id="canvas" width="500px" height="500px"></canvas>
</div>
<script>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var width=canvas.width; //获取画布的宽
var height=canvas.height; //获取画布的高
var r=width/2; //设置圆的半径为宽的一半
function fun(){
ctx.save() //保存当前的状态
ctx.beginPath(); //开启一条路径
ctx.translate(r,r); //将画布原点改为(r,r)
ctx.arc(0,0,r-5,0,Math.PI*2); //设置半径为R-5的圆,因为设置了线宽为10,所以半径减去了线宽的一半
ctx.closePath(); //闭合路径
ctx.lineWidth=10;
ctx.stroke();
//
var li=[3,4,5,6,7,8,9,10,11,12,1,2] //设置一个数组保存钟表的数字刻度,按照弧度的起始位置设置
for(var i=0 ;i<li.length;i++){
ctx.beginPath();
ctx.fillStyle="#000000"
ctx.textBaseline="middle";
ctx.textAlign="center";
ctx.font="18px Arial";
var x=Math.cos(Math.PI*2/12*i)*(r-30); //用三角函数cos计算出数字所在的X坐标
var y=Math.sin(Math.PI*2/12*i)*(r-30); //用三角函数cos计算出数字所在的X坐标
ctx.fillText(""+li[i]+"",x,y);
ctx.closePath();
for(var j=0 ;j<60;j++){ //画60个圆点为分秒刻度
ctx.beginPath();
var x=Math.cos(Math.PI*2/60*j)*(r-15);
var y=Math.sin(Math.PI*2/60*j)*(r-15);
if(j%5==0){
ctx.fillStyle="#000000"; //给整点刻度圆点设置为黑色
}else{
ctx.fillStyle="#ccc"; //其余设置为灰色
}
ctx.arc(x,y,2,0,Math.PI*2);
ctx.fill();
ctx.closePath();
}
}
}
function drawHour(hour,minu){ //设置时针方法
ctx.save(); //保存当前的状态
ctx.beginPath();
ctx.lineWidth=6;
var rad = Math.PI*2 / 12 * hour;
var radminu = Math.PI / 360 * minu;
ctx.rotate(rad + radminu) //时针的旋转角度
ctx.moveTo(0,10);
ctx.lineTo(0,-r+150); //绘制时针
ctx.lineCap="round"; //设置时针的圆角样式,lineCap受closePath影响,两者同时出现时,lineCap无效
ctx.stroke()
ctx.restore() //返回之前保存过的状态
}
function drawMinu(minu){ //设置分针方法
ctx.save(); //保存当前的状态
ctx.beginPath();
ctx.lineWidth = 4;
var rad = Math.PI * 2 / 60 * minu;
ctx.rotate(rad)
ctx.moveTo(0,10);
ctx.lineTo(0,-r+100); //绘制分针
ctx.lineCap="round"; //设置时针的圆角样式,lineCap受closePath影响,两者同时出现时,lineCap无效
ctx.stroke() //描边
ctx.restore() //返回之前保存过的状态
}
function drawmiao(miao){
ctx.save(); //保存当前的状态
ctx.beginPath();
ctx.lineWidth = 1;
var rad = Math.PI * 2 / 60 * miao;
ctx.rotate(rad)
ctx.moveTo(-2,20);
ctx.lineTo(2,20);
ctx.lineTo(1,-r+50);
ctx.lineTo(-1,-r+50);
ctx.closePath() //绘制秒针
ctx.fillStyle="#f00"
ctx.fill()
ctx.restore() //返回之前保存过的状态
}
function draw(){
ctx.clearRect(0,0,width,height);
var datenow = new Date();
var hour = datenow.getHours();
var minu = datenow.getMinutes();
var miao = datenow.getSeconds();
fun()
drawHour(hour,minu)
drawMinu(minu)
drawmiao(miao) //执行
ctx.restore() //返回之前保存过的状态
}
draw() //执行
setInterval(draw,1000) //定时器,设置间隔时间为1s
</script>
</body>
</html>