Hello,大家好!

小W复活啦!继续欢乐的给大家更博,输送新知识~~

不开玩笑啦!秒进正题~~~

上次更博,小W给大家介绍了Canvas画布的基础部分,以及实现了一个由7*10点阵图显示的倒计时的基本架构。

上次的效果如下图所示,仅仅只是一个时间的静态显示而已:

今天呢,小W想实现就是,让它开始倒计时!效果先给大家看一下:

Canvas画布用于图形的绘制、动画,都是通过脚本(JavaScript)实现的。

上次更博,countdown.js代码中,已经实现了时:分:秒的基本架构,先把上次的JS代码再次梳理一下,在这个基础上,小W再进行接下来的操作:

  1. // 全局变量 有助于后期数据的变动更改
  2. var WINDOW_WIDTH = 1024;
  3. var WINDOW_HEIGHT = 768; // 此处需要注意宽高的比例 适当缩小放大画布的时候,尽量同时缩小放大,避免出现圆形显示为椭圆形等不对称现象
  4. var MARGIN_LEFT = 30;
  5. var MARGIN_TOP = 60;
  6. var RADIUS = 8;
  7.  
  8. window.onload = function(){
  9.  
  10. var canvas = document.getElementById("canvas");
  11. var context = canvas.getContext("2d");
  12.  
  13. canvas.width = WINDOW_WIDTH;
  14. canvas.height = WINDOW_HEIGHT;
  15.  
  16. render( context );
  17. }
  18.  
  19. function render( cxt ){
  20.  
  21. var hours = 12;
  22. var minute = 36;
  23. var second = 59;
  24. // 小时 为了显示效果好看、设置居中,给每个数字设置margin
  25. renderDigit( MARGIN_LEFT , MARGIN_TOP , parseInt(hours/10) , cxt );
  26. // 每个字水平点阵个数为直径7,半径:7*2 = 14,14+1 = 15 (1间隔)
  27. renderDigit( MARGIN_LEFT + 15*(RADIUS+1) , MARGIN_TOP , parseInt(hours%10) , cxt );
  28.  
  29. // 冒号 (4*2+1)= 9 digit.js中 10代表 :
  30. renderDigit( MARGIN_LEFT+ 30*(RADIUS+1) , MARGIN_TOP , 10 , cxt );
  31. // 分钟
  32. renderDigit( MARGIN_LEFT+ 39*(RADIUS+1) , MARGIN_TOP , parseInt(minute/10) , cxt );
  33. renderDigit( MARGIN_LEFT+ 54*(RADIUS+1) , MARGIN_TOP , parseInt(minute%10) , cxt );
  34.  
  35. renderDigit( MARGIN_LEFT+ 69*(RADIUS+1) , MARGIN_TOP , 10 , cxt );
  36. // 秒
  37. renderDigit( MARGIN_LEFT+ 78*(RADIUS+1) , MARGIN_TOP , parseInt(second/10) , cxt );
  38. renderDigit( MARGIN_LEFT+ 93*(RADIUS+1) , MARGIN_TOP , parseInt(second%10) , cxt );
  39. }
  40.  
  41. function renderDigit(x , y , num , cxt){ // X轴坐标、Y轴坐标、将要显示的数字、canvas上下文语境
  1.   cxt.fillStyle = "#005588";
  2.  
  3.   for (var i = 0 ; i < digit[num].length ;i++) {
         for (var j = 0 ; j < digit[num][i].length ;j++){
      
          if(digit[num][i][j] == 1){ cxt.beginPath();
  4.  
  5.         // 圆心位置公式
            cxt.arc( x+j * 2 * (RADIUS+1) + (RADIUS+1) , y+i * 2 * (RADIUS+1) + (RADIUS+1) , RADIUS , 0 , 2*Math.PI ); cxt.closePath(); cxt.fill();
           }
         }
      }
    }

梳理完成之后我们可以进行下一步操作了,首先,我们需要设置一个截止时间,倒计时就是从现在开始到截止时间所剩余的时间:

  1. //限制: 小时二位数 不超过4天
  2. var endTime = new Date(2017,9,15,18,15,26); // 注意!!!:data中的参数第二个表示月份,是由0-11表示的。0 - 一月;11- 十二月

  这里需要注意,我们在之前调取小时hours的位数的时候,仅仅只是设置了两位数,因而现在我们的倒计时最多到99:99:99,也就是四天。如果有读者需要实现更长时间的倒计时,需要再做些许调整,为了效果美观整洁,我们这里只设置两位数。使用JS提供的data()方式设置截止时间。

