canvas简单实现动态时钟

使用到的知识:

1.     获取系统时间

2.     画图形,空心图形,实心图形,以及一些属性

3.     for循环

准备工作:添加一块画布1000*1000(随意),引用canvas.js

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus?">
  <meta name="Author" content="华慕熊">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>动态时钟</title>
  <script src = "canvas.js"></script>
  <style>
body,h1,h2,h3,h4,h5,h6,*{margin:0px;}
  </style>
 </head>
 <body>
<canvas id="myCanvas" width="1000" height="1000"></canvas>
 </body>
</html>

canvas.js

window.onload = function(){  //html5加载完成后才加载这个文件
	var myCanv = document.getElementById("myCanvas");//通过id获取到canvas画布(演员)
	var oCanv = myCanv.getContext("2d");  //2d环境(舞台)

}

开始画图:canvas.js

静态效果

图中有圆,刻度线,时分秒针,点数。另外的是系统时间。

我们在圆心为(200,200)的位置画一个半径为150的圆

oCanv.beginPath();//	起始一条路径,或重置当前路径 
oCanv.arc(200,200,150,0,360*Math.PI/180,false);   //这里是弧度
oCanv.stroke();//画

解释:arc(x,y,r,sAangle,eAangle,conterclockwise);

此时的效果图:

下边画分针刻度线:

此时我们需要思考并要明白的几件事:

  1. 刻度线怎么画出来的?
  2. 画圆的起始点在哪?
  3. 应该在哪?

解决思考的问题:

先看一段代码与效果:

        oCanv.beginPath();
	oCanv.moveTo(200,200);
	oCanv.arc(200,200,150,0,6*Math.PI/180,false);
	oCanv.closePath();
	oCanv.stroke();

这段代码是从0度顺时针画了一个6度的扇形

一、画分针刻度线

一周有60个刻度线,此时可以说是两个刻度线画出来了,只要使用一下循环即可了:

        oCanv.beginPath();
	for( var i=0; i<60; i++){
		oCanv.moveTo(200,200);
		oCanv.arc(200,200,150,6*i*Math.PI/180,6*(i+1)*Math.PI/180,false);
	}
	oCanv.closePath();
	oCanv.stroke();

此时的效果图是:

其实这里我们应该能想到该怎么做了吧?

画一个比这个稍微小点的白色实心圆即可(圆心要一致)!

        oCanv.beginPath();
	oCanv.fillStyle = "#fff";
	oCanv.arc(200,200,150*19/20,0,360*Math.PI/180,false);
	oCanv.fill();
	oCanv.stroke();

此时的效果:

好像差不多,只是我们不想要内圆的边,其实写到fill()就可以了,既然写到那就可以了,我为什么还要写呢?我只是在乎你疑惑我为什么不写呢。

为了实现我们想要的效果,去掉stroke()即可。图不粘了

二、画时针刻度线

方法类似画分针刻度线,不同的是时针应该有12条线,之间是30度,线条比较粗

        oCanv.beginPath();
	oCanv.lineWidth=3;//线条的粗细,默认是1,3就加粗了
	for(var i=0;i<12;i++){
		oCanv.moveTo(200,200);
		oCanv.arc(200,200,150,30*i*Math.PI/180,30*(i+1)*Math.PI/180,false);
	}
	oCanv.closePath();
	oCanv.stroke();
	//画实心圆
	oCanv.beginPath();
	oCanv.fillStyle = "#fff";
	oCanv.arc(200,200,150*18/20,0,360*Math.PI/180,false);
	oCanv.fill();

效果图:

三、获取系统的时间(电脑时间)

  1. Date()对象
  2. Hours()方法/时
  3. Minutes()方法/分
  4. Seconds()方法/秒
        var oDate = new Date();
	var oHours = oDate.getHours();
	var oMin = oDate.getMinutes();
	var oSec = oDate.getSeconds();
	document.write(oHours+"时"+oMin+"分"+oSec+"秒");

打印一下时间:

我们要知道,虽然说时间是一秒一秒走的,但在这里可就不是这么说的了,应该说是多少弧度的走,所以把时间用弧度算出来,那么问题来了,我们时钟的0在12的位置,而我们现在0的位置在钟表的3的位置,那么0-3之间的角度是90度,即90*π/180

如果我们只画一个圆,那么起点是钟表的3的位置,但我们的画钟表的0点0时0分都是在12的位置,那么怎么才能使其都为钟表上0的位置呢?

先看代码:

        var oHoursValues = (-90+oHours*30)*Math.PI/180;
	var oMinValues = (-90+oMin*6)*Math.PI/180;
	var oSecValues = (-90+oSec*6)*Math.PI/180;

