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 相关文章推荐
对JavaScript的eval()中使用函数的进一步讨论
Jul 26 Javascript
JavaScript中的运算符种类及其规则介绍
Sep 26 Javascript
PHP abstract与interface之间的区别
Nov 11 Javascript
JS中判断null、undefined与NaN的方法
Mar 24 Javascript
处理文本部分内容的TextRange对象应用实例
Jul 29 Javascript
JavaScript实现的简单幂函数实例
Apr 17 Javascript
jQuery超精致图片轮播幻灯片特效代码分享
Sep 10 Javascript
移动适配的几种方案(三种方案)
Nov 25 Javascript
详解ES6中的let命令
Apr 05 Javascript
vue轻量级框架无法获取到vue对象解决方法
May 12 Javascript
vue控制多行文字展开收起的实现示例
Oct 11 Javascript
Vue将props值实时传递 并可修改的操作
Aug 09 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
php中filter_input函数用法分析
2014/11/15 PHP
php 5.6版本中编写一个PHP扩展的简单示例
2015/01/20 PHP
简单谈谈PHP vs Node.js
2015/07/17 PHP
简单了解将WordPress中的工具栏移到底部的小技巧
2015/12/31 PHP
PHP Cookei记录用户历史浏览信息的代码
2016/02/03 PHP
laravel实现上传图片并在页面显示的例子
2019/10/14 PHP
laravel Task Scheduling(任务调度)在windows下的使用详解
2019/10/22 PHP
9个javascript语法高亮插件 推荐
2009/07/18 Javascript
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
2011/01/06 Javascript
JQuery1.6 使用方法三
2011/11/23 Javascript
初学Jquery插件制作 在SageCRM的查询屏幕隐藏部分行的功能
2011/12/26 Javascript
javaScript函数中执行C#代码中的函数方法总结
2013/08/07 Javascript
jQuery scrollFix滚动定位插件
2015/04/01 Javascript
JS实现选中当前菜单后高亮显示的导航条效果
2015/10/15 Javascript
喜大普奔!jQuery发布 3.0 最终版
2016/06/12 Javascript
详解Jquery 遍历数组之$().each方法与$.each()方法介绍
2017/01/09 Javascript
Vue常见面试题整理【值得收藏】
2018/09/20 Javascript
详解一个基于套接字实现长连接的express
2019/03/28 Javascript
layer 刷新某个页面的实现方法
2019/09/05 Javascript
python实现发送和获取手机短信验证码
2016/01/15 Python
CentOS安装pillow报错的解决方法
2016/01/27 Python
python 拷贝特定后缀名文件,并保留原始目录结构的实例
2018/04/27 Python
Python 中字符串拼接的多种方法
2018/07/30 Python
Python数据分析matplotlib设置多个子图的间距方法
2018/08/03 Python
django框架模板中定义变量(set variable in django template)的方法分析
2019/06/24 Python
在python里面运用多继承方法详解
2019/07/01 Python
Python爬虫爬取电影票房数据及图表展示操作示例
2020/03/27 Python
基于Python的Jenkins的二次开发操作
2020/05/12 Python
python 动态渲染 mysql 配置文件的示例
2020/11/20 Python
用HTML5 实现橡皮擦的涂抹效果的教程
2015/05/11 HTML / CSS
Beach Bunny Swimwear官网:设计师泳装和性感比基尼
2019/03/13 全球购物
慕尼黑山地运动、户外服装和体育用品专家:Sporthaus Schuster
2019/08/27 全球购物
村优秀党员事迹材料
2014/01/15 职场文书
承诺书的格式范文
2014/03/28 职场文书
安全生产月标语
2014/10/07 职场文书
Python还能这么玩之用Python修改了班花的开机密码
2021/06/04 Python