迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 >

用canvas实现炫丽的计时器效果

作者:迹忆 最近更新:2022/11/13 浏览次数:

首先看一下将要实现的效果图

接下来我们逐步实现此效果

一、 定义画布的宽高,还有小球的半径,并且定义小球的几种颜色

var WINDOW_WIDTH=1024;
var WINDOW_HEIGHT=768;
var RADIUS=6;
const colors=["#33B5E5","#0099CC","#AA66CC","#9933CC","#99CC00","#669900","#FFBB33","#FF8800","#FF4444","#CC0000"];

二、 使用canvas开始绘制画布,小球等图形

window.onload=function(){
            WINDOW_WIDTH=document.body.clientWidth;
            WINDOW_HEIGHT=document.body.clientHeight;
            var canvas=document.getElementById("canvas_onmpw");
            var context=canvas.getContext("2d");
            canvas.width=WINDOW_WIDTH;
            canvas.height=WINDOW_HEIGHT;
            setInterval( 
                function(){
                    drawBalls(context);
                    moveball();
                },50);
 }

三、 定义drawBalls() 和 moveball()函数

function drawBalls(cxt){
            cxt.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
            var times=getTime();
            var hours=parseInt(times/3600);
            var minutes=parseInt((times-hours*3600)/60);
            var seconds=parseInt(times%60);
            drawDigit(parseInt(hours/10),0,cxt);
            drawDigit(hours%10,digit[0][0].length,cxt);
            drawDigit(10,digit[0][0].length*2,cxt);
            drawDigit(parseInt(minutes/10),digit[0][0].length*2+digit[10][0].length,cxt);
            drawDigit(minutes%10,digit[0][0].length*3+digit[10][0].length,cxt);
            drawDigit(10,digit[0][0].length*4+digit[10][0].length,cxt);
            drawDigit(parseInt(seconds/10),digit[0][0].length*4+digit[10][0].length*2,cxt);
            drawDigit(seconds%10,digit[0][0].length*5+digit[10][0].length*2,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();    
            }
 }

函数体中又有自定义函数drawDigit(),这个函数是用来实现时间的样式的。关于此函数的定义,我们在第四步的时候实现,下面我们看moveball()函数的定义

function moveball(){
            //得到当前的时间
            var nextShowTime=getTime();
            var nextHour=parseInt(nextShowTime/3600);
            var nextMinutes=parseInt((nextShowTime-nextHour*3600)/60);
            var nextSeconds=nextShowTime%60;
            var curHour=parseInt(currentshowtime/3600);
            var curMinutes=parseInt((currentshowtime-curHour*3600)/60);
            var curSeconds=currentshowtime%60;
            if(nextSeconds!=curSeconds){
                if(parseInt(nextHour/10)!=parseInt(curHour/10)){
                    addBalls(100,100,parseInt(nextHour/10));    
                }
                if(nextHour%10!=curHour%10){
                    addBalls(100+digit[0][0].length*(2*(RADIUS+2)),100,nextHour%10);    
                }
                if(parseInt(curMinutes/10)!=parseInt(nextMinutes/10)){
                    addBalls(100+(digit[0][0].length*2+digit[10][0].length)*(2*(RADIUS+2)),100,parseInt(nextMinutes/10));    
                }
                if(curMinutes%10!=nextMinutes%10){
                    addBalls(100+(digit[0][0].length*3+digit[10][0].length)*(2*(RADIUS+2)),100,nextMinutes%10);    
                }
                if(parseInt(curSeconds/10)!=parseInt(nextSeconds/10)){
                    addBalls(100+(digit[0][0].length*4+digit[10][0].length*2)*(2*(RADIUS+2)),100,parseInt(nextSeconds/10));
                }
                if(curSeconds%10!=nextSeconds%10){
                    addBalls(100+(digit[0][0].length*5+digit[10][0].length*2)*(2*(RADIUS+2)),100,nextSeconds%10);
                }
                currentshowtime=nextShowTime;
            }
            move();
            console.log(balls.length);
 }

同样此函数中涉及到两个自定义函数,addBalls()(此函数是为了实现将要改变的数字上面的小球加入数组中,以实现这些小球的斜抛运动)和 move()(实现由addBalls()加入数组中的小球的斜抛运动)。这两个函数将在第五步中实现

四、 定义drawDigit()函数

function drawDigit(num,dis,cxt){         
       var tempball={x:100,y:100,radius:RADIUS,color:"#FF0000"};
        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){
                        tempball.x=100+dis*(2*(RADIUS+2))+j*(2*(RADIUS+1));
                        tempball.y=100+i*2*(RADIUS+1);
                        drawball(tempball,cxt);    
                    }
             }
        }
 }

此函数中涉及到drawball()函数,此函数功能是绘制时间小球。其定义我们在第六步中实现

五、 定义addBalls() 和 move()函数

function addBalls(ax,ay,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:ax+j*(2*(RADIUS+1)),
                            y:ay+i*(2*(RADIUS+1)),
                            gy:8+Math.random(),
                            vx:Math.pow(-1,Math.ceil(Math.random()*1000))*5,
                            vy:-8,
                            color:colors[Math.floor(Math.random()*colors.length)]      
                        };    
                        balls.push(aball);
                    }
                }
            }
 }

function move(){
        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].vy+balls[i].gy*0.05;
        }
        var count=0;
        for(var j=0;j<balls.length;j++){
             if(balls[j].y<WINDOW_HEIGHT){
                 balls[count++]=balls[j];    
             }
        }
        while(balls.length>count){
             balls.pop();    
        }
 }

在addBalls()函数中有balls.push()将小球放入数组中,如果无限制的将小球加入数组,那么数组会越来越大,所以在move()函数中定义又根据小球是否超出边界来将小球从数组中再取出,以达到数组中小球数量的稳定。

六、 实现drawball()函数

function drawball(ball,cxt){
         cxt.fillStyle=ball.color;
         cxt.beginPath();
         cxt.arc(ball.x,ball.y,ball.radius,0,2*Math.PI,true);
         cxt.closePath();
         cxt.fill();
}

实现以上六个步骤,就可以实现计时器的效果。如果有什么问题,欢迎在下面留言讨论,大家共同提高。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便