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返回上一页并刷新代码整理
Dec 21 Javascript
innerHTML在IE中报错解决方案
Dec 15 Javascript
javascript模拟评分控件实现方法
May 13 Javascript
javaScript中slice函数用法实例分析
Jun 08 Javascript
javascript获取wx.config内部字段解决微信分享
Mar 09 Javascript
原生js实现tab选项卡切换
Mar 23 Javascript
canvas学习之API整理笔记(一)
Dec 29 Javascript
vue修改对象的属性值后页面不重新渲染的实例
Aug 09 Javascript
angularJs中ng-model-options设置数据同步的方法
Sep 30 Javascript
JavaScript数据结构与算法之二叉树添加/删除节点操作示例
Mar 01 Javascript
微信小程序 Storage更新详解
Jul 16 Javascript
JavaScript组合继承详解
Nov 07 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 管理系统程序中的后门
2009/08/05 PHP
php cli模式学习(PHP命令行模式)
2013/06/03 PHP
PHP array_multisort() 函数的深入解析
2013/06/20 PHP
ThinkPHP的I方法使用详解
2014/06/18 PHP
destoon安装出现Internal Server Error的解决方法
2014/06/21 PHP
php上传图片之时间戳命名(保存路径)
2014/08/15 PHP
php自定义截取中文字符串-utf8版
2017/02/27 PHP
各种效果的jquery ui(接口)介绍
2008/09/17 Javascript
JavaScript中如何通过arguments对象实现对象的重载
2014/05/12 Javascript
JavaScript截断字符串的方法
2015/07/15 Javascript
jQuery progressbar通过Ajax请求实现后台进度实时功能
2016/10/11 Javascript
JavaScript下拉菜单功能实例代码
2017/03/01 Javascript
axios post提交formdata的实例
2018/03/16 Javascript
100行代码实现一个vue分页组功能
2018/11/06 Javascript
手挽手带你学React之React-router4.x的使用
2019/02/14 Javascript
实用的Vue开发技巧
2019/05/30 Javascript
微信小程序页面滚动到指定位置代码实例
2019/09/07 Javascript
使用Python对SQLite数据库操作
2017/04/06 Python
实例讲解python中的序列化知识点
2018/10/08 Python
Python简单过滤字母和数字的方法小结
2019/01/09 Python
django实现支付宝支付实例讲解
2019/10/17 Python
Python 日志logging模块用法简单示例
2019/10/18 Python
Python 词典(Dict) 加载与保存示例
2019/12/06 Python
Python3.7在anaconda里面使用IDLE编译器的步骤详解
2020/04/29 Python
Python无损压缩图片的示例代码
2020/08/06 Python
CSS3弹性伸缩布局之box布局
2016/07/12 HTML / CSS
Marriott国际:万豪国际酒店查询预订
2017/09/25 全球购物
日本著名化妆品零售网站:Cosme Land
2019/03/01 全球购物
《桥》教学反思
2014/04/09 职场文书
历史学专业求职信
2014/06/19 职场文书
2014年企业员工工作总结
2014/12/09 职场文书
2015迎新晚会开场白
2015/05/29 职场文书
MySQL 使用自定义变量进行查询优化
2021/05/14 MySQL
idea编译器vue缩进报错问题场景分析
2021/07/04 Vue.js
微软Win11什么功能最惊艳? Windows11新功能特性汇总
2021/11/21 数码科技
ssh服务器拒绝了密码 请再试一次已解决(亲测有效)
2022/08/14 Servers