先来个效果图:
效果很不错吧,学习视频链接如下:http://www.imooc.com/learn/133。
(PS:老师讲的太好,忍不住为他打个小广告了,,强烈推荐去学习啊)
1、页面结构:跟前面两个一样的,body中一个canvas标签,id为myCanvas。另外引入digit.js和countdown.js。
2、digit.js:定义了一个名为digit的全局数组,记录了0-9以及冒号的11个点阵,一种1代表该处需要绘制一个小球,0处表示该处为空,不需要绘制东西。以下为0的点阵信息:
[ [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开始,所以 digit数组也是从0开始,这样子digit[0]取的也就是0的点阵信息,digit[1]即为数字1的点阵信息,是不是很巧妙。
3、countdown.js:用来获取当前时间,根据当前时间和digit.js中的点阵信息以小球的形式显示电子钟,再根据时间的变化绘制上弹跳小球。代码如下:
var WINDOW_Width=1024;//canvas的宽度 var WINDOW_HEIGHT=600;//canvas的高度 var RADIUS=8;//圆球半径 var MAGIN_TOP=60;//每个数字距离画布上部的距离 var MAGIN_LEFT=30;//每个数字距离画布左部的距离 //var endTime = new Date(2016,5,30,18,00,00);//指定结束时间 //指定时间为当前时间一个小时之后 var endTime = new Date(); endTime.setTime(endTime.getTime()+1*60*60*1000); var interval=null; var curShowTimeSeconds=0; //添加弹跳小球数据 var ball=[];//小球的坐标 var colors=["#33B5E5","#0099CC","#AA66CC","#9933CC","#99CC00","#669900","#FFBB33","#FF8800","#FF4444","#CC0000"];//小球的颜色 window.onload=function(){ //1、获取myCanvas对象 var myCanvas = document.getElementById("myCanvas"); //判断当前浏览器是否支持canvas if(myCanvas.getContext("2d")){ var context = myCanvas.getContext("2d");//获取绘图上下文环境 //通过获取屏幕的宽度和高度,给canvas设置宽高以自适应屏幕 //此处有三个注意点: //1、必须给body和canvas标签添加style="height:100%;"的样式,让时间数字铺开整个屏幕; //2、必须使用document.documentElement.clientHeight,若是使用document.body.clientHeight获取到的高度非常小,显示的数字只能显示一半 //3、必须减去20,否则会出现滚动条 WINDOW_Width = document.documentElement.clientWidth-20; WINDOW_HEIGHT = document.documentElement.clientHeight-20; //设置宽高 myCanvas.width=WINDOW_Width; myCanvas.height=WINDOW_HEIGHT; //设置margin-left和margin-top,以及RADIUS //10:时间数字占据整个屏幕的4/5,那么两边总共是1/5,一侧则是1/10 MAGIN_LEFT = Math.round(WINDOW_Width/10); //时间数字占据整个屏幕的4/5,即window_width*4/5,这是所有时间数字占据的屏幕总宽度 //而最后一个数字的左边距为margin_left+93*(radius+1),在加上它本身的15个(radius+1),因此这个4/5的屏幕宽度总共放置了93+15=108个(radius+1),计算出每个(radius+1)之后再减去1就是radius的值了 RADIUS = Math.round(WINDOW_Width*4/5/108)-1;//108=93+15 //margin_top跟上下文的坐标的计算没有关系,因此可以随便定义,此处定义为屏幕高度的1/5 MAGIN_TOP = Math.round(WINDOW_HEIGHT/5); //alert(WINDOW_Width+"\n"+WINDOW_HEIGHT); //2、绘制当前时间图形 curShowTimeSeconds = getCurrentShowTimeSeconds(); setInterval(function(){ render(context);//绘制数字和小球 update();//更新数字和小球信息 },50);//50毫秒执行一次 }else{ alert("当前浏览器不支持canvas标签"); } } /** *该方法用来绘制图形 *@param cxt:上下文绘图环境context **/ function render(cxt){ if(curShowTimeSeconds>0){ cxt.clearRect(0,0,WINDOW_Width,WINDOW_HEIGHT);//刷新整个canvas,不然时间数字和弹跳小球会堆积在整个画布中 var hour = parseInt((curShowTimeSeconds/(60*60))%24,10);//小时 var minute = parseInt((curShowTimeSeconds/60)%60,10);//分钟:先计算成总共有多少分钟,再取分钟的余数 var seconds = curShowTimeSeconds%60;//秒:本来就是秒,直接获取最后剩下的秒就好了 //补零:当分钟和秒数只有两位数时,十位数/10时结果为零,会自动绘制0的图形,所以不再需要手动补零 //minute = checkTime(minute); //seconds = checkTime(seconds); //时+冒号 renderDigit(MAGIN_LEFT,MAGIN_TOP,parseInt(hour/10,10),cxt);//小时的十位数 //15=7*2+1,7:每个点阵是7*10,每个方形的直径为2*(RADIUS+1),所以要乘以2,最后的1是保留空间,让两个数字之间有间距 renderDigit(MAGIN_LEFT+(15*(RADIUS+1)),MAGIN_TOP,parseInt(hour%10,10),cxt);//小时的个位数 //30:前面一个已经到15*(RADIUS+1),且每一个数字的间距都是15*(RADIUS+1),因此此处就到30了 //10:digit点阵下标为10的,刚好是冒号对应的点阵,所以用10 renderDigit(MAGIN_LEFT+(30*(RADIUS+1)),MAGIN_TOP,10,cxt);//小时后面的冒号 //分+冒号 //39=30+4*2+1:30是前一个冒号的x坐标,4是“冒号的点阵为4*10”,2为“方形的直径为2*(RADIUS+1)”,1为保留空间 renderDigit(MAGIN_LEFT+(39*(RADIUS+1)),MAGIN_TOP,parseInt(minute/10,10),cxt);//分钟的十位数 //54=39+15 renderDigit(MAGIN_LEFT+(54*(RADIUS+1)),MAGIN_TOP,parseInt(minute%10,10),cxt);//分钟的个位数 //69=54+15 renderDigit(MAGIN_LEFT+(69*(RADIUS+1)),MAGIN_TOP,10,cxt);//分钟后面的冒号 //秒+冒号 //78=69+4*2+1 renderDigit(MAGIN_LEFT+(78*(RADIUS+1)),MAGIN_TOP,parseInt(seconds/10,10),cxt);//秒数的十位数 //93=78+15 renderDigit(MAGIN_LEFT+(93*(RADIUS+1)),MAGIN_TOP,parseInt(seconds%10,10),cxt);//秒数的十位数 //绘制小球 for(var i=0;i<ball.length;i++){ cxt.fillStyle=ball[i].color;//填充颜色 cxt.beginPath(); cxt.arc(ball[i].x,ball[i].y,RADIUS,0,2*Math.PI,true);//绘制弹跳小球 cxt.closePath(); cxt.fill();//给小球填充颜色 } } } //获取当前时间 function getCurrentShowTimeSeconds(){ /*(倒计时) var startTime = new Date().getTime();//开始时间 var diffTime = parseInt((endTime-startTime)/1000,10);//得到两个时间差的秒数 return diffTime>0?diffTime:0; */ //时钟效果 var curTime = new Date();//开始时间 var diffTime = curTime.getHours()*60*60+curTime.getMinutes()*60+curTime.getSeconds();//得到两个时间差的秒数(电子钟报时) return diffTime; } function update(){ var nextShowTimeSeconds = getCurrentShowTimeSeconds(); var nextHour = parseInt((nextShowTimeSeconds/(60*60))%24,10);//小时 var nextMinute = parseInt((nextShowTimeSeconds/60)%60,10);//分钟:先计算成总共有多少分钟,再取分钟的余数 var nextSeconds = nextShowTimeSeconds%60;//秒:本来就是秒,直接获取最后剩下的秒就好了 var curHour = parseInt((curShowTimeSeconds/(60*60))%24,10);//小时 var curMinute = parseInt((curShowTimeSeconds/60)%60,10);//分钟:先计算成总共有多少分钟,再取分钟的余数 var curSeconds = curShowTimeSeconds%60;//秒:本来就是秒,直接获取最后剩下的秒就好了 //因为秒数变化的比较最快,所以判断秒数是否相同 if(nextSeconds!=curSeconds){ //判断哪个数字发生了变化,若变化了就添加当前时间下的小球 //小时 if(parseInt(curHour/10)!=parseInt(nextHour/10)){ addBall(MAGIN_LEFT+0,MAGIN_TOP,parseInt(curHour/10));//发生变化时,添加变化数字的弹跳小球 } if(parseInt(curHour%10)!=parseInt(nextHour%10)){ addBall(MAGIN_LEFT+(15*(RADIUS+1)),MAGIN_TOP,parseInt(curHour%10,10)); } //分钟 if(parseInt(curMinute/10)!=parseInt(nextMinute/10)){ addBall(MAGIN_LEFT+(39*(RADIUS+1)),MAGIN_TOP,parseInt(curMinute/10,10)); } if(parseInt(curMinute%10)!=parseInt(nextMinute%10)){ addBall(MAGIN_LEFT+(54*(RADIUS+1)),MAGIN_TOP,parseInt(curMinute%10,10)); } //秒 if(parseInt(curSeconds/10)!=parseInt(nextSeconds/10)){ addBall(MAGIN_LEFT+(78*(RADIUS+1)),MAGIN_TOP,parseInt(curSeconds/10,10)); } if(parseInt(curSeconds%10)!=parseInt(nextSeconds%10)){ addBall(MAGIN_LEFT+(93*(RADIUS+1)),MAGIN_TOP,parseInt(curSeconds%10,10)); } curShowTimeSeconds = nextShowTimeSeconds; } //更新正在画布上运动的小球 updateBalls(); //console.log(ball.length); } //该方法用来处理正在画布上运动的小球 function updateBalls(){ for(var i=0;i<ball.length;i++){ ball[i].x +=ball[i].vx; ball[i].y +=ball[i].vy; ball[i].vy +=ball[i].g; //判断小球是否碰壁,若是碰壁就减小y方向的高度,达到小球越跳越低的效果 if(ball[i].y>=WINDOW_HEIGHT-RADIUS){ ball[i].y=WINDOW_HEIGHT-RADIUS; ball[i].vy = -ball[i].vy*0.75;//慢慢降低弹跳小球的高度,达到小球越跳越低的效果 } } //判断小球是否还在画布中 var cnt = 0; for(var i=0;i<ball.length;i++){ if(ball[i].x+RADIUS>0 && ball[i].x-RADIUS<WINDOW_Width){//说明小球还在画布中 ball[cnt++]=ball[i];//将在画布中的小球全部添加到ball的前面 } } //通过前面for循环的处理,在画布中的小球全部集中到了ball数组的全面,那么后面部分即为不在屏幕中的小球,可以清空掉 //按道理while循环中的条件应该为:ball.length>cnt,这样子会有一个bug,就是:打开该页面以后,切换到别的页面,弹跳的数量会一直积累,达不到优化性能的效果 //所以修改为ball.length>Math.min(300,cnt),让画布中的弹跳小球保持在300附近 while(ball.length>Math.min(300,cnt)){ //pop() 方法用于删除并返回数组的最后一个元素。 ball.pop();//将数组末尾的小球删掉,避免内存中小球数量太多影响性能 } } /** *该方法用来添加弹跳的小球 *@param x:小球起点x坐标 *@param y:小球起点y坐标 *@param num:需要添加弹跳小球的数字 **/ function addBall(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)),//x坐标 y:(y+i*2*(RADIUS+1)+(RADIUS+1)),//y坐标 g:1.5+Math.random(),//加速度:设置为随机数,到小球弹跳不规则 vx:Math.pow(-1,Math.ceil(Math.random()*1000))*4,//小球在x方向的速度(-4或者+4) vy:-5,//小球在y方向的速度,让小球在生成时有一个向上抛的动作 color:colors[Math.floor(Math.random()*colors.length)]//小球的颜色 }; ball.push(aBall);//将生成的小球添加到ball数组中 } } } } /** *该方法用来解决“分秒为1位数以下时自动添加零变成2位数”的问题 *@param value:需要补零的值 */ function checkTime(value){ value = parseInt(value,10); if(value<10){ value = "0"+value; } return value; } /** *该方法用来绘制图形 *@param x:起点x坐标 *@param y:起点y坐标 *@param num:需要进行绘制的数字 *@param cxt:上下文绘图环境context **/ 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(); //RADIUS为圆球的半径,RADIUS+1作为盛放圆球的方形半径,1是多余出来的空间,那么方形的直径为:2*(RADIUS+1) //x+j*2*(RADIUS+1)+(RADIUS+1):x+j*2*(RADIUS+1)计算要绘制的球形所在前一个方形的位置, //(RADIUS+1)为下一个方形的一半,也就是要绘制的球形的中心 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();//绘制 } } } }
具体实例已经上传到附件,有需要的可以下载。记得在支持html5的浏览器中执行哦!
相关推荐
之前我们有给大家介绍过很多基于...这次要分享的是15个超绚丽的HTML5 Canvas时钟动画特效,它们很多都有各自不同的外观,有几个时钟的造型还非常新颖奇特,因为是基于HTML5 Canvas的,所以你的浏览器需要支持HTML5。
在JavaScript的世界里,canvas元素是Web开发中的一个强大工具,它允许开发者动态绘制...通过学习和理解这个项目,开发者不仅可以提升canvas技能,还能掌握时间显示和动画制作的技术,为自己的项目添加更多创意元素。
在本案例中,我们关注的是HTML5中的Canvas元素,它是实现炫丽时钟倒计时效果的关键。 Canvas是HTML5的一个核心特性,允许通过JavaScript在网页上绘制图形。它是一个矩形区域,可以被编程来显示动态或静态的图像。...
1.11_优化、扩展canvas绚丽时钟之性能优化|倒计时粒子效果|Canvas图形、动画、游戏开发从入门到精通全系列课程
1.12_优化、扩展canvas绚丽时钟之屏幕自适应|倒计时粒子效果|Canvas图形、动画、游戏开发从入门到精通全系列课程
1.13_优化、扩展canvas绚丽时钟之改进成时间管理小工具|倒计时粒子效果|Canvas图形、动画、游戏开发从入门到精通全系
HTML5的Canvas元素是...通过以上知识点的学习和实践,你将能够利用HTML5的Canvas和JavaScript创造出各种炫丽的计时器效果,甚至更复杂的动画图形。在实践中不断探索和优化,你会发现Canvas是一个充满无限可能的舞台。
采用HTML5-炫丽的时钟效果 Canvas 绘图与动画,炫酷的彩球颗粒效果-当前时间秒变换。
"canvas study"这个主题深入探讨了使用Canvas进行炫丽倒计时效果的实现,以及Canvas绘图与动画的基础知识。 首先,让我们了解一下Canvas的基本概念。HTML5的Canvas是一个矩形区域,通过JavaScript API,我们可以在...
在这个“clockCanvas”示例中,我们将学习如何使用Canvas来实现一个绚丽的时钟特效。 首先,Canvas是一个基于标签的HTML元素,通过JavaScript来控制其内容的绘制。在HTML文件中,我们需要创建一个`<canvas>`标签,...
现实最新的版本可以利用Qt Quick实现很多的绚丽的效果。此里只是利用画布Canvas简单钟表的效果。效果如下: 源码如下 import QtQuick 2.6 import QtQuick.Window 2.2 Window { visible: true width: 740 height...
CSS3波浪形菜单 结合背景超级绚丽 HTML5 Canvas头发飘逸动画 很酷的HTML5动画 HTML5 Canvas画板画图工具 可定义笔刷和画布 HTML5_CSS3 3D文字特效 文字外翻效果 HTML5_CSS3带日期区间的日期选择插 HTML5_CSS3时尚的...
1、结合使用HTML5与JS实现...2、倒计时数字时钟及弹落的小球都是基于Canvas绘制的,时间的计算是基于javascript中的Date()中的方法。 3、这里的Canvas不仅是一个元素,它更是一套编程的接口,HTML5得到更多人的青睐。
8. **HTML5 Canvas时钟**:通过Canvas绘制的3D时钟,利用HTML5的绘图能力,创建出极具视觉冲击力的时间显示效果。 9. **3D侧躺菜单**:CSS3的3D变换特性被用于创建这款独特的菜单,侧躺的布局和3D展开效果为用户...