周末学习canvas的一些基础功能,顺带写了一个基础的时钟。现在加工一下,做的更好看一点,先放上效果图:

    

  谈一些自己的理解:

    (1)、要绘制一个新的样式(不想被其他样式影响,或者影响到其他样式),那么一定记得先用beginPath(),beginPath()可以新建一个子路径,接下来的绘制,都是针对该子路径进行的。如果不适用该方法,那么默认和之前路径为同一路径设置,在接下来的绘制中,前面设置的路径会被重复绘制(打个比方,如果不用beginPath(),上面我绘制了一个长方形,边框宽度为1,下面我又绘制了一个长方形,边框宽度为5,那么上面的长方形会被重新绘制,且边框宽度也变为5)。相对的还有一个closePath()方法,如果前面设置的路径是开放的,该方法会自动用直线连接终点和起点。

    (2)、因为时、分、秒针都是通过循环并且旋转来做出移动效果,所以需要在每次旋转前,通过save()方法保存下当前状态,并在旋转后restore()恢复到之前状态,否则每次旋转都会在上一次旋转的基础上进行。

    (3)、仔细看的话可以发现秒针的尾端是一个弧线,canvas里有很多曲线的绘制方法,且大多与切线(切点)有关,具体可以搜索下,网上有很多详解文章了。

    (4)、lineTo()、arc()、arcTo()这些都仅仅是绘制路径,最后要通过fill()或者stroke()来完成绘制。

  下面给出完整代码,补上了注释:

  1. <!doctype html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  4. <style>
  5. </style>
  6. </head>
  7. <body>
  8. <canvas id="my_clock" width="1200" height="900">不支持canvas</canvas>
  9. <script>
  10. var myClock = document.getElementById('my_clock');
  11. var ctx = myClock.getContext('2d');
  12. var clockImg = new Image();
  13. clockImg.src = 'clock.png';
  14. ctx.translate(600, 400);
  15.  
  16. var startTime = new Date().getTime(),
  17. count = 0;
  18.  
  19. function clock() {
  20. ctx.clearRect(-600, -400, 1200, 900);
  21.  
  22. // 裁剪钟面图,只留下圆的钟面
  23. ctx.beginPath();
  24. ctx.arc(0, 0, 250, 0, 2 * Math.PI);
  25. ctx.clip();
  26.  
  27. // 钟面图有点歪,需要差不多顺时针旋转1/3度
  28. ctx.save()
  29. ctx.rotate(1 / 3 * 2 * Math.PI / 60);
  30. ctx.drawImage(clockImg, - 250, -250, 500, 500);
  31. ctx.restore();
  32.  
  33. // 这里注释的部分的是绘制的一个简单的钟面,如果不用图片可以打开下面的注释
  34. // ctx.beginPath();
  35. // ctx.arc(0, 0, 200, 0, 2 * Math.PI, false);
  36.  
  37. // ctx.moveTo(195, 0);
  38. // ctx.arc(0, 0, 195, 0, 2 * Math.PI, false);
  39. // ctx.stroke();
  40. // ctx.closePath();
  41.  
  42. // ctx.font = '16px Arial';
  43. // ctx.textAlign = 'center';
  44. // ctx.textBaseline = 'middle';
  45.  
  46. // ctx.fillText('12', 0, -180);
  47. // ctx.fillText('3', 180, 0);
  48. // ctx.fillText('6', 0, 180);
  49. // ctx.fillText('9', -180, 0);
  50.  
  51. var nowTime = new Date(),
  52. sec = nowTime.getSeconds(),
  53. min = nowTime.getMinutes() + sec / 60,
  54. hour12 = nowTime.getHours() >= 12 ? nowTime.getHours() - 12 : nowTime.getHours(),
  55. hour = hour12 + min / 60;
  56.  
  57. // 实时时间转换成角度,一圈是360度,也就是2PI,一圈有60小格,一小格就是(2 * Math.PI / 60)
  58. var angle = 2 * Math.PI / 60,
  59. secHandAngle = sec * angle,
  60. minHandAngle = min * angle,
  61. hourHandAngle = hour * 5 * angle;
  62.  
  63. // 秒针
  64. ctx.save();
  65. ctx.beginPath();
  66. ctx.rotate(secHandAngle)
  67. ctx.moveTo(-2, 10);
  68. ctx.lineTo(0, -240);
  69. ctx.lineTo(2, 10);
  70. ctx.moveTo(-2, 10);
  71. ctx.arcTo(0, -240, 2, 10, 2);
  72. ctx.stroke();
  73. ctx.restore();
  74.  
  75. // 分针
  76. ctx.save();
  77. ctx.beginPath();
  78. ctx.rotate(minHandAngle)
  79. ctx.moveTo(0, 0);
  80. ctx.lineTo(0, -170);
  81. ctx.lineWidth = 2;
  82. ctx.stroke();
  83. ctx.restore();
  84.  
  85. // 时针
  86. ctx.save();
  87. ctx.beginPath();
  88. ctx.rotate(hourHandAngle)
  89. ctx.moveTo(-5, 0);
  90. ctx.lineTo(0, -120);
  91. ctx.lineTo(5, 0);
  92. ctx.strokeStyle = '#fff'
  93. ctx.fillStyle = 'rgba(0, 0, 0, .3)';
  94. ctx.lineWidth = 1;
  95. ctx.stroke();
  96. ctx.fill();
  97. ctx.restore();
  98.  
  99. // 减少setTimeout误差
  100. count++;
  101. var diff = new Date().getTime() - (startTime + count * 1000);
  102. var nextStart = (1000 - diff) < 0 ? 0 : 1000 - diff;
  103. setTimeout(clock, nextStart);
  104. }
  105.  
  106. // 占用线程
  107. // setInterval(function(){
  108. // var j = 0;
  109. // while (j++ < 100000000);
  110. // }, 0);
  111. // setInterval(function(){
  112. // var j = 0;
  113. // while (j++ < 100000000);
  114. // }, 0);
  115. // setInterval(function(){
  116. // var j = 0;
  117. // while (j++ < 100000000);
  118. // }, 0);
  119.  
  120. setTimeout(clock, 1000);
  121. // setInterval(clock, 1000)
  122.  
  123. </script>
  124. </body>
  125. </html>

  然后给上我用的钟面图:

    

