構建canvas動畫框架(三)——canvas圖片預加載及進度條的實現


照例先回顧一下目錄

1.通用類的提取:動畫對象與幀對象

2.靈與肉的結合:便於拆卸的運動方程

3.進度條的實現:canvas的圖片預加載

4.demo測試:通過一個demo測試框架

今天和大家探討canvas動畫框架之圖片預加載,如上圖的進度條,這可不是假的進度條,是真正能夠實時獲取圖片加載進度的進度條。

為什么想要做這個進度條呢?canvas需要進度條么?答案顯然是肯定的。我們的頁面如果放到服務器上,圖片的下載將是相當漫長的一個過程。如果我們不進行預加載就開始執行動畫的話,那么用戶肯定看不到理想的效果。

那么我們就來看看canvas圖片預加載的實現(此處參考了網上一段代碼,來源:http://hi.baidu.com/jqz880321/item/fba0a210593b748489a9566c):

/*star
 *loading模塊
 *實現圖片的預加載,並顯示進度條
 *參數:圖片數組對象,加載完成的回調函數
 */
function loadImages(sources,callback){    
    var loadedImages = 0;    
    var numImages = 0;  
    ctx.font='14px bold';
    ctx.lineWidth=5;
    var clearWidth=canvas.width;
    var clearHeight=canvas.height;
    // get num of sources    
    for (var src in sources) {    
        numImages++;    
    }    
    for (var src in sources) {    
        images[src] = new Image();
        //當一張圖片加載完成時執行    
        images[src].onload = function(){ 
            //重繪一個進度條
            ctx.clearRect(0,0,clearWidth,clearHeight);
            ctx.fillText('Loading:'+loadedImages+'/'+numImages,200,280);
            ctx.save();
            ctx.strokeStyle='#555';
            ctx.beginPath();
            ctx.moveTo(200,300);
            ctx.lineTo(600,300);
            ctx.stroke();
            ctx.beginPath();
            ctx.restore();
            ctx.moveTo(200,300);
            ctx.lineTo(loadedImages/numImages*400+200,300);  
            ctx.stroke();
            //當所有圖片加載完成時,執行回調函數callback
            if (++loadedImages >= numImages) {    
                callback();    
            }    
        };  
        //把sources中的圖片信息導入images數組  
        images[src].src = sources[src];    
    }    
}    
//定義預加載圖片數組對象,執行loading模塊
window.onload = function(){    
    var sources = {    
        PaperBoy1: "images/run/PaperBoy1.png",    
        PaperBoy2: "images/run/PaperBoy2.png", 
        PaperBoy3: "images/run/PaperBoy3.png",    
        PaperBoy4: "images/run/PaperBoy4.png",  
        PaperBoy5: "images/run/PaperBoy5.png",    
        PaperBoy6: "images/run/PaperBoy6.png",  
        PaperBoy7: "images/run/PaperBoy7.png",    
        PaperBoy8: "images/run/PaperBoy8.png",  
        PaperBoy9: "images/run/PaperBoy9.png",    
        PaperBoy10: "images/run/PaperBoy10.png",  
        PaperBoy11: "images/run/PaperBoy11.png",    
        PaperBoy12: "images/run/PaperBoy12.png",   
        PaperBoy13: "images/run/PaperBoy13.png",    
        PaperBoy14: "images/run/PaperBoy14.png", 
        PaperBoy15: "images/run/PaperBoy15.png",    
        PaperBoy16: "images/run/PaperBoy16.png",  
        PaperBoy17: "images/run/PaperBoy17.png",    
        PaperBoy18: "images/run/PaperBoy18.png",  
        PaperBoy19: "images/run/PaperBoy19.png",    
        PaperBoy20: "images/run/PaperBoy20.png",  
        PaperBoy21: "images/run/PaperBoy21.png",    
        PaperBoy22: "images/run/PaperBoy22.png",  
        PaperBoy23: "images/run/PaperBoy23.png",    
        PaperBoy24: "images/run/PaperBoy24.png", 
        _Street:'images/_Street.png',
        AD:'images/AD.png',
        building:'images/building.png',
        cloud:'images/cloud.png'
    };    
    //執行圖片預加載,加載完成后執行main
    loadImages(sources,main);    
};   
/*end*/

當windows.onload發生后,我們定義一個存儲着所有圖片信息的對象sources,然后把它傳入loadImages這個方法里。

重點是看看loadImages這個方法,它有兩個參數,一個是存儲的圖片信息的sources,一個是回調函數callback(一旦圖片加載完畢,即執行callback。我們這里執行的是main函數,意味着動畫開始初始化)

總圖片數我們存在numImages里面:


//
首先遍歷數組,計算出總圖片數 for (var src in sources) { numImages++; }

其實這個方法的核心就是給每張圖片添加一個onload事件

當每張圖片加載完成后,我們做了三件事:

1.計算出加載完成圖片與總圖片的百分比;

2.然后畫出一個用戶可見的進度條,告訴用戶加載的進度;

3.做判斷看圖片是否加載完,如加載完了就執行callback,否則返回error。

結構如下:

//當一張圖片加載完成時執行 
images[src].onload = function(){
  //計算出加載圖片數,並根據總圖片數,算出百分比
//畫出進度條
//if圖片加載完畢,則執行callback
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM