canvas 时钟2
用另外一种思路绘制时钟
<canvas id="myCanvas" width="200" height="200" style="border:1px solid #f00;"></canvas>
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
var width=ctx.canvas.width;
var height=ctx.canvas.height;
var r=width/2;
function drawInit(){
ctx.save();
ctx.translate(r,r);
ctx.beginPath();
ctx.lineStyle='#f00';
ctx.lineWidth=10;
ctx.arc(0,0,r-5,0,2*Math.PI,false);
ctx.stroke();
ctx.closePath();
//时间点
var time=[3,4,5,6,7,8,9,10,11,12,1,2];
ctx.beginPath();
ctx.font='bold 16px arial';
ctx.textAlign='center';
ctx.textBaseline='middle';
time.forEach(function(ele,index){
var rad=2*Math.PI/12*index;
var y=Math.sin(rad)*(r-30);
var x=Math.cos(rad)*(r-30);
ctx.fillText(ele,x,y);
});
ctx.closePath();
//刻度点
for(var i=0;i<60;i++){
var rad=2*Math.PI/60*i;
var x=Math.cos(rad)*(r-18);
var y=Math.sin(rad)*(r-18);
ctx.beginPath();
ctx.arc(x,y,2,0,2*Math.PI,false);
if(i%5==0){
ctx.fillStyle='#000';
}else{
ctx.fillStyle='#ccc';
}
ctx.fill();
ctx.closePath();
}
}
function drawHours(hour,minutes){
var rad=2*Math.PI/12*hour;
var mrad=2*Math.PI/12/60*minutes
ctx.save();
ctx.rotate(rad+mrad);
ctx.beginPath();
ctx.lineWidth=8;
ctx.lineCap='round';
ctx.moveTo(0,10);
ctx.lineTo(0,-35);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
function drawMinutes(minutes,second){
var rad=2*Math.PI/60*minutes;
var sad=2*Math.PI/60/60*second;
ctx.save();
ctx.rotate(rad+sad);
ctx.beginPath();
ctx.lineWidth=4;
ctx.lineCap='round';
ctx.moveTo(0,10);
ctx.lineTo(0,-45);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
function drawSeconds(second){
var rad=2*Math.PI/60*second;
ctx.save();
ctx.rotate(rad);
ctx.beginPath();
ctx.moveTo(-2,20);
ctx.lineTo(2,20);
ctx.lineTo(1,-50);
ctx.lineTo(-1,-50);
ctx.lineTo(-2,20);
ctx.fillStyle='#ccc';
ctx.fill();
ctx.closePath();
ctx.restore();
}
function drawDot(){
ctx.beginPath();
ctx.arc(0,0,5,0,2*Math.PI,false);
ctx.fillStyle='#fff';
ctx.fill();
ctx.closePath();
}
function draw(){
var now=new Date();
var hours=now.getHours();
var minutes=now.getMinutes();
var seconds=now.getSeconds();
ctx.clearRect(0, 0, width, height);
drawInit();
drawHours(hours,minutes);
drawMinutes(minutes,seconds);
drawSeconds(seconds);
drawDot();
ctx.restore();
}
setInterval(function(){
draw();
},1000);
重难点
一、绘制时间点和绘制刻度点
function drawInit(){
ctx.save();
ctx.translate(r,r);
ctx.beginPath();
ctx.lineStyle='#f00';
ctx.lineWidth=10;
ctx.arc(0,0,r-5,0,2*Math.PI,false);
ctx.stroke();
ctx.closePath();
//时间点
var time=[3,4,5,6,7,8,9,10,11,12,1,2];
ctx.beginPath();
ctx.font='bold 16px arial';
ctx.textAlign='center';
ctx.textBaseline='middle';
time.forEach(function(ele,index){
var rad=2*Math.PI/12*index;
var y=Math.sin(rad)*(r-30);
var x=Math.cos(rad)*(r-30);
ctx.fillText(ele,x,y);
});
ctx.closePath();
//刻度点
for(var i=0;i<60;i++){
var rad=2*Math.PI/60*i;
var x=Math.cos(rad)*(r-18);
var y=Math.sin(rad)*(r-18);
ctx.beginPath();
ctx.arc(x,y,2,0,2*Math.PI,false);
if(i%5==0){
ctx.fillStyle='#000';
}else{
ctx.fillStyle='#ccc';
}
ctx.fill();
ctx.closePath();
}
}
这种方法和上篇canvas绘制手表的方法不太一样。
- 这种方法在一开始绘制表盘结束后就想原点移动到圆表盘的中心位置上去。
- 在绘制时间点的时候从时钟3对应的水平线开始,时间点对应的x、y轴坐标直接用弧度来计算不像上一篇文章一样,先计算角度,再通过角度转成弧度(
var rad=2*Math.PI/12*index
) - 刻度点和上篇文章不一样的地方上,上一篇文章的刻度点是长方形,因为刻度的朝向要指向圆心所以需要通过旋转的方法来正确的摆放刻度,而此文中的方法由于刻度是圆形,所有不会有刻度没有指向圆心的情况,这样也就只需要计算出时间点对应的x、y轴坐标就可以了
二、如何让时针、分针、秒针在正确的时间点在正确的位置
function drawHours(hour,minutes){
var rad=2*Math.PI/12*hour;
var mrad=2*Math.PI/12/60*minutes
ctx.save();
ctx.rotate(rad+mrad);
ctx.beginPath();
ctx.lineWidth=8;
ctx.lineCap='round';
ctx.moveTo(0,10);
ctx.lineTo(0,-35);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
function drawMinutes(minutes,second){
var rad=2*Math.PI/60*minutes;
var sad=2*Math.PI/60/60*second;
ctx.save();
ctx.rotate(rad+sad);
ctx.beginPath();
ctx.lineWidth=4;
ctx.lineCap='round';
ctx.moveTo(0,10);
ctx.lineTo(0,-45);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
时针、分针、秒针在正确的时间点在正确的位置是指:当此时时间是4:30:60的时候,时针不应该正对着4这个时间点,而应该在4-5之间,分针也不应该正对着6这个时间点,而应该在6-7之间靠近6的位置,所以我们需要计算出此时 时针应该向4后偏移多少,分针应该向6后偏移多少
即有
var rad=2*Math.PI/12*hour;//2π个弧度平均分成12等分,求得每两个时间点之间的弧度,然后乘以小时数(时针指向的数字)得到时针应转动的弧度
var mrad=2*Math.PI/12/60*minutes//2π个弧度平均分成12等分,求得每两个时间点之间的弧度,再除以60求得每一个小时中没一分钟对应的弧度,最后乘以分钟数,得到分钟应转动的弧度
var rad=2*Math.PI/60*minutes;//2π个弧度平均分成60等分,求得每两个刻度点之间的弧度,然后乘以分钟数(分针指向的数字)得到分针应转动的弧度
var sad=2*Math.PI/60/60*second;//2π个弧度平均分成60等分,求得每两个刻度点之间的弧度,再除以60求得每一分钟中没一秒钟对应的弧度,最后乘以秒钟数,得到秒针应转动的弧度