canvas粒子时钟

前面的话

本文将使用canvas实现粒子时钟效果

效果展示

点阵数字

digit.js是一个三维数组,包含的是0到9以及冒号(digit[10])的二维点阵。每个数字的点阵表示是7*10大小的二维数组

通过遍历数字点阵的二维数组,当该位置的值为1时,则绘制一个粒子,否则不绘制
canvas830-1

将绘制数字的函数命名为renderDigit()。在该函数中,将粒子绘制为一个小圆。小圆的半径为R,小圆所占据的矩形宽(高)为2(R+1)。由于数字点阵是10*7的二维数组,所以一个数字的宽度为14(R+1),高度为20(R+1)

假设数字的高度为100px,则小圆的半径R=4

< div id = "test" >
     < button >1</ button >
     < button >2</ button >
     < button >3</ button >
     < button >4</ button >
     < button >5</ button >
     < button >6</ button >
     < button >7</ button >
     < button >8</ button >
     < button >9</ button >
     < button >10</ button >
</ div >
< canvas id = "canvas" >当前浏览器不支持canvas,请更换浏览器后再试</ canvas >
< script src = "http://files.cnblogs.com/files/xiaohuochai/digit.js" ></ script >   
< script >
var canvas = document.getElementById('canvas');
if(canvas.getContext){
     var cxt = canvas.getContext('2d');
     function renderDigit(num){
         //重置画布宽度,达到清空画布的效果
         canvas.height = 100;
         var R = canvas.height/20-1;
         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(j*2*(R+1)+(R+1),i*2*(R+1)+(R+1),R,0,2*Math.PI);
                     cxt.closePath();
                     cxt.fill();
                 }
             }
         }       
     }
     var test = document .getElementById('test');
     test.onclick = function (e){
         e = e || event;
         var target = e.target || e.srcElement;
         if(!isNaN(target.innerHTML)){
             renderDigit(target.innerHTML);
         }
         
     }   
}
</script>

时钟实现

  在上一步的点阵数字的基础上,实现一个粒子时钟。将时钟实现的函数命名为digitTime(),时钟实现由获取时间数据和渲染时钟两部分组成

【时间数据】

  最简单的时钟形式由两位的小时、两位的分钟和两位的秒钟组成,中间用冒号隔开。通过日期对象Date来获取当前时间,以及当前的小时、分钟和秒钟。但是,最终需要得到的是数字表示的时钟

  比如12:02:36的时间数据的表示形式为data[1,2,10,0,2,10,3,6]

【渲染时钟】

  获取到时间数据后,通过循环使用renderDigit()来渲染时钟中的每一个数字。此时,有一个需要改变的地方是arc()函数中的x坐标,否则它们将叠加在一起

  为了将时钟数字表示更加清晰在每个数字之间增加一定的间距。每个数字的宽度是14(R+1),假设data数组中7个数字的索引为index,则每个数字的起始X坐标可以等于14(R+2)*index

  最后通过定时器每间隔一段时间后更新时间

< canvas id = "canvas" style = "width:400px;" >当前浏览器不支持canvas,请更换浏览器后再试</ canvas >
< script src = "http://files.cnblogs.com/files/xiaohuochai/digit.js" ></ script >   
< script >
var canvas = document.getElementById('canvas');
if(canvas.getContext){
     var cxt = canvas.getContext('2d');
     canvas.height = 100;
     canvas.width = 700;
     function renderDigit(index,num){
         var R = canvas.height/20-1;
         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(14*(R+2)*index + j*2*(R+1)+(R+1),i*2*(R+1)+(R+1),R,0,2*Math.PI);
                     cxt.closePath();
                     cxt.fill();
                 }
             }
         }       
     }
     function digitTime(){
         /*获取时间数据*/
         var temp = /(\d)(\d):(\d)(\d):(\d)(\d)/.exec(new Date());
         //存储时间数字,由十位小时、个位小时、冒号、十位分钟、个位分钟、冒号、十位秒钟、个位秒钟这7个数字组成
         var data = [];
         data.push(temp[1],temp[2],10,temp[3],temp[4],10,temp[5],temp[6]);
         /*渲染时钟*/
         //重置画布宽度,达到清空画布的效果
         canvas.height = 100 ;
         for(var i = 0 ; i < data.length; i++){
             renderDigit(i,data[i]);
         }
     }
     digitTime();
     clearInterval(oTimer);
     var oTimer = setInterval (function(){
         digitTime();
     },500);   
}
</script>

