canvas 做出數字倒計時 (綵球掉落效果)

 

首先是html頁面代碼

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <canvas id="canvas" style="display:block;margin:50px auto;">
        當前瀏覽器不支持Canvas,請更換瀏覽器後再試
    </canvas>

    <script src="digit.js"></script>
    <script src="countdown.js"></script>
</body>
</html>

控制形狀的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]
        ]//:
    ];

js頁面

//設置全局變量
var window_height = 768;
var window_width = 1024;
var r=8;//半徑
//第一個數字外邊距
var margin_top=60;
var margin_left=30;

var time=0;
//定義一個數組存放所有滾落的小球
var balls = [];
//定義滾落小球的顏色
var colors=["#33B5E5","#0099CC","#AA66CC","#9933CC","#99CC00","#669900","#FFBB33","#FF8800","#FF4444","#CC0000"]
//主方法 開啓啓動
window.onload=function(){
    window_height=document.body.clientHeight;
    window_width=document.body.clientWidth;

    margin_left=Math.round(window_width/10);
    r=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.height=window_height;
    canvas.width=window_width;
    //通過一個方法取得秒數
    time=gettime();
    //設置動畫  調用函數
    setInterval(
        function(){

            update();
            render(context);

        },
        50
    )

}
//更新時間
function update(){
    //獲取下一個時間的差值 和當前的差值 作比較  如果不同把給當前的差值賦值爲下一時間差值
    var nexttime=gettime();

    var nexthours=parseInt(nexttime/3600);
    var nextmin=parseInt((nexttime-nexthours*3600)/60);
    var nextsec=nexttime%60;
    //和render裏時間相同
    var nowhours=parseInt(time/3600);
    var nowmin=parseInt((time-nowhours*3600)/60);
    var nowsec=time%60;
    //如果時間發生改變
    if(nowsec != nextsec){
        //分別判斷每個數字是否相同  如果不同 調用函數添加數組
        if(parseInt(nowhours/10) != parseInt(nexthours/10)){
            addballs(margin_left,margin_top,parseInt(nexthours/10));
        }
        if(parseInt(nowhours%10) != parseInt(nexthours%10)){
            addballs(margin_left+15*(r+1),margin_top,parseInt(nexthours%10));
        }
        if(parseInt(nowmin/10) != parseInt(nextmin/10)){
            addballs(margin_left+39*(r+1),margin_top,parseInt(nextmin/10));
        }
        if(parseInt(nowmin%10) != parseInt(nextmin%10)){
            addballs(margin_left+54*(r+1),margin_top,parseInt(nextmin%10));
        }
        if(parseInt(nowsec/10) != parseInt(nextsec/10)){
            addballs(margin_left+78*(r+1),margin_top,parseInt(nextsec/10));
        }
        if(parseInt(nowsec%10) != parseInt(nextsec%10)){
            addballs(margin_left+93*(r+1),margin_top,parseInt(nextsec%10));
        }
        time=nexttime;
    }
        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;
        //如果小球到達屏幕最下方  設置小球的y軸速度爲反方向相同速度
        if(balls[i].y >= window_height-r){
            balls[i].y=window_height-r;
            //因爲空氣中有阻力 所以小球反彈應該加上一定的摩擦力
            balls[i].vy=-balls[i].vy*0.5;
        }
    }
    //因爲存放小球的數組balls的長度是不斷增長的 佔用內存
    //所以把屏幕外部的小球從數組中刪除
    var count=0;
    for(var i=0 ; i<balls.length;i++){
        if(balls[i].x+r > 0&&balls[i].x-r < window_width){
            balls[count++]=balls[i];
        }
    }
                        //如果count>300取300  如果count小於300 取count
    while(balls.length>Math.min(300,count)){
        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++){
            //如果當前位置=1 繪製小球
            if(digit[num][i][j]==1){
               var aball = {
                   x:x+2*j*(r+1)+(r+1),
                   y:y+2*i*(r+1)+(r+1),
                   //加速度1.5~2.5
                   g:1.5+Math.random(),
                   vx:Math.pow(-1,Math.ceil(Math.random()*100))*4,
                   vy:-5,
                   color:colors[Math.floor(Math.random()*colors.length)]
                }
                balls.push(aball);
            }
        }
    }
}
//獲取當前時間和結束時間的差值
function gettime(){
    //獲得當前時間
    var htime=new Date();
    var time=htime.getHours()*3600+htime.getMinutes()*60+htime.getSeconds();
    return time;
}
//得到要繪製的.數字 依次調用renderDigit函數繪製小球
function render(context){
    //清除當前窗口內容 避免多個圖案疊加
    context.clearRect(0,0,window_width,window_height);
    //得到要繪製的數字 小時 分鐘 秒
    var hours=parseInt(time/3600);
    var min=parseInt((time-hours*3600)/60);
    var sec=time%60;

    //依次繪製
    // 開始座標 第一個數字parseInt(hours/10) 上下文環境
    renderDigit(margin_left,margin_top,parseInt(hours/10) ,context);
    //第二個數字parseInt(hours%10) 上下文環境
    renderDigit(margin_left+15*(r+1),margin_top,parseInt(hours%10) ,context);

    //第一個冒號
    renderDigit(margin_left+30*(r+1),margin_top,10 ,context);

    renderDigit(margin_left+39*(r+1),margin_top,parseInt(min/10) ,context);
    renderDigit(margin_left+54*(r+1),margin_top,parseInt(min%10) ,context);

    renderDigit(margin_left+69*(r+1),margin_top,10 ,context);

    renderDigit(margin_left+78*(r+1),margin_top,parseInt(sec/10) ,context);
    renderDigit(margin_left+93*(r+1),margin_top,parseInt(sec%10) ,context);

    //循環遍歷添加彩色小球
    for(var i=0;i<balls.length;i++){

        context.beginPath();
        context.arc(balls[i].x , balls[i].y ,r , 0 , 2*Math.PI);
        context.fillStyle=balls[i].color;
        context.closePath();
        context.fill();
    }
}

//獲得每一個數字的座標 和 digit下標  根據數值判斷是否畫小球
function renderDigit(x,y,num,context){
    context.fillStyle="red";
    //遍歷每一行
    for(var i = 0 ; i <digit[num].length;i++){
        //遍歷每一行的每一個
        for(var j = 0 ; j <digit[num][i].length;j++){
            //如果當前位置=1 繪製小球
            if(digit[num][i][j]==1){
                context.beginPath();
                //開始位置
                /*
                * 圓心位置x  x+2*j*(r+1)+(r+1)
                * 圓心位置y  y+2*i*(r+1)+(r+1)
                * 半徑 r 定義
                * */
                context.arc(x+2*j*(r+1)+(r+1),y+2*i*(r+1)+(r+1),r,0,2*Math.PI);
                context.closePath();
                context.fill();
            }
        }
    }
}



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章