在render函数中,如何获取当前时间距离截止时间剩余时间?

  JS的data对象给我们提供了一个getTime的方法:它返回了距离1970.1.1的00:00:00的毫秒数,用这个方法减去截止日期的getTime(),这个差值就表示中间我们需要倒计时的小时、分钟和秒数,但是由于时间是一秒一秒变动的,这个动画效果需要不断的与当前时间作比较,为此我们设计一个全局的变量,来表示现在倒计时需要多少秒?

  1. var curShowTimeSecond = 0; // 现在倒计时需要多少毫秒, —— > 秒

接下来,对 curShowTimeSecond 进行具体的计算:

  1. curShowTimeSecond = getCurShowTimeSecond(); // 封装一个函数
  1. // javascript Date 提供了 getTime 函数 以便于获取实时时间
  2. // getCurShowTimeSecond 函数 获取当前总共的毫秒数
  3. function getCurShowTimeSecond(){
  4. var curTime = new Date(); // 获取当前的时间是多少
  5. var ret = endTime.getTime() - curTime.getTime(); //ret 获取截止时间与当前时间相差的毫秒数
  6. ret = Math.round( ret/1000 ); // 将毫秒转换成秒
  7.  
  8. return ret>=0 ? ret : 0; // 判断 ret,倒计时结束,函数返回0.
  9. }

现在,剩余时间的秒数已经得到了,我们接下来需要设置小时、分钟、秒数的显示:

  1. var hours = parseInt( curShowTimeSecond/3600 ); // 剩余时间有多少个小时
  2. var minute = parseInt( (curShowTimeSecond - hours * 3600) / 60 ); // 减去小时,剩余时间的分钟数
  3. var second = curShowTimeSecond % 60; // 减去小时、分钟后,剩余时间还剩多少秒

到这里,在浏览器的刷新后,倒计时可以实现实时更新了。

然而我们想要实现的是让它自己更新、变化,实现倒计时,接下来我们需要引入一个实现动画的基础函数——定时器setInterval() 方法:

  1. // 动画效果
  2. setInterval(
  3. function(){
  4. render( context ); // 绘制当前的画面。
  5. update(); // 根据绘制画面所需要的数据结构,对数据结构进行调整。
  6. },
  7. 50 // 毫秒
  8. );

  其实,我们可以直接获取新的时间在render()里面进行绘制就可以了,但是这个最终的效果是想要实现,随着时间变化,产生彩色小球的物理变化的动画,因为为了铺垫后文,我们使用了一个update() 函数,如下图所示:

  1. // 时间更新函数
  2. function update(){
  3.  
  4. // 注意 render 里面是绘制curShowTimeSecond
  5. var nextShowTimeSecond = getCurShowTimeSecond(); // 下一次
  6.  
  7. // 下一次要显示的时间(时\分\秒分解)
  8. var nextHours = parseInt( nextShowTimeSecond/3600 );
  9. var nextMinute = parseInt( (nextShowTimeSecond - nextHours * 3600) / 60 );
  10. var nextSecond = nextShowTimeSecond % 60;
  11.  
  12. var curtHours = parseInt( curShowTimeSecond/3600 );
  13. var curtMinute = parseInt( (curShowTimeSecond - curtHours * 3600) / 60 );
  14. var curtSecond = curShowTimeSecond % 60;
  15.  
  16. if(nextSecond != curtSecond) // 下一次显示的秒数不等于当前显示的秒数了,替换为新的时间
  17. curShowTimeSecond = nextShowTimeSecond;
  18. }

为了避免当前新图像,与之前的图像叠加,我们在render()里面引入一个新的函数:

  1. // 为避免新一次的图像与之前的图像叠加。
  2. // clearRect(): 对一个矩形空间内的图像进行一次刷新操作。这里,对整个屏幕进行一次操作、刷新。
  3. cxt.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);

到这里我们今天的效果已经基本实现了。

后续学习后,还会继续更新,与大家分享...希望可以多多关注!

如果有任何问题,大家可以提出来,小W同大家一起解决,有何不妥的地方也请大神多多指教,这次的博文就到这了,谢谢大家!

