JavaScript html5 canvas绘制时钟效果(二)


Posted in Javascript onMarch 27, 2016

 对于H5来说,canvas可以说是它最有特色的一个地方了,有了它之后我们可以随意的在网页上画各种各样的图形,做一些小游戏啊什么的。canvas这个标签的用法,在网上也有特别多的教程了,这里就不作介绍了。今天我们就用canvas来做一个小小的时钟。完整的代码在这里https://github.com/wwervin72/HTML5-Clock。

那么首先在这个页面里面我使用了两个canvas,一个用来绘制静态的时钟表盘和刻度,另一个用来绘制时钟的三个指针,然后用定位让他们重合到一起。然后这里没什么好说的,下面附上代码。

<canvas id="plate">
 画表盘
</canvas>
<canvas id="needles">
 画时针
</canvas>
var plate=document.getElementById('plate');
var needles=document.getElementById('needles');
needles.setAttribute('style','position:absolute;top:8px;left:8px;'); //这里因为chrome里面,body的magin值为8px,所以我这里就没设为0了。
var cntP=plate.getContext('2d');
var cntH=needles.getContext('2d');
plate.width=800;
plate.height=500;
needles.width=800;
needles.height=500;

到了这里准备工作就做完了,下面就准备绘制时钟了。我先定义了一个绘制时钟表盘的构造函数。

function drawclock(cnt,radius,platelen,linewidth,numLen,NUMLEN){
  this.cnt=cnt;
  this.radius=radius;
  this.platelen=platelen;
  this.linewidth=linewidth;
  this.numLen=numLen;
  this.NUMLEN=NUMLEN;
  this.getCalibCoor=function(i){ 
  //获得表盘刻度两端的坐标
  var X=200+this.radius*Math.sin(6*i*Math.PI/180);
  var Y=200-this.radius*Math.cos(6*i*Math.PI/180);
  var x=200+(this.radius-this.platelen)*Math.sin(6*i*Math.PI/180);
  var y=200-(this.radius-this.platelen)*Math.cos(6*i*Math.PI/180);

  // 获得分钟数字的坐标
  var numx=200+(this.radius-this.platelen-this.numLen)*Math.sin(6*i*Math.PI/180);
  var numy=200-(this.radius-this.platelen-this.numLen)*Math.cos(6*i*Math.PI/180);
  //获得小时数字的坐标
  var numX=200+(this.radius-this.platelen-this.NUMLEN)*Math.sin(6*i*Math.PI/180); 
  var numY=200-(this.radius-this.platelen-this.NUMLEN)*Math.cos(6*i*Math.PI/180);
  return {X:X,Y:Y,x:x,y:y,numx:numx,numy:numy,numX:numX,numY:numY};
  };
  this.drawCalibration=function(){ //画刻度
  for(var i=0,coorObj;i<60;i++){
   coorObj=this.getCalibCoor(i);
   this.cnt.beginPath();
   this.cnt.moveTo(coorObj.X,coorObj.Y);
   this.cnt.lineTo(coorObj.x,coorObj.y);
   this.cnt.closePath();

   this.cnt.lineWidth=this.linewidth;
   this.cnt.strokeStyle='#ddd';
   i%5==0&&(this.cnt.strokeStyle='#aaa')
   &&(this.cnt.lineWidth=this.linewidth*2);
   i%15==0&&(this.cnt.strokeStyle='#999')
   &&(this.cnt.lineWidth=this.linewidth*3);
   this.cnt.stroke();

   this.cnt.font='10px Arial';
   this.cnt.fillStyle='rgba(0,0,0,.2)';
   this.cnt.fillText(i,coorObj.numx-7,coorObj.numy+3);
   i%5==0&&(this.cnt.fillStyle='rgba(0,0,0,.5)')
   &&(this.cnt.font='18px Arial')
   &&(this.cnt.fillText(i/5,coorObj.numX-5,coorObj.numY+5));
  }
  };
 }


var clock=new drawclock(cntP,200,5,1,10,25); //实例化一个表盘对象



clock.drawCalibration();

这里最重要的部分就应该是获得刻度和数字绘制的坐标了。我把绘制刻度的起始点放在了表盘的边缘上,然后从表盘的半径上减去刻度的长度,就可以得到刻度终点的位置,然后利用角度和三角函数得到两个点的坐标。最后就可以绘制出表盘的刻度了。下面绘制出表盘上的数字也是一样的方法。我这里吧表盘的中心放在了(200,200)这里位置。到了这里我们就已经绘制好了一个静态的时钟表盘。

下面我又定义了一个绘制时钟指针的构造函数。

function clockNeedle(cnt,R,lineWidth,strokeStyle,lineCap,obj){
  this.R=R;
  this.cnt=cnt;
  this.lineWidth=lineWidth;
  this.strokeStyle=strokeStyle;
  this.lineCap=lineCap;
  this.obj=obj;
  this.getNeedleCoor=function(i){
  var X=200+this.R*0.8*Math.sin(i); //起点的坐标
  var Y=200-this.R*0.8*Math.cos(i);

  var x=200-20*Math.sin(i); //终点的坐标
  var y=200+20*Math.cos(i);
  return {X:X,Y:Y,x:x,y:y};
  };
  this.drawNeedle=function(){
  var d=new Date().getTime();
  var angle;
  switch(this.obj){
   case 0:
   angle=(d/3600000%24+8)/12*360*Math.PI/180;
   break;
   case 1:
   angle=d/60000%60/60*360*Math.PI/180;
   break;
   case 2:
   angle=d/1000%60/60*360*Math.PI/180;
   break;
  }
  var coorobj=this.getNeedleCoor(angle);
  this.cnt.beginPath();
  this.cnt.moveTo(coorobj.x,coorobj.y);
  this.cnt.lineTo(coorobj.X,coorobj.Y);
  // this.cnt.closePath();

  this.cnt.lineWidth=this.lineWidth;
  this.cnt.strokeStyle=this.strokeStyle;
  this.cnt.lineCap=this.lineCap;
  this.cnt.stroke();
  }
 }

