本次随笔中,我将实现一个绚丽的倒计时效果,这个效果主要是结合canvas和js实现的,具体代码如下

index.html文件

<!DOCTYPE html>
<html>
<head>
</head>
<body style="height:100%">
<canvas id="canvas" style="height:100%">
</canvas> <script src="digit.js"></script>
<script src="countdown.js"></script>
</body>
</html>

接着书写digit.js文件,这个文件中主要是一个三维数组,观察可以发现,总共有十个二维数组,分别对应1...9和:

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,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]
],//
[
[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]
],//
[
[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]
],//
[
[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]
],//
[
[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]
],//
[
[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]
],//
[
[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]
],//
[
[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]
],//
[
[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]
],//
[
[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]
]//:
];

最后实现整个效果的代码书写在countdown.js中

var WINDOW_WIDTH=1024;
var WINDOW_HEIGHT=768;
var RADIUS=8;
var MARGIN_TOP=60;
var MARGIN_LEFT=30;
var endTime=new Date();
endTime.setTime(endTime.getTime()+3600*1000); var curShowTimeSeconds=0;
var balls=[];
const colors=["#33b5E5","#0099cc","#aa66cc","#9933cc","#99cc00","#669900","#FFBB33","#FF8800","#FF4444","#cc0000"];
window.onload=function(){
WINDOW_WIDTH=document.body.clientWidth;
WINDOW_HEIGHT=768; MARGIN_LEFT=Math.round(WINDOW_WIDTH/10);
RADIUS=Math.round(WINDOW_WIDTH*4/5/108)-1;
MARGIN_TOP=Math.round(WINDOW_HEIGHT/5);
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
canvas.width=WINDOW_WIDTH;;
canvas.height=WINDOW_HEIGHT; curShowTimeSeconds=getCurrentShowTimeSeconds();
setInterval(
function(){
render(context);
update();
},
50 ); }
function getCurrentShowTimeSeconds(){
var curTime=new Date();
var ret=endTime.getTime()-curTime.getTime();
ret=Math.round(ret/1000);
return ret>0? ret:0; }
function update(){
var nextShowTimeSeconds=getCurrentShowTimeSeconds();
var nextHours=parseInt(nextShowTimeSeconds/3600);
var nextMinutes=parseInt(nextShowTimeSeconds/60%60);
var nextSeconds=parseInt(nextShowTimeSeconds%60); var curHours=parseInt(curShowTimeSeconds/3600);
var curMinutes=parseInt(curShowTimeSeconds/60%60);
var curSeconds=parseInt(curShowTimeSeconds%60);
if(nextSeconds!=curSeconds){
if(parseInt(curHours/10)!=parseInt(nextHours/10)){
addBalls(MARGIN_LEFT+0,MARGIN_TOP,parseInt(curHours/10));
}
if(parseInt(curHours%10)!=parseInt(nextHours%10)){
addBalls(MARGIN_LEFT+15*(RADIUS+1),MARGIN_TOP,parseInt(curHours%10));
}
if(parseInt(curMinutes/10)!=parseInt(nextMinutes/10)){
addBalls(MARGIN_LEFT+39*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes/10));
}
if(parseInt(curMinutes%10)!=parseInt(nextMinutes%10)){
addBalls(MARGIN_LEFT+54*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes%10));
}
if(parseInt(curSeconds/10)!=parseInt(nextSeconds/10)){
addBalls(MARGIN_LEFT+78*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds/10));
}
if(parseInt(curSeconds%10)!=parseInt(nextSeconds%10)){
addBalls(MARGIN_LEFT+93*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds%10));
}
curShowTimeSeconds=nextShowTimeSeconds;
}
updateBalls();
}
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>=WINDOW_HEIGHT-RADIUS){
balls[i].y=WINDOW_HEIGHT-RADIUS;
balls[i].vy=-balls[i].vy*0.75;
}
}
var cnt=0;
for(var i=0;i<balls.length;i++)
if(balls[i].x+RADIUS>0&&balls[i].x-RADIUS<WINDOW_WIDTH)
balls[cnt++]=balls[i];
while(balls.length>cnt){
balls.pop();
} }
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 aBall={
x:x+j*2*(RADIUS+1)+(RADIUS+1),
y:y+i*2*(RADIUS+1)+(RADIUS+1),
g:1.5+Math.random(),
vx:Math.pow(-1,Math.ceil(Math.random()*1000))*4,
vy:-5,
color:colors[Math.floor(Math.random()*colors.length)]
}
balls.push(aBall);
}
}
function render(cxt){
cxt.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
var hours=parseInt(curShowTimeSeconds/3600);
var minutes=parseInt(curShowTimeSeconds/60%60);
var seconds=parseInt(curShowTimeSeconds%60);
//var hours=12;
//var minutes=34;
// var seconds=56;
renderDigit(MARGIN_LEFT,MARGIN_TOP,parseInt(hours/10),cxt);
renderDigit(MARGIN_LEFT+15*(RADIUS+1),MARGIN_TOP,parseInt(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,parseInt(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,parseInt(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,RADIUS,0,2*Math.PI,true);
cxt.closePath();
cxt.fill();
}
}
function renderDigit(x,y,num,cxt){
cxt.fillStyle = "rgb(0,102,153)"; 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. 使用nosql实现页面静态化的一个小案列

    页面静态化,其实就是将动态生成的php页面,变成静态的HTML页面,让用户直接访问.有一下几方面好处: 1,首先就是访问速度,不需要去访问数据库,或者缓存来获取哪些数据,浏览器直接加载渲染html页即 ...

  2. Jquery局部刷新小案列

    /* 调用showTest()方法去后台拿到处理数据后返回到part.jsp页面,main.jsp再调用html()方法 和显示的结果集show()方法把part.jsp显示到当前的页面,实现局部页面 ...

  3. jQuery---EasyUI小案列

    jQuery EasyUI为提供了大多数UI控件的使用,如:accordion,combobox,menu,dialog,tabs,validatebox,datagrid,window,tree等等 ...

  4. 表格排序tablesort小案列

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  5. Tensorflow 中(批量)读取数据的案列分析及TFRecord文件的打包与读取

    内容概要: 单一数据读取方式: 第一种:slice_input_producer() # 返回值可以直接通过 Session.run([images, labels])查看,且第一个参数必须放在列表中 ...

  6. 2021年-在windwos下如何用TOMACT发布一个系统(完整配置案列)

    2021年新年第一篇:博主@李宗盛-关于在Windwos下使用TOMCAT发布一个系统的完成配置案列. 之前写过关于TOMCAT的小篇幅文档,比较分散,可以作为对照与参考. 此篇整合在一起,一篇文档写 ...

  7. 如何开发一个简单的HTML5 Canvas 小游戏

    原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...

  8. Spring MVC的配置文件(XML)的几个经典案列

    1.既然是配置文件版的,那配置文件自然是必不可少,且应该会很复杂,那我们就以一个一个的来慢慢分析这些个经典案列吧! 01.实现Controller /* * 控制器 */ public class M ...

  9. js闭包的作用域以及闭包案列的介绍:

    转载▼ 标签: it   js闭包的作用域以及闭包案列的介绍:   首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几 ...

随机推荐

  1. 【c# 学习笔记】c#委托是什么

    法庭上律师为当事人辩护,他真正执行的是当事人的陈词,律师就相当于一个委托对象,而当事人则委托律师对象为自己辩护. c#中的委托概念也就好比律师对象,它是一个类(“委托是类类型”这个事实将在“委托本质” ...

  2. cad.net vs调试问题 20190923增加默认启动注册表,20191007更新vs2019到16.3.2

    Acad2008和Acad2010需要修改安装目录下的acad.exe.config文件内容,才可以捕获断点: <configuration> <startup> <!- ...

  3. Docker容器内部端口映射到外部宿主机端口 - 运维笔记

    Docker允许通过外部访问容器或者容器之间互联的方式来提供网络服务.容器启动之后,容器中可以运行一些网络应用,通过-p或-P参数来指定端口映射. 注意:宿主机的一个端口只能映射到容器内部的某一个端口 ...

  4. Jmeter之Bean shell使用(二)(转载)

    转载地址:https://www.cnblogs.com/puresoul/p/4949889.html 上一篇Jmeter之Bean shell使用(一)简单介绍了下Jmeter中的Bean she ...

  5. [转帖]spring boot项目集成jacoco

    小试牛刀:spring boot项目集成jacoco 2019-03-28 20:14:36 zyq23333 阅读数 509   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议, ...

  6. thymeleaf是用于编写html模版的编程语言(工具语言)

    一.编程语言 用于编写html模版的编程语言. thymeleaf一种命令式和声名式混合的寄生语言. html与thymeleaf的结合是dsl与命令式语言的结合. html与thymeleaf的结合 ...

  7. golang学习笔记--接口

    go 的接口类型用于定义一组行为,其中每个行为都由一个方法声明表示. 接口类型中的方法声明只有方法签名而没有方法实体,而方法签名包括且仅包括方法的名称.参数列表和结果列表. 只要一种数据类型的方法集合 ...

  8. 1、VUE介绍

    1.VUE简介 最近一段时间,Web前端领域出现了很多MVVM框架技术,如AngularJS.React,VUE.js等等. Vue.js借鉴了AngularJS的设计理念,也吸取了React和Ang ...

  9. 通过Ldap实现人事系统组织人事和AD的同步

    项目需求:同步人事系统的组织架构-对应AD的OU树同步人事系统的员工-对应AD的用户 创建OU 名字不能重复,需要父级路径(parentOrganizeUnit)以及新ou的名字(name),如果最父 ...

  10. C# 调用JS Eval,高效率

    /// <summary> /// 动态计算表达式 /// </summary> class JSCaller { /// <summary> /// 动态计算表达 ...