首先-90使起点到钟表上12的位置,+oHours*30是现在时刻的度数,比如现在是晚上21:30,oHours=21,21x30°=630°(=9x30=270°),应该在钟表的9的位置,我们可以看看:

        //画时针
	oCanv.beginPath();
	oCanv.lineWidth=5;
	oCanv.moveTo(200,200);
	oCanv.arc(200,200,150*8/20,oHoursValues,oHoursValues,false);  //用画圆的方法画的时针, 让起点与终点一个位置即可,感兴趣的试试画直线
	oCanv.closePath();
	oCanv.fill();
	oCanv.stroke();

分针与秒针类似时针。

现在我们让它动起来:

新知识:setInterval()方法,间隔多长时间刷新页面,我们需要1秒,它的单位是毫秒,那么就是1000毫秒

在这之前可以先清除一下画布:clearRect(0, 0, 200, 200);//清空画布

最后我们加上小时数(点数)

            var deg = 2 * Math.PI / 12;//弧度=角度*Math.PI/180;
            ogc.save();
            ogc.beginPath();
            ogc.translate(200, 200);
            for (var i = 1; i < 13; i++) {
                var x1 = Math.sin(i * deg);//正弦
                var y1 = -Math.cos(i * deg);//余弦
                ogc.fillStyle = "black";//字体颜色
                ogc.font = "noraml 30px Calibri";//字体
                ogc.textAlign = 'center';
                ogc.textBaseline = 'middle';
                ogc.fillText(i, x1 * 125, y1 * 125);//填充 125这个值越大 越显示在圆外面
            }
            ogc.closePath();
            ogc.restore();

此时就是最开始的图片的样子了。

修改后的完整的代码:canvas.js

window.onload = function(){  //html5加载完成后才加载这个文件
	setInterval(myCanvas,1000);
}
function myCanvas(){
	var myCanv = document.getElementById("myCanvas");//通过id获取到canvas画布(演员)
	var oCanv = myCanv.getContext("2d");  //2d环境(舞台)
//	ogc.clearRect(0, 0, circleX, circleY);//清空画布
	//画分针刻度线
	oCanv.beginPath();
	for( var i=0; i<60; i++){
		oCanv.moveTo(200,200);
		oCanv.arc(200,200,150,6*i*Math.PI/180,6*(i+1)*Math.PI/180,false);
	}
	oCanv.closePath();
	oCanv.stroke();

	//画实心圆
	oCanv.beginPath();
	oCanv.fillStyle = "#fff";
	oCanv.arc(200,200,150*19/20,0,360*Math.PI/180,false);
	oCanv.fill();

	/*画时针刻度线*/
	oCanv.beginPath();
	oCanv.lineWidth=3;//线条的粗细,默认是1,3就加粗了
	for(var i=0;i<12;i++){
		oCanv.moveTo(200,200);
		oCanv.arc(200,200,150,30*i*Math.PI/180,30*(i+1)*Math.PI/180,false);
	}
	oCanv.closePath();
	oCanv.stroke();
	//画实心圆
	oCanv.beginPath();
	oCanv.fillStyle = "#fff";
	oCanv.arc(200,200,150*18/20,0,360*Math.PI/180,false);
	oCanv.fill();

	//获取本地时间
	var oDate = new Date();
	var oHours = oDate.getHours();
	var oMin = oDate.getMinutes();
	var oSec = oDate.getSeconds();

	//转换成弧度
	var oHoursValues = (-90+oHours*30)*Math.PI/180;
	var oMinValues = (-90+oMin*6)*Math.PI/180;
	var oSecValues = (-90+oSec*6)*Math.PI/180;

	//画时针
	oCanv.beginPath();
	oCanv.lineWidth=5;
	oCanv.moveTo(200,200);
	oCanv.arc(200,200,150*8/20,oHoursValues,oHoursValues,false);
	oCanv.closePath();
	oCanv.fill();
	oCanv.stroke();

	//画分针
	oCanv.beginPath();
	oCanv.lineWidth=3;
	oCanv.moveTo(200,200);
	oCanv.arc(200,200,150*12/20,oMinValues,oMinValues,false);
	oCanv.closePath();
	oCanv.fill();
	oCanv.stroke();

	//画秒针
	oCanv.beginPath();
	oCanv.lineWidth=1;
	oCanv.moveTo(200,200);
	oCanv.arc(200,200,150*15/20,oSecValues,oSecValues,false);
	oCanv.closePath();
	oCanv.fill();
	oCanv.stroke();

	//画数字
    var deg = 2 * Math.PI / 12;//弧度=角度*Math.PI/180;
    oCanv.save();
    oCanv.beginPath();
    oCanv.translate(200, 200);
    for (var i = 1; i < 13; i++) {
        var x1 = Math.sin(i * deg);//正弦
        var y1 = -Math.cos(i * deg);//余弦
        oCanv.fillStyle = "black";//字体颜色
        oCanv.font = "noraml 30px Calibri";//字体
        oCanv.textAlign = 'center';
        oCanv.textBaseline = 'middle';
        oCanv.fillText(i, x1 * 125, y1 * 125);//填充 125这个值越大 越显示在圆外面
    }
    oCanv.closePath();
    oCanv.restore();
}

