使用到的知识:
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,h2,h3,h4,h5,h6,h7,*{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);
此时的效果图:
下边画分针刻度线:
此时我们需要思考并要明白的几件事:
刻度线怎么画出来的?
画圆的起始点在哪?
应该在哪?
解决思考的问题:
先看一段代码与效果:
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();
效果图:
三、获取系统的时间(电脑时间)
Date()对象
Hours()方法/时
Minutes()方法/分
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();
}
有什么错误或写的不好的地方,还请不吝赐教,谢谢!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。