使用canvas绘制一个时钟的更多相关文章

  1. 用canvas绘制一个时钟

    实现一个时钟的绘制和时间的显示 一,首先是页面的搭建html部分以及一点点的css代码,因为css这块用的比较少,所以就没有单独出来: <!DOCTYPE html> <html l ...

  2. 用canvas绘制一个简易时钟

    在见识了html5中canvas的强大,笔者准备制作一个简易时钟. 下面就是成果啦,制作之前我们先分析一下,绘制一个时钟需要做哪些准备. 一 . 1.首先这个时钟分为表盘,指针(时针,分针,秒针)和数 ...

  3. 深夜,用canvas画一个时钟

    深夜,用canvas画一个时钟 查看demo 这几天准备阿里巴巴的笔试,可以说已经是心力交瘁,自从阿里和蘑菇街的内推被刷掉之后,开始越来越怀疑起自己的能力来,虽然这点打击应该是微不足道的.毕竟校招在刚 ...

  4. 通过H5的新标签canvas做出一个时钟的全过程,希望对初学者有帮助

    最近学习了H5中的一个新标签canvas并且用它做出了一个时钟,最下面是成品图像,还不错吧,这只是我学习中的一个小demo,做得有点粗糙,但终究是做出来了,以后再写自己的网页主页再做一个好看点放上去. ...

  5. 用HTML5的canvas做一个时钟

    对于H5来说,canvas可以说是它最有特色的一个地方了,有了它之后我们可以随意的在网页上画各种各样的图形,做一些小游戏啊什么的.canvas这个标签的用法,在网上也有特别多的教程了,这里就不作介绍了 ...

  6. HTML5 在canvas绘制一个矩形

    笔者:本笃庆军 原文地址:http://blog.csdn.net/qingdujun/article/details/32930501 一.绘制矩形 canvas使用原点(0,0)在左上角的坐标系统 ...

  7. Canvas绘制一个大鱼喂小鱼的游戏

    Canvas是HTML5中的一部分,强大的API足以让我们绘制我们任意想绘制的东西.利用Canvas的基础学习以及JavaScript面向对象的思想绘制一个小游戏,下面是源码地址https://git ...

  8. canvas绘制表盘时钟

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  9. Canvas 绘制一个像素风电子时钟

    想法是在 Canvas 上绘制由小方块组成的数字. 第一步是实现绘制小方块的方法,先画出一个边长为 5 的 10x10 个方块,使用两个 for 循环很简单就能完成. for (let i = 0; ...

随机推荐

  1. 定义类型uint8_t,uint32_t

    定义的类型uint8_t,uint32_t能更明显的显示所占字节数.uint8_t表示占1个字节(1 字节=8 bit), uint32_t表示占4个字节((4 字节=32 bit). #includ ...

  2. python 装饰器

    #!/usr/bin/env python3 #-*-encoding:utf-8-*- def w3(*args, **kwargs): ') def w1(): def ww1(func): de ...

  3. 调用图片按钮的img图片

    今天是我学前端的第12天.早上起床后活动筋骨时看了<JS的基本属性操作>,作业是模拟手机发送短信.文字都能传输到<div>上,就是图片不知道怎么传.折腾了好久才弄清楚,多亏了某 ...

  4. 简单的SQL语句

    说明:SQL语句大小写都可以,执行一句时,后面可不加分号,如果同时执行两句,就必须加分号,不然会报错. --+空格  是SQL的注释 表格名为users,里面有name和age属性 一.增 inser ...

  5. Java_太阳系_行星模型_小游戏练习_详细注释

    //实现MyFrame--实现绘制窗口,和实现重写 重画窗口线程类 package cn.xiaocangtian.Test; import java.awt.Frame; import java.a ...

  6. ASP.NET知识总结(9.使用Cookies实现购物车)

    ListInfo.aspx向购物车的添加商品的方法 private void GouWu(string name, double price, string id) { //往购物车中添加商品 Htt ...

  7. AngularJS 相关小问题解决方案合集

    1  解决 Select选择框遍历时,出现一个空白选项: <select style="width: 20%;margin-left: 5px;height: 31px;" ...

  8. sqlserver 中数据导入到mysql中的方法以及注意事项

    数据导入从sql server 到mysql (将数据以文本格式从sqlserver中导出,注意编码格式,再将文本文件导入mysql中): 1.若从slqserver中导出的表中不包含中文采用: bc ...

  9. Centos 下编译安装Redis

    安装环境说明: 操作系统:Centos 6.5 -64bit 安装路径:/usr/local/redis 开始编译redis tar -zxvf redis-2.8.19.tar.gz cd redi ...

  10. java的布尔运算符和位运算符

    1.布尔运算符 &&  逻辑与: ||   逻辑或: !=  不等于: 三元操作符:?: :表达式为  condition?expression1:expression2(当条件为真时 ...