但由于里边的圆心,半径,点数都是固定好的,如果要修改圆心位置、半径大小会比较麻烦,我们可以封装一下,下边是我之前写的一个封装好的代码:

window.onload = function(){
    setInterval(oCan, 1000);//毫秒
}	 
function oCan(){
    var circleX = 200;
    var circleY = 200;
    var circleR = 150;
    var oPI = Math.PI/180;
    var oc = document.getElementById("myCanvas");
    var ogc = oc.getContext("2d");
    ogc.clearRect(0, 0, circleX, circleY);//清空画布
    ogc.beginPath();
    /*画分针刻度*/

    for(var i=0; i<60; i++){
	ogc.moveTo(circleX,circleY);
	ogc.arc(circleX,circleY,circleR,6*oPI*i,6*oPI*(i+1),false);
    }
    ogc.closePath();
    ogc.stroke();
    //画一个白色实心圆盖住其他的线,使其出来分针刻度线
    ogc.beginPath();
    ogc.fillStyle = "#fff";
    ogc.arc(circleX,circleY,circleR * 19 / 20,0,360*oPI,false);
    ogc.closePath();
    ogc.fill();
    //ogc.stroke();//为什么注释,会出现黑框

    /*画时针刻度*/
    ogc.beginPath();
    ogc.lineWidth = 3;
    for(var i=0; i<12; i++){
        ogc.moveTo(circleX,circleY);
        ogc.arc(circleX,circleY,circleR,30*oPI*i,30*oPI*(i+1),false);
    }
    ogc.closePath();
    ogc.stroke();
    //画一个白色实心圆盖住其他的线,使其出来时针刻度线
    ogc.beginPath();
    ogc.fillStyle = "#fff";
    ogc.arc(circleX,circleY,circleR*18/20,0,360*oPI,false);
    ogc.closePath();
    ogc.fill();

    /*求当前时间*/
    var oDate = new Date();
    var oHours = oDate.getHours();
    var oMin = oDate.getMinutes();
    var oSec = oDate.getSeconds();

    /*把时间转换成弧度*/
    var oHoursValues = (-90 + oHours * 30)*oPI;
    var oMinValues = (-90 + oMin * 6)*oPI;
    var oSecValues = (-90 + oSec * 6)*oPI;
    /*画时针*/
    ogc.beginPath();
    ogc.lineWidth=5;
    ogc.moveTo(circleX,circleY);
    ogc.arc(circleX,circleY,circleR*8/20,oHoursValues,oHoursValues,false);
    ogc.closePath();
    ogc.fill();
    ogc.stroke();

    /*画分针*/
    ogc.beginPath();
    ogc.lineWidth = 3;
    ogc.moveTo(circleX,circleY);
    ogc.arc(circleX,circleY,circleR*12/20,oMinValues,oMinValues,false);
    ogc.closePath();
    ogc.fill();
    ogc.stroke();

    /*画秒针*/
    ogc.beginPath();
    ogc.lineWidth = 1;
    ogc.moveTo(circleX,circleY);
    ogc.arc(circleX,circleY,circleR*15/20,oSecValues,oSecValues,false);
    ogc.closePath();
    ogc.fill();
    ogc.stroke();

    //画数字
    var deg = 2 * Math.PI / 12;//弧度=角度*Math.PI/180;
    ogc.save();
    ogc.beginPath();
    ogc.translate(circleX, circleY);
    for (var i = 1; i < 13; i++) {
        var x1 = Math.sin(i * deg);//正弦
        var y1 = -Math.cos(i * deg);//余弦
        ogc.fillStyle = "black";//字体颜色
        ogc.font = "noraml 30px Calibri";//字体
        ogc.textAlign = 'center';
        ogc.textBaseline = 'middle';
        ogc.fillText(i, x1 * (circleR*3/4), y1 * (circleR*3/4));//填充 125这个值越大 越显示在圆外面
    }
    ogc.closePath();
    ogc.restore();
}

