2016-10-22 22 views
1

我有一個畫布和100個小圖像,我想將它們以網格狀形式添加到我的畫布中。僅在加載後顯示HTML5 Canvas中的數百個微小圖像

我已經實現了這個功能,但是圖像在畫布上逐一繪製,有時第40個位置的圖像可能會在第10個位置的圖像之前繪製。

這需要幾秒鐘,然後我得到我想要的結果,但我想知道如何才能顯示圖像只有他們加載後?

我知道還有其他類似問題的問題,但我已經閱讀了所有這些問題,並嘗試了他們的解決方案,但尚未成功。

我有這一段代碼使用嵌套的for循環繪製圖像逐一在畫布上的正確的位置:

for(...) { 
    for(..) { 
    add_image(source, row, column, width, height); 
    } 
} 

現在add_image實際創建的圖像對象,並繪製其onload

function add_image(...) { 
    let image = new Image(); 
    image.src = source; 

    image.onload = function() { 
    context.drawImage(img, row, col, width, height); 
    } 
} 

在這種情況下,首先加載所有圖像並「繪製」它們的最佳方法是什麼?我試圖創建一個數組並填充所有圖像對象,然後當所有的圖像被加載時,我會運行for循環來繪製圖像,但它不會工作,我沒有看到控制檯錯誤,所以我是左無知。

預先感謝您!

+1

你想等到它們全都加載之後再顯示它們嗎?另一種方法就像這個答案中所描述的那樣,一旦它們可用,它就按照正確的順序顯示圖像http://stackoverflow.com/questions/39506073/how-to-make-sure-images-load-sequentially/ 39526950#39526950 –

+1

在互聯網上這已被問** ** **次。你有沒有試過'javascript預加載圖像'或'javascript等到所有的圖像加載'和喜歡? – vsync

回答

0

將圖像添加到數組中,並對每個圖像進行計數。在圖像onload事件減少計數器。當計數爲零時,所有圖像都已加載並可以繪製。

例子:

var images = []; 
var loading = 0; 
function add_image(url,xpos,ypos) { 
    var image = new Image(); 
    image.src = url; 
    images.push({ 
    image : image, 
    xpos : xpos, 
    ypos : ypos, 
    }); 
    loading += 1; 
    image.onload = function() { 
     loading -= 1; 
     if(loading === 0){ 
     drawImages(); // call function to draw all the images. 
     } 
    } 
} 
function drawImages(){ 
    for(var i = 0; i < images.length; i ++){ 
     // draw the image 
     ctx.drawImage(images[i].image,images[i].xpos,images[i].ypos); 
    } 
} 
+0

我會建議使用兩個計數器一個toLoad(images.length)和一個加載的。在你的實現中,如果第一個圖像被緩存,onload事件可能會在下一個循環發生之前觸發(聽起來像是一個bug,但它每隔一段時間發生) – Kaiido

+0

@Kaiido事件不能中斷當前的執行,這是該語言的基本必要性..只要所有的圖像在同一個呼叫中添加一個計數是完全安全的。這個例子「First」將永遠在「second」之前,如果一個bug使得這個不真實的JS將無法使用。圖像只是一個1像素黑色gif'var i = new Image(); i.onload = function(){console.log(「second」);}; i.src =「data:image/gif; base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs =「; var n = performance.now(); while(performance.now() Blindman67

+0

不正確:https://jsfiddle.net/d4e5wfgv/並且有關於它的bug行爲的長列表SO:例如http:// stackoverflow。com/questions/1038327/image-onload-not-firing-twice-in-ie7 – Kaiido

0

或者使用Promise.all ...

function preloadImage(source) { 
    return new Promise((resolve, reject) => { 
    const image = new Image(); 

    image.addEventListener('load', resolve.bind(null, image)); 
    image.src = source; 
    }); 
} 

const images = []; // Array of image sources 

Promise.all(images.map(preloadImage)).then((imgs) => { 
    // Draw them :) 
}); 

這裏有一個demo on jsfiddle