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表单验证插件formValidator(改进版)
Feb 03 Javascript
Jquery实现简单的动画效果代码
Mar 18 Javascript
animate动画示例(泪奔的小孩)及stop和delay的使用
May 06 Javascript
JS简单的轮播的图片滚动实例
Jun 17 Javascript
浅析jQuery1.8的几个小变化
Dec 10 Javascript
解析javascript中鼠标滚轮事件
May 26 Javascript
基于jQuery实现左右图片轮播(原理通用)
Dec 24 Javascript
jQuery 表单序列化实例代码
Jun 11 jQuery
利用js编写网页进度条效果
Oct 08 Javascript
利用nvm管理多个版本的node.js与npm详解
Nov 02 Javascript
详解Vue 全局变量,局部变量
Apr 17 Javascript
jquery.tagsinput.js实现记录checkbox勾选的顺序
Sep 21 jQuery
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
Laravel学习教程之路由模块
2017/08/18 PHP
PHP生成加减算法方式的验证码实例
2018/03/12 PHP
Ubuntu彻底删除PHP7.0的方法
2018/07/27 PHP
range 标准化之获取
2011/08/28 Javascript
javascript中基本类型和引用类型的区别分析
2015/05/12 Javascript
jquery对象和DOM对象的任意相互转换
2016/02/21 Javascript
浅谈jQuery 选择器和dom操作
2016/06/07 Javascript
js实现表单及时验证功能 用户信息立即验证
2016/09/13 Javascript
轻松实现jQuery添加删除按钮Click事件
2017/03/13 Javascript
Javascript实现登录记住用户名和密码功能
2017/03/22 Javascript
JS/jquery实现一个网页内同时调用多个倒计时的方法
2017/04/27 jQuery
彻底搞懂JavaScript中的apply和call方法(必看)
2017/09/18 Javascript
vuejs 动态添加input框的实例讲解
2018/08/24 Javascript
node 解析图片二维码的内容代码实例
2019/09/11 Javascript
node.JS的crypto加密模块使用方法详解(MD5,AES,Hmac,Diffie-Hellman加密)
2020/02/06 Javascript
如何基于javascript实现贪吃蛇游戏
2020/02/09 Javascript
使用Vue 自定义文件选择器组件的实例代码
2020/03/04 Javascript
jQuery中event.target和this的区别详解
2020/08/13 jQuery
浅谈Python中列表生成式和生成器的区别
2015/08/03 Python
Python中定时任务框架APScheduler的快速入门指南
2017/07/06 Python
对python3 urllib包与http包的使用详解
2018/05/10 Python
python Pexpect 实现输密码 scp 拷贝的方法
2019/01/03 Python
python循环定时中断执行某一段程序的实例
2019/06/29 Python
解决Keras 中加入lambda层无法正常载入模型问题
2020/06/16 Python
Python Switch Case三种实现方法代码实例
2020/06/18 Python
python不同版本的_new_不同点总结
2020/12/09 Python
美国生日蛋糕店:Bake Me A Wish!
2017/02/08 全球购物
SNIDEL官网:日本VIVI杂志人气少女第一品牌
2020/03/12 全球购物
应用服务器有那些
2012/01/19 面试题
计算机大学生的自我评价
2013/10/15 职场文书
合作经营协议书
2014/04/17 职场文书
婚纱摄影师求职信范文
2014/04/17 职场文书
物流管理专业自荐信
2014/06/23 职场文书
2015年中学总务处工作总结
2015/07/22 职场文书
2016年国庆节67周年活动总结
2016/04/01 职场文书