随机抛物线

  这节的随机抛物线运动是下节粒子动画的预备节。以DOM节点的投掷碰壁为基础,利用canvas实现一个小球的随机抛物线运动

  将小球的运动拆分为x轴和y轴运动。x轴做匀速运动,y轴先做向上的减速运动,再做向下的加速运动。当小球离开画布区域时,停止定时器

< canvas id = "canvas" style = "width:500px;" >当前浏览器不支持canvas,请更换浏览器后再试</ canvas >
< script src = "http://files.cnblogs.com/files/xiaohuochai/digit.js" ></ script >   
< script >
var canvas = document.getElementById('canvas');
if(canvas.getContext){
     var cxt = canvas.getContext('2d');
     //声明canvas的宽高
     var H = 100,W = 700;
     canvas.height = H;
     canvas.width = W;
     //存储时间数据
     var data = [];
     //存储运动的小球
     var balls = [];
     //设置粒子半径
     var R = canvas.height/20-1;
     (function(){
         var temp = /(\d)(\d):(\d)(\d):(\d)(\d)/.exec(new Date());
         //存储时间数字,由十位小时、个位小时、冒号、十位分钟、个位分钟、冒号、十位秒钟、个位秒钟这7个数字组成
         data.push(temp[1],temp[2],10,temp[3],temp[4],10,temp[5],temp[6]);   
     })();
 
     /*生成点阵数字*/
     function renderDigit(index,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){
                     cxt.beginPath();
                     cxt.arc(14*(R+2)*index + j*2*(R+1)+(R+1),i*2*(R+1)+(R+1),R,0,2*Math.PI);
                     cxt.closePath();
                     cxt.fill();
                 }
             }
         }       
     }
 
     /*更新时钟*/
     function updateDigitTime(){
         var changeNumArray = [];
         var temp = /(\d)(\d):(\d)(\d):(\d)(\d)/.exec(new Date());
         var NewData = [];
         NewData.push(temp[1],temp[2],10,temp[3],temp[4],10,temp[5],temp[6]);
         for(var i = data .length-1; i >=0 ; i--){
             //时间发生变化
             if(NewData[i] !== data[i]){
                 //将变化的数字值和在data数组中的索引存储在changeNumArray数组中
                 changeNumArray.push(i+'_'+(Number(data[i])+1)%10);
             }
         }
         //增加小球
         for(var i = 0; i< changeNumArray.length ; i++){
             addBalls.apply(this,changeNumArray[i].split('_'));
         }   
         data = NewData .concat();
     }
 
     /*更新小球状态*/
     function updateBalls(){
         for(var i = 0 ; i < balls.length; i++){
             balls[i].stepY += balls[i].disY;
             balls[i].x += balls[i].stepX;
             balls[i].y += balls[i].stepY;   
             if(balls[i].x > W + R || balls[i].y > H + R){
                 balls.splice(i,1);
                 i--;
             }               
         }
     }
 
     /*增加要运动的小球*/
     function addBalls(index,num){
         var numArray = [1,2,3];
         var colorArray =  ["#3BE","#09C","#A6C","#93C","#9C0","#690","#FB3","#F80","#F44","#C00"];
         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:14*(R+2)*index + j*2*(R+1)+(R+1),
                         y:i*2*(R+1)+(R+1),
                         stepX:Math.floor(Math.random() * 4 -2),
                         stepY:-2*numArray[Math.floor(Math.random()*numArray.length)],
                         color:colorArray[Math.floor(Math.random()*colorArray.length)],
                         disY:1
                     };
                     balls.push(ball);           
                 }
             }
         }   
     }
 
     /*渲染*/
     function render(){
         //重置画布宽度,达到清空画布的效果
         canvas.height = 100 ;
         //渲染时钟
         for(var i = 0 ; i < data.length; i++){
             renderDigit(i,data[i]);
         }       
         //渲染小球
         for(var i = 0 ; i < balls.length; i++){
             cxt.beginPath();
             cxt.arc(balls[i].x,balls[i].y,R,0,2*Math.PI);
             cxt.fillStyle = balls [i].color;
             cxt.closePath();
             cxt.fill();               
         }
     }
 
     clearInterval(oTimer);
     var oTimer = setInterval (function(){
         //更新时钟
         updateDigitTime();
         //更新小球状态
         updateBalls();
         //渲染
         render();
     },50);   
}
</script>

源码查看

公告栏扩展

  将canvas粒子时钟js部分封装为canvasTime.js,在公告栏添加如下代码,即可以实现在公告栏插入时钟的效果

< canvas id = "canvas" style = "width:100%;" height = "100" width = "700" >当前浏览器不支持canvas,请更换浏览器后再试</ canvas >

canvas830-2

canvas830-3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值