HTML

html很简单,引入两个文件

digit.js:存放每个数字的点阵数据
countdown.js:主要逻辑

<!DOCTYPE html>
<html lang="en">
<head>![这里写图片描述](https://img-blog.csdn.net/20161101175756119)<meta charset="UTF-8"><title>绚丽的倒计时效果</title>
</head>
<body style="height:100%;position:absolute;"><canvas id='canvas' style="height:100%;">当前浏览器不支持canvas,请更换浏览器后重试</canvas><script type="text/javascript" src='digit.js'></script><script type="text/javascript" src='countdown6.js'></script>
</body>
</html>

点阵数据

我们可以看到每个数据的组成是用小圆点规划的,我们可以从下图出看出

可以看出,每个数字都是通过这样的10*7的点阵数据来实现的,那么我们的表示是这一个点存在就写为1,不存在就写为0,可以看digit.js的源码

/*** 存放二位的点阵模型*/
digit =[[[0,0,1,1,1,0,0],[0,1,1,0,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,0,1,1,0],[0,0,1,1,1,0,0]],//0[[0,0,0,1,1,0,0],[0,1,1,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[1,1,1,1,1,1,1]],//1[[0,1,1,1,1,1,0],[1,1,0,0,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,1,1,0],[0,0,0,1,1,0,0],[0,0,1,1,0,0,0],[0,1,1,0,0,0,0],[1,1,0,0,0,0,0],[1,1,0,0,0,1,1],[1,1,1,1,1,1,1]],//2[[1,1,1,1,1,1,1],[0,0,0,0,0,1,1],[0,0,0,0,1,1,0],[0,0,0,1,1,0,0],[0,0,1,1,1,0,0],[0,0,0,0,1,1,0],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0]],//3[[0,0,0,0,1,1,0],[0,0,0,1,1,1,0],[0,0,1,1,1,1,0],[0,1,1,0,1,1,0],[1,1,0,0,1,1,0],[1,1,1,1,1,1,1],[0,0,0,0,1,1,0],[0,0,0,0,1,1,0],[0,0,0,0,1,1,0],[0,0,0,1,1,1,1]],//4[[1,1,1,1,1,1,1],[1,1,0,0,0,0,0],[1,1,0,0,0,0,0],[1,1,1,1,1,1,0],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0]],//5[[0,0,0,0,1,1,0],[0,0,1,1,0,0,0],[0,1,1,0,0,0,0],[1,1,0,0,0,0,0],[1,1,0,1,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0]],//6[[1,1,1,1,1,1,1],[1,1,0,0,0,1,1],[0,0,0,0,1,1,0],[0,0,0,0,1,1,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,1,1,0,0,0],[0,0,1,1,0,0,0],[0,0,1,1,0,0,0],[0,0,1,1,0,0,0]],//7[[0,1,1,1,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0]],//8[[0,1,1,1,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,1,1,0],[0,0,0,1,1,0,0],[0,1,1,0,0,0,0]],//9[[0,0,0,0],[0,0,0,0],[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0],[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]]//:];

实现逻辑

/*** 第六步:屏幕自适应** 1.WIDDOW_WIDTH,WIDTH_HEIGHT:获取屏幕的高度和宽度,这点要把body的height设置为100%才可以* 2.MARGIN_LEFT:希望数字部分占整个屏幕的4/5,那么其余部分就占屏幕的1/5,数字左侧的一边就占屏幕的1/10* 3.RADIUS*//*** 主逻辑的处理*/
var WIDDOW_WIDTH = 1024;
var WIDTH_HEIGHT = 910;
var RADIUS = 8;
var MARGIN_TOP = 60;//每一个数字距离画布的上边距的距离
var MARGIN_LEFT = 30;//第一个数字距离画布的左边距的距离
//声明结束时间
//这里定义的小时只有两位数,所以最多显示4天的时间,如果更长的话可以扩充为3位数或者4位数
// var endTime = new Date(2016,10,4,23,59,59);
var endTime = new Date();
endTime.setTime(endTime.getTime() + 3600*1000);//表示结束时间时当前时间加上一个小时
//声明当前时间距离结束时间的秒数
var curShowEndtimeSeconds = 0;//声明一个存放小球的数组
var balls = [];
//小球颜色数组
var colors = ['#e83355','#e95cd0','#e133ec','#a033ec','#7d33ec','#3c33ec','#336cec','#33ecdd','#33ec70','#ec6733'];window.onload = function(){WIDDOW_WIDTH = document.body.clientWidth;WIDTH_HEIGHT = document.body.clientHeight;MARGIN_LEFT = Math.round(WIDDOW_WIDTH / 10);/*** WIDDOW_WIDTH * 4 / 5:表示整个时钟区域占屏幕的4/5* WIDDOW_WIDTH * 4 / 5 / 108:之前计算出来的最后一个数字的开始绘制距离为MARGIN_LEFT + 93 * (RADIUS+1),*                              而一个数字占用的是15 * (RADIUS + 1),则到最后一列的小球距离就是MARGIN_LEFT + 108 * (RADIUS+1)*                              这里就需要除以108,而之前是给每一个小球加了个1,这里需要减去1*/RADIUS = Math.round(WIDDOW_WIDTH * 4 / 5 / 108) - 1;MARGIN_TOP = WIDTH_HEIGHT / 7;var canvas = document.getElementById('canvas');canvas.width = WIDDOW_WIDTH;canvas.height = WIDTH_HEIGHT;var context = canvas.getContext('2d');curShowEndtimeSeconds = getCurShowEndTimeSeconds();setInterval(function(){render(context);update();},50);
}
/*** 获取当前时间到结束时间的秒数*/
function getCurShowEndTimeSeconds(){var curTime = new Date();//getTime()获取当前时间到1970年的毫秒数var ret = endTime.getTime() - curTime.getTime();ret = Math.round(ret / 1000);//求整return ret >= 0 ? ret:0;
}
/*** 更新时间* * 1.在下一次显示的时间和当前显示的时间做比较,如果不相等时,就需要改变** 2.在每一次更新时间时,需要判断小时,分钟,秒每一位上面的数字是否改变,如果改变,就要进行叠加彩色小球的操作*/
function update(){var nextShowTimeSeconds = getCurShowEndTimeSeconds();var nextHours = parseInt(nextShowTimeSeconds / 3600),nextMinutes = parseInt((nextShowTimeSeconds - nextHours * 3600) / 60),nextSeconds = nextShowTimeSeconds % 60;var curHours = parseInt(curShowEndtimeSeconds / 3600),curMinutes = parseInt((curShowEndtimeSeconds - curHours * 3600) / 60),curSeconds = curShowEndtimeSeconds % 60;if(nextSeconds != curSeconds){if(parseInt(nextHours / 10) != parseInt(curHours / 10)){//小时的十位数变化addBalls(MARGIN_LEFT,MARGIN_TOP,parseInt(nextHours/10));}if(nextHours % 10 != curHours % 10){ //小时的个位数变化addBalls(MARGIN_LEFT + 15 *(RADIUS + 1),MARGIN_TOP,nextHours % 10);}if(parseInt(nextMinutes / 10) != parseInt(curMinutes / 10)){addBalls(MARGIN_LEFT + 39*(RADIUS + 1),MARGIN_TOP,parseInt(nextMinutes/10));}if(nextMinutes % 10 != curMinutes % 10){ addBalls(MARGIN_LEFT + 54 *(RADIUS + 1),MARGIN_TOP,nextMinutes % 10);}if(parseInt(nextSeconds / 10) != parseInt(curSeconds / 10)){addBalls(MARGIN_LEFT + 78*(RADIUS + 1),MARGIN_TOP,parseInt(nextSeconds/10));}if(nextSeconds % 10 != curSeconds % 10){addBalls(MARGIN_LEFT + 93 *(RADIUS + 1),MARGIN_TOP,nextSeconds%10);}curShowEndtimeSeconds = nextShowTimeSeconds;}updateBalls();console.log(balls.length);
}
/*** 小球运动*/
function updateBalls(){for(var  i = 0;i < balls.length;i++){balls[i].x += balls[i].vx;balls[i].y += balls[i].vy;balls[i].vy += balls[i].g;//添加碰撞检测if(balls[i].y >= WIDTH_HEIGHT - balls[i].r){balls[i].y = WIDTH_HEIGHT - balls[i].r;balls[i].vy = -balls[i].vy * 0.75; }}/*** 这里进行小球数量的删除*/var count = 0;//保存当前存在在画布上的小球数量for(var i = 0;i < balls.length; i++){/*** @param  {[type]} balls[i].x +  RADIUS > 0  [小球的右边缘大于0]* @param {[type]} balls[i].x - RADIUS < WIDDOW_WIDTH  [小球的左边缘小于画布的宽度]*/if(balls[i].x + RADIUS > 0 && balls[i].x - RADIUS < WIDDOW_WIDTH){balls[count++] = balls[i];//执行完这步操作之后,前count个元素都是存在在画布上面的小球,count后面的数据就是应该删除的小球}}//删除不在画布上的小球/*** 为保证一定的运算速率,避免计算机因性能低而计算失误,那么最多只保留300个小球,* 因为count的值有可能比300大很多,所以取最小值* Math.min(300,count)*/while(balls.length > Math.min(300,count)){balls.pop();}
}
/*** [addBalls 添加彩色小球]* 类似于小球的绘制* @param {[type]} x   [当前数字的起始位置x]* @param {[type]} y   [当前数字的起始位置y]* @param {[type]} num [当前数字在数组中的索引]*/
function addBalls(x,y,num){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){//定义小球的参数var ball = {x:x+j*2*(RADIUS+1)+(RADIUS+1),y: y+i*2*(RADIUS+1)+(RADIUS+1),r:RADIUS,g:1.5 + Math.random(),/*** Math.random() * 1000:0-1000的随机数* Math.ceil(Math.random() * 1000):取整* Math.pow( -1 , Math.ceil(Math.random() * 1000)):-1的多少次方,即是1还是-1*/vx:Math.pow( -1 , Math.ceil(Math.random() * 1000)) * 4,vy:-5,color:colors[Math.ceil(Math.random() * colors.length)]}balls.push(ball);}}}
}
/*** [render 分别绘制数字]* @param  {[type]} cxt [description]*/
function render(cxt){/*** 在进行更新时间之前,如果不清空当前的画布内容* 那么后绘制的数字就会叠加在之前的数字上面,所以,这里需要刷新整个画布,也就是清空*/cxt.clearRect(0,0,WIDDOW_WIDTH,WIDTH_HEIGHT);var hours = parseInt(curShowEndtimeSeconds / 3600),minutes = parseInt((curShowEndtimeSeconds - hours * 3600) / 60),seconds = curShowEndtimeSeconds % 60;renderDigit(MARGIN_LEFT,MARGIN_TOP,parseInt(hours/10),cxt);renderDigit(MARGIN_LEFT + 15 * (RADIUS+1),MARGIN_TOP,hours%10,cxt);//冒号renderDigit(MARGIN_LEFT + 30 * (RADIUS+1),MARGIN_TOP,10,cxt);renderDigit(MARGIN_LEFT + 39 * (RADIUS+1),MARGIN_TOP,parseInt(minutes/10),cxt);renderDigit(MARGIN_LEFT + 54 * (RADIUS+1),MARGIN_TOP,minutes%10,cxt);renderDigit(MARGIN_LEFT + 69 * (RADIUS+1),MARGIN_TOP,10,cxt);renderDigit(MARGIN_LEFT + 78 * (RADIUS+1),MARGIN_TOP,parseInt(seconds/10),cxt);renderDigit(MARGIN_LEFT + 93 * (RADIUS+1),MARGIN_TOP,seconds%10,cxt);//绘制新生成的彩色小球for(var i = 0;i < balls.length ; i++){cxt.fillStyle = balls[i].color;cxt.beginPath();cxt.arc(balls[i].x,balls[i].y,balls[i].r, 0 ,Math.PI*2);cxt.closePath();cxt.fill();}
}
/*** [renderDigit 具体的绘制函数]* @param  {[type]} x   [当前数字绘制的起始坐标x]* @param  {[type]} y   [当前数字绘制的起始坐标y]* @param  {[type]} num [在digit.js中的数组中的索引值,注意冒号是10]* @param  {[type]} cxt [description]*/
function renderDigit(x,y,num,cxt){cxt.fillStyle = '#058';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();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();}}}
}

Canvas实现绚丽的倒计时效果(动画效果)相关推荐

  1. 基于canvas制作绚丽的倒计时效果

    基于canvas制作绚丽的倒计时效果 一.先看下效果 项目设计: 数字渲染:数字是存储在一个三维数组里面,通过每次传入一个数字,来取出这个数字对应的点阵模型,这个模型是一个二维数组,有圆点的地方值为1 ...

  2. 前端实现图片快速反转替换_HTML5开发之canvas实现元素图片镜像翻转动画效果的方法...

    一.Canvas图片水平镜像翻转效果预览 您可以狠狠的点击这里:canvas图片水平镜像翻转动画demo demo页面中点击图片动画效果可见. 二.Canvas上实现图片镜像翻转的实现 CSS中要想实 ...

  3. php动画效果,动画效果总结

    摘要: 动画效果总结 .main{width:100px;height: 100px;margin: 20px 20px;float:left;} .fadein,.fadeout,.fadetogg ...

  4. 实现倒计时的动画效果

    项目要求做一个这样子的gif View的代码是 package com.example;import android.content.Context; import android.graphics. ...

  5. iOS倒计时的动画效果

    -(void)countDown:(int)count{ if(count <=0){ //倒计时已到,作需要作的事吧. return; } UILabel* lblCountDown = [[ ...

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

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

  7. 炫酷canvas网页背景动画效果

    下载地址非常炫酷的网页背景旋转特效,基于canvas画布实现的网页背景动画效果 dd:

  8. Vue倒计时动画效果

    这一次在b站看到一个博主做的一个倒计时的动画效果,跟着做了一下.以下是对此次项目的一些记录与总结. 该项目效果链接:Vue倒计时 HTML部分: <div id="app"& ...

  9. js实现酷炫倒计时动画效果

    前段时间和朋友去音乐餐厅吃饭,中间有个活动,然后看到他们软件公众号H5有个活动开始的倒计时的动画效果,于是想了下实现思路. <!DOCTYPE html> <html> < ...

最新文章

  1. 解决Python模块报错:ModuleNotFoundError: No module name 'StringIO'
  2. WinForm打包或部署
  3. 命令 检查Linux服务器性能
  4. 优化ASP.NET应用性能之ViewState篇
  5. 关于反爬虫,看这一篇就够了 1
  6. 这是你从未见过的组件库 -- Android 上的手绘风格组件
  7. E. Mocha and Stars(莫比乌斯反演、简单dp)
  8. [NOI Online 2022 提高组] 丹钓战(单调栈 + 树状数组 / 主席树)
  9. Python 的协程
  10. java调用wkhtmltopdf生成pdf文件,美观,省事
  11. 剑指Offer_47_求1+2+3+...+n
  12. C# Unity依赖注入
  13. 那些基础的线程知识,你都懂了吗?| CSDN 博文精选
  14. 中缀表达式 转 前缀表达式
  15. 2021概率论与数理统计辅导讲义-李林
  16. DNS:解析域资源记录(A, AAAA, PTR, SOA, NS, CNAME, MX)
  17. docker部署kafka踩坑
  18. 30岁学前端晚不晚?别被年龄定义你的人生!
  19. C++实用的闹钟程序
  20. linux下文件属性drwxr-xr-x各是什么意思

热门文章

  1. 2018年第13周-虚拟化技术理解(内含Centos7上安装KVM)
  2. java:阿里云号码隐私服务使用
  3. 成为明星程序员的10个提示
  4. 室内地图有哪些用途?
  5. Twaver-HTML5基础学习(17)子网(SubNetwork)
  6. 计算机网络——数据链路层之介质访问控制
  7. 三菱FX3U和5U气缸控制讲解
  8. linux 卸载交叉编译工具,在终端使用命令卸载交叉编译工具
  9. 怎么将PDF文件转成PNG格式
  10. pyechart pie