附完整countdown.js代码

  1. var WINDOW_WIDTH = 1024;
  2. var WINDOW_HEIGHT = 768;
  3. var MARGIN_LEFT = 30;
  4. var MARGIN_TOP = 60;
  5. var RADIUS = 8;
  6.  
  7. //限制: 小时二位数 不超过4天
  8. var endTime = new Date(2017,9,15,18,15,26); // 注意!!!:data中的参数第二个表示月份,是由0-11表示的。0 - 一月;11- 十二月
  9. var curShowTimeSecond = 0; // 现在倒计时需要多少毫秒
  10.  
  11. window.onload = function(){
  12.  
  13. var canvas = document.getElementById("canvas");
  14. var context = canvas.getContext("2d");
  15.  
  16. canvas.width = WINDOW_WIDTH;
  17. canvas.height = WINDOW_HEIGHT;
  18.  
  19. curShowTimeSecond = getCurShowTimeSecond(); //curShowTimeSecond:当前总共的毫秒数
  20.  
  21. // 动画效果
  22. setInterval(
  23. function(){
  24. render( context );
  25. update();
  26. },
  27. 50 // 毫秒
  28. );
  29.  
  30. }
  31.  
  32. // javascript 的 Date 提供了 getTime 函数 以便于获取实时时间
  33. // getCurShowTimeSecond 函数 获取当前总共的毫秒数
  34. function getCurShowTimeSecond(){
  35. var curTime = new Date(); // 获取当前的时间是多少
  36. var ret = endTime.getTime() - curTime.getTime(); //ret 获取截止时间与当前时间相差的毫秒数
  37. ret = Math.round( ret/1000 ); // 将毫秒转换成秒
  38.  
  39. return ret>=0 ? ret : 0; // 判断 ret,倒计时结束,函数返回0.
  40. }
  41.  
  42. // 时间更新函数
  43. function update(){
  44.  
  45. var nextShowTimeSecond = getCurShowTimeSecond();
  46.  
  47. // 下一次要显示的时间(时分秒分解)
  48. var nextHours = parseInt( nextShowTimeSecond/3600 );
  49. var nextMinute = parseInt( (nextShowTimeSecond - nextHours * 3600) / 60 );
  50. var nextSecond = nextShowTimeSecond % 60;
  51.  
  52. var curtHours = parseInt( curShowTimeSecond/3600 ); // 一共需要多少个小时
  53. var curtMinute = parseInt( (curShowTimeSecond - curtHours * 3600) / 60 );
  54. var curtSecond = curShowTimeSecond % 60;
  55.  
  56. if(nextSecond != curtSecond)
  57. curShowTimeSecond = nextShowTimeSecond;
  58.  
  59. }
  60.  
  61. function render( cxt ){
  62.  
  63. // 为避免新一次的图像与之前的图像叠加。
  64. // clearRect(): 对一个矩形空间内的图像进行一次刷新操作。这里,对整个屏幕进行一次刷新。
  65. cxt.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
  66.  
  67. var hours = parseInt( curShowTimeSecond/3600 ); // 一共需要多少个小时
  68. var minute = parseInt( (curShowTimeSecond - hours * 3600) / 60 );
  69. var second = curShowTimeSecond % 60;
  70.  
  71. // 小时
  72. renderDigit( MARGIN_LEFT , MARGIN_TOP , parseInt(hours/10) , cxt );
  73. // 每个字水平位置直径7,7*2 = 14半径+1 = 15
  74. renderDigit( MARGIN_LEFT + 15*(RADIUS+1) , MARGIN_TOP , parseInt(hours%10) , cxt );
  75.  
  76. // 冒号 (4*2+1)= 9 digit.js中 10代表 :
  77. renderDigit( MARGIN_LEFT+ 30*(RADIUS+1) , MARGIN_TOP , 10 , cxt );
  78. // 分钟
  79. renderDigit( MARGIN_LEFT+ 39*(RADIUS+1) , MARGIN_TOP , parseInt(minute/10) , cxt );
  80. renderDigit( MARGIN_LEFT+ 54*(RADIUS+1) , MARGIN_TOP , parseInt(minute%10) , cxt );
  81.  
  82. // 冒号 (4*2+1)= 9 digit.js中 10代表 :
  83. renderDigit( MARGIN_LEFT+ 69*(RADIUS+1) , MARGIN_TOP , 10 , cxt );
  84. // 秒
  85. renderDigit( MARGIN_LEFT+ 78*(RADIUS+1) , MARGIN_TOP , parseInt(second/10) , cxt );
  86. renderDigit( MARGIN_LEFT+ 93*(RADIUS+1) , MARGIN_TOP , parseInt(second%10) , cxt );
  87. }
  88.  
  89. function renderDigit(x , y , num , cxt){
  90.  
  91. cxt.fillStyle = "#005588";
  92. for (var i = 0 ; i < digit[num].length ;i++) {
  93. for (var j = 0 ; j < digit[num][i].length ;j++){
  94.  
  95. if(digit[num][i][j] == 1){
  96.  
  97. cxt.beginPath();
  98. // 圆心位置公式
  99. cxt.arc( x+j * 2 * (RADIUS+1) + (RADIUS+1) , y+i * 2 * (RADIUS+1) + (RADIUS+1) , RADIUS , 0 , 2*Math.PI );
  100. cxt.closePath();
  101. cxt.fill();
  102. }
  103. }
  104. }
  105. }

