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 相关文章推荐
区分JS中的undefined,null,&quot;&quot;,0和false
Mar 08 Javascript
对字符串进行HTML编码和解码的JavaScript函数
Feb 01 Javascript
window.ActiveXObject使用说明
Nov 08 Javascript
JS 退出系统并跳转到登录界面的实现代码
Jun 29 Javascript
js定时器的使用(实例讲解)
Jan 06 Javascript
JS实现的另类手风琴效果网页内容切换代码
Sep 08 Javascript
Jquery日历插件制作简单日历
Oct 28 Javascript
跟我学习JScript的Bug与内存管理
Nov 18 Javascript
js当前页面登录注册框,固定div,底层阴影的实例代码
Oct 04 Javascript
Vue.js表单控件实践
Oct 27 Javascript
Angular中的ng-template及angular 使用ngTemplateOutlet 指令的方法
Aug 08 Javascript
解决Antd 里面的select 选择框联动触发的问题
Oct 24 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
多数据表共用一个页的新闻发布
2006/10/09 PHP
解析PayPal支付接口的PHP开发方式
2010/11/28 PHP
windows环境下php配置memcache的具体操作步骤
2013/06/09 PHP
PHP自动生成缩略图函数的源码示例
2019/03/18 PHP
php 使用mpdf实现指定字段配置字体样式的方法
2019/07/29 PHP
重构Javascript代码示例(重构前后对比)
2013/01/23 Javascript
window.location不跳转的问题解决方法
2014/04/17 Javascript
浅谈JavaScript字符集
2014/05/22 Javascript
js根据鼠标移动速度背景图片自动旋转的方法
2015/02/28 Javascript
javascript实现通过表格绘制颜色填充矩形的方法
2015/04/21 Javascript
jQuery实现伪分页的方法分享
2016/02/17 Javascript
javascript  删除select中的所有option的实例
2017/09/17 Javascript
Vue 中的compile操作方法
2018/02/26 Javascript
webstorm和.vue中es6语法报错的解决方法
2018/05/08 Javascript
对node.js中render和send的用法详解
2018/05/14 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
2018/05/21 jQuery
vue-router传递参数的几种方式实例详解
2018/11/13 Javascript
JQuery搜索框自动补全(模糊匹配)功能实现示例
2019/01/08 jQuery
vue操作动画的记录animate.css实例代码
2019/04/26 Javascript
[39:18]完美世界DOTA2联赛PWL S3 Forest vs LBZS 第二场 12.17
2020/12/19 DOTA
在python的WEB框架Flask中使用多个配置文件的解决方法
2014/04/18 Python
Python抽象类的新写法
2015/06/18 Python
Python cookbook(数据结构与算法)字典相关计算问题示例
2018/02/18 Python
Python学习笔记之Django创建第一个数据库模型的方法
2019/08/07 Python
PyTorch预训练的实现
2019/09/18 Python
django admin管理工具自定义时间区间筛选器DateRangeFilter介绍
2020/05/19 Python
python如何实现图片压缩
2020/09/11 Python
AmazeUI 输入框组的示例代码
2020/08/14 HTML / CSS
美国嘻哈首饰购物网站:Hip Hop Bling
2016/12/30 全球购物
链表面试题-一个链表的结点结构
2015/05/04 面试题
2014年廉洁自律承诺书
2014/05/26 职场文书
农业项目建议书
2014/08/25 职场文书
打架赔偿协议书范本
2014/10/26 职场文书
西双版纳导游词
2015/02/03 职场文书
经营目标责任书
2015/05/08 职场文书
利用python Pandas实现批量拆分Excel与合并Excel
2021/05/23 Python