構(gòu)建Canvas動(dòng)畫框架進(jìn)度條的實(shí)現(xiàn)
今天和大家探討canvas動(dòng)畫框架之圖片預(yù)加載,如上圖的進(jìn)度條,這可不是假的進(jìn)度條,是真正能夠?qū)崟r(shí)獲取圖片加載進(jìn)度的進(jìn)度條。
為什么想要做這個(gè)進(jìn)度條呢?canvas需要進(jìn)度條么?答案顯然是肯定的。我們的頁面如果放到服務(wù)器上,圖片的下載將是相當(dāng)漫長的一個(gè)過程。如果我們不進(jìn)行預(yù)加載就開始執(zhí)行動(dòng)畫的話,那么用戶肯定看不到理想的效果。
那么我們就來看看canvas圖片預(yù)加載的實(shí)現(xiàn)(此處參考了網(wǎng)上一段代碼,來源:http://hi.baidu.com/jqz880321/item/fba0a210593b748489a9566c)
- /*star
- *loading模塊
- *實(shí)現(xiàn)圖片的預(yù)加載,并顯示進(jìn)度條
- *參數(shù):圖片數(shù)組對象,加載完成的回調(diào)函數(shù)
- */
- 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();
- //當(dāng)一張圖片加載完成時(shí)執(zhí)行
- images[src].onload = function(){
- //重繪一個(gè)進(jìn)度條
- 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();
- //當(dāng)所有圖片加載完成時(shí),執(zhí)行回調(diào)函數(shù)callback
- if (++loadedImages >= numImages) {
- callback();
- }
- };
- //把sources中的圖片信息導(dǎo)入images數(shù)組
- images[src].src = sources[src];
- }
- }
- //定義預(yù)加載圖片數(shù)組對象,執(zhí)行l(wèi)oading模塊
- 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'
- };
- //執(zhí)行圖片預(yù)加載,加載完成后執(zhí)行main
- loadImages(sources,main);
- };
- /*end*/
當(dāng)windows.onload發(fā)生后,我們定義一個(gè)存儲(chǔ)著所有圖片信息的對象sources,然后把它傳入loadImages這個(gè)方法里。
重點(diǎn)是看看loadImages這個(gè)方法,它有兩個(gè)參數(shù),一個(gè)是存儲(chǔ)的圖片信息的sources,一個(gè)是回調(diào)函數(shù)callback(一旦圖片加載完畢,即執(zhí)行callback。我們這里執(zhí)行的是main函數(shù),意味著動(dòng)畫開始初始化)
總圖片數(shù)我們存在numImages里面:
- // 首先遍歷數(shù)組,計(jì)算出總圖片數(shù)
- for (var src in sources) {
- numImages++;
- }
其實(shí)這個(gè)方法的核心就是給每張圖片添加一個(gè)onload事件。
當(dāng)每張圖片加載完成后,我們做了三件事:
1.計(jì)算出加載完成圖片與總圖片的百分比;
2.然后畫出一個(gè)用戶可見的進(jìn)度條,告訴用戶加載的進(jìn)度;
3.做判斷看圖片是否加載完,如加載完了就執(zhí)行callback,否則返回error。
結(jié)構(gòu)如下:
- //當(dāng)一張圖片加載完成時(shí)執(zhí)行
- images[src].onload = function(){
- //計(jì)算出加載圖片數(shù),并根據(jù)總圖片數(shù),算出百分比
- //畫出進(jìn)度條
- //if圖片加載完畢,則執(zhí)行callback
- }
原文鏈接:http://www.cnblogs.com/shawn-xie/archive/2012/07/13/2589776.html
【編輯推薦】