更新——Canvas画布动画效果之实现倒计时的更多相关文章

  1. 使用Canvas实现动画效果 | DKlogs -- 设计 | 生活

    使用Canvas实现动画效果 | DKlogs -- 设计 | 生活 使用Canvas实现动画效果

  2. 用Canvas实现动画效果

    1.清除Canvas的内容 clearRect(x,y,width,height)函数用于清除图像中指定矩形区域的内容 <!doctype html> <html> <h ...

  3. canvas/CSS仪表盘效果

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

  4. 基于canvas实现物理运动效果与动画效果(一)

    一.为什么要写这篇文章 某年某月某时某种原因,我在慕课网上看到了一个大神实现了关于小球的抛物线运动的代码,心中很是欣喜,故而写这篇文章来向这位大神致敬,同时也为了弥补自己在运动效果和动画效果制作方面的 ...

  5. 7个惊艳的HTML5 Canvas动画效果及源码

    HTML5非常强大,尤其是现在大部分浏览器都支持HTML5和CSS3,用HTML5制作的动画也多了起来.另外,Canvas上绘制图形非常简单,本文就分享了一些强大的HTML5 Cnavas动画,一起来 ...

  6. Particles.js基于Canvas画布创建粒子原子颗粒效果

    文章目录 使用方法 自定义参数 相关链接 Particles.js是一款基于HTML5 Canvas画布的轻量级粒子动画插件,可以设置粒子的形状.旋转.分布.颜色等属性,还可以动态添加粒子,效果非常炫 ...

  7. HTML5 Canvas动画效果实现原理

    在线演示 使用HTML5画布可以帮助我们高速实现简单的动画效果.基本原理例如以下: 每隔一定时间绘制图形而且清除图形,用来模拟出一个动画过程,能够使用context.clearRect(0, 0, x ...

  8. 使用JavaScript和Canvas实现下雪动画效果

    该下雪动画效果使用了HTML5中Canvas画布实现,其中涉及了物理学中曲线运动的相关知识与运算. index.html <!DOCTYPE html> <html lang=&qu ...

  9. 神奇的canvas——点与线绘制的绚丽动画效果

    代码地址如下:http://www.demodashi.com/demo/11636.html 前言 之前在某网站上看到了一个canvas绘制的动画效果,虽然组成的元素很简单,只有点和线,但是视觉效果 ...

随机推荐

  1. setTimeout,setInterval你不知道的…

    javascript线程解释(setTimeout,setInterval你不知道的事) 标签: javascript引擎任务浏览器functionxmlhttprequest 2011-11-21 ...

  2. 团队作业8——Beta 阶段冲刺5th day

    一.当天站立式会议 二.每个人的工作 (1)昨天已完成的工作(具体在表格中) 支付功能测试 (2)今天计划完成的工作(具体如下) 完善订单功能 (3)工作中遇到的困难(在表格中) 成员 昨天已完成的工 ...

  3. win8下安装VC6出现兼容性问题的解决办法

    重装系统之后(win8的系统),发现VC6安装出现兼容性问题,花了一些时间解决,有出现的问题都差不多在下面链接的总结中,写的很详细: http://www.docin.com/p-1126120829 ...

  4. 201521123068《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 查看脑图->多态与接口 1.2 可选:使用常规方法总结其他上课内容. 2. 书面作业 1.代码阅读:Child压缩包内源 ...

  5. 201521123052《Java程序设计》第3周学习总结

    1. 本周学习总结 2. 书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...

  6. 201521123086《JAVA程序设计》第二周学习总结

    一.本章学习总结 学会在Java程序中使用函数,使程序层次更清晰 使用StringBuilder编写代码,减少内存空间的占用 使用BigDecimal精确计算浮点数 使用枚举类型编写函数,掌握返回值使 ...

  7. Java课程设计—学生成绩管理系统(201521123005 杨雪莹)

    一.团队课程设计博客链接 学生成绩管理系统 二.个人负责模块或任务说明 学生成绩录入 显示所有学生信息 显示各科平均成绩 显示学生成绩(按降序排序) 三.自己的代码提交记录截图 四.自己负责模块或任务 ...

  8. java从控制台接收一个数字

    //时间:2017/7/22//作者:江骆//功能:从控制台接收一个数import java.io.*;  //引入一个IO流的包public class helloworld1{    public ...

  9. python数据分析panda库

    panda内有两种数据结构,Series()和DataFrame() >>> a=pd.Series([1,2],index=['a','b']) >>> a a ...

  10. u盘分区装机版

    第一步:制作启动U盘前的软硬件准备 .准备一个最好大于2G的U盘,并先备份好里面的数据,防止接下来需要清空U盘的数据而出现丢失重要文件: 2.下载U盘启动盘制作工具6.1软件,直接放在桌面,方便接下来 ...