有什么错误或写的不好的地方,还请不吝赐教,谢谢!

原文地址:http://blog.51cto.com/13534640/2120441

时间: 2024-08-25 03:46:02

canvas简单实现动态时钟的相关文章

利用canvas画一个动态时钟

目标:利用canvas画布画一个动态时钟,根据目前的时间可以实时更新的,可以在过程中添加一些效果,比如让时钟外围的一圈颜色渐变,时钟上的数字颜色改变,时钟的指针颜色改变... 设置一个定时器 先放上一张效果图,参考一下 先建一个画布,写好样式 <style type="text/css"> *{ margin: 0; padding: 0; } div{ //设置div的text-align为center,margin-top text-align: center; mar

canvas :原生javascript编写动态时钟

canvas :原生javascript编写动态时钟 此时针是以画布的中心为圆心: g.translate(width/2,width/2); 此函数是将画布的原点移到(width/2,width/2) 绘制表盘 function jiang(){ r = width/2 g.clearRect(0, 0, 600, 600); g.save(); g.translate(r, r); g.rotate(-Math.PI / 2); //分钟刻度线 for(var i = 0; i < 60;

Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)

在前面章节的讨论中,我们一直基于一个假设:Linux中的时钟事件都是由一个周期时钟提供,不管系统中的clock_event_device是工作于周期触发模式,还是工作于单触发模式,也不管定时器系统是工作于低分辨率模式,还是高精度模式,内核都竭尽所能,用不同的方式提供周期时钟,以产生定期的tick事件,tick事件或者用于全局的时间管理(jiffies和时间的更新),或者用于本地cpu的进程统计.时间轮定时器框架等等.周期性时钟虽然简单有效,但是也带来了一些缺点,尤其在系统的功耗上,因为就算系统目

js+css3实现动态时钟-------Day66

昨天搬家一天,宽带到最后也没有安装上,颇为恼火,但是收拾了一天新租的房屋,倒有了颇多的想法,这里先来实现一个--动态时钟(已经上传到资源里了,图片整的有些粗糙了,汗...) 这里来记录下,这个看起来简单好实现的功能,我在实现的过程中碰到了哪些问题,因为这时还没查看网上的代码,只是根据自己现阶段的学习来做的,可能会有些麻烦,有些粗糙,但是终归是实现了这个效果,心里还是小开心了下. 先来张最终实现的效果图(静态图片); 首先准备素材,我从网上搜到了一个时钟的素材,谁让我的ps还菜的菜呢,然后我有了表

linux动态时钟探索

在早期的linux内核版本的时间概念都是由周期时钟提供的.虽然比较有效,但是,对于关注能耗电量的系统上,就不能满足长时间休眠的需求,因为周期系统要求必须在一定的频率下,周期性的处于活动状态.因此,linux提出了tickless system,即无时钟系统.其关键就是判定系统当前是否无事可做,若是则禁用时钟系统.判定系统当前无事可做的依据是:如果运行队列时没有活动进程,内核将选择idle进程来运行,而此时动态时钟发挥作用. 一.动态时钟使用的数据结构tick_sched 1 struct tic

.NET实时2D渲染入门&#183;动态时钟

.NET实时2D渲染入门·动态时钟 从小以来"坦克大战"."魂斗罗"等游戏总令我魂牵梦绕.这些游戏的基础就是2D实时渲染,以前没意识,直到后来找到了Direct2D.我的2D实时渲染入门,是从这个动态时钟开始的. 本文将使用我写的"准游戏引擎"FlysEngine完成.它是对Direct2D和.NET库SharpDX浅层次的封装,隐藏了一些细节,简化了一些调用.同时还保留了Direct2D的原汁原味. 本文的最终效果如下: 绘制动态时钟 要绘制动

SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法

首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33# 这篇文章中讲的是spring中使用spring data jpa,使用了xml配置文件.我现在使用的是spring boot ,没有了xml文件配置就方便多了.我同样尝试了两种方式,也都是简单的查询,需要更复杂的查询,还需要我研究研究.往下看,需要先配置springboot的开发环境,需要大致了解springboot,这里可以看下面两篇文章: springboot 项目新建 springboot

JavaScript+svg绘制的一个动态时钟

结果图: 代码如下: <!DOCTYPE html> <html> <head> <title>动态时钟</title> </head> <body > <script type="text/javascript"> function updateTime(){ //更新svg时钟来显示当前时间 var now =new Date(); //当前时间 var min = now.getMin

使用延时器实现动态时钟

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-cn"> 3 <head> 4 <meta ht