这里有两个地方需要说一下:1、在我们获得当前时间的的毫秒数,然后转换为小时的时候,对24取模计算出当天的小时数的时候,这里需要加上8。2、如果想要使用lineCap这个属性吗,那么上面在设置路径的时候,不要用closePath()。

到了这里我们还需要一个来绘制指针的方法,并且让指针看起来能够转动:

function draw(){
  cntH.clearRect(0,0,needles.width,needles.height);
  var mzneedle=new clockNeedle(cntH,200,1,'rgba(0,0,0,.5)','round',2);
  //最后一个参数0代表画时针,1画分针,2画秒针
  var fzneedle=new clockNeedle(cntH,80,3,'rgba(0,0,0,.4)','round',0);
  var szneedle=new clockNeedle(cntH,140,2,'rgba(0,0,0,.3)','round',1);
  mzneedle.drawNeedle();
  fzneedle.drawNeedle();
  szneedle.drawNeedle();
  cntH.arc(200,200,5,0,2*Math.PI);
  cntH.fillStyle='rgba(0,0,0,.5)';
  cntH.fill();
 }
 setInterval(draw,1);

下面附上该时钟的图片:

JavaScript html5 canvas绘制时钟效果(二)

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
jQuery 表单验证扩展(四)
Oct 20 Javascript
jQuery实现级联菜单效果(仿淘宝首页菜单动画)
Apr 10 Javascript
jQuery通过点击行来删除HTML表格行的实现示例
Sep 10 Javascript
JavaScript jquery及AJAX小结
Jan 24 Javascript
谈谈VUE种methods watch和compute的区别和联系
Aug 01 Javascript
使用classList来实现两个按钮样式的切换方法
Jan 24 Javascript
vue内置组件transition简单原理图文详解(小结)
Jul 12 Javascript
Vue中Quill富文本编辑器的使用教程
Sep 21 Javascript
JavaScript数组去重的方法总结【12种方法,号称史上最全】
Feb 28 Javascript
7个好用的JavaScript技巧分享(译)
May 07 Javascript
JavaScript中var的重要性实例分析
Jul 09 Javascript
node.js中fs文件系统模块的使用方法实例详解
Feb 13 Javascript
Bootstrap每天必学之级联下拉菜单
Mar 27 #Javascript
详解javascript跨浏览器事件处理程序
Mar 27 #Javascript
js事件处理程序跨浏览器解决方案
Mar 27 #Javascript
基于javascript实现九九乘法表
Mar 27 #Javascript
深入浅析JavaScript中的作用域和上下文
Mar 26 #Javascript
JS中改变this指向的方法(call和apply、bind)
Mar 26 #Javascript
浏览器复制插件zeroclipboard使用指南
Mar 26 #Javascript
You might like
《忧国的莫里亚蒂》先导宣传图与STAFF公开
2020/03/04 日漫
Zend引擎的发展 [15]
2006/10/09 PHP
php addslashes和mysql_real_escape_string
2010/01/24 PHP
php unicode编码和字符串互转的方法
2020/08/12 PHP
jQuery中与toggleClass等价的程序段 以及未来学习的方向
2010/03/18 Javascript
点弹代码 点击页面任何位置都可以弹出页面效果代码
2012/09/17 Javascript
javascript数组的使用
2013/03/28 Javascript
深入理解Javascript里的依赖注入
2014/03/19 Javascript
基于HTML+CSS,jQuery编写的简易计算器后续(添加了键盘监听)
2016/01/05 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
2016/08/05 Javascript
JS实现获取当前URL和来源URL的方法
2016/08/24 Javascript
原生JS实现匀速图片轮播动画
2016/10/18 Javascript
Bootstrap源码解读网格系统(3)
2016/12/22 Javascript
Angular.js中控制器之间的传值详解
2017/04/24 Javascript
Vue+SpringBoot开发V部落博客管理平台
2017/12/27 Javascript
Node.Js中实现端口重用原理详解
2018/05/03 Javascript
基于Vue 2.0 监听文本框内容变化及ref的使用说明介绍
2018/08/24 Javascript
解决Vue 项目打包后favicon无法正常显示的问题
2018/09/01 Javascript
微信小程序网络请求实现过程解析
2019/11/06 Javascript
VueX模块的具体使用(小白教程)
2020/06/05 Javascript
vue移动端的左右滑动事件详解
2020/06/17 Javascript
koa2 数据api中间件设计模型的实现方法
2020/07/13 Javascript
[01:18:45]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第三场2月1日
2021/03/11 DOTA
编写Python CGI脚本的教程
2015/06/29 Python
Python应用03 使用PyQT制作视频播放器实例
2016/12/07 Python
django定期执行任务(实例讲解)
2017/11/03 Python
python控制windows剪贴板,向剪贴板中写入图片的实例
2018/05/31 Python
Pycharm plot独立窗口显示的操作
2020/12/11 Python
JustFab加拿大:女鞋、靴子、手袋和服装在线
2018/05/18 全球购物
FLOS美国官网:意大利高级照明工艺的传奇
2018/08/07 全球购物
数控技术专业毕业自荐书范文
2014/02/05 职场文书
离婚起诉书范文2015
2015/05/19 职场文书
运动会班级前导词
2015/07/20 职场文书
反邪教教育心得体会
2016/01/15 职场文书
python中pandas对多列进行分组统计的实现
2021/06/18 Python
mysql优化之query_cache_limit参数说明
2021/07/01 MySQL