2016-06-19 35 views
1

您好我有以下功能帆布畫已被碼圖像下方

render = function (ctx, img, W, H) { 
    ctx.drawImage(img, 0, 0, W, H, 0, 0, W, H); 
} 

我從另一個功能

renderImage(ctx, img, width, height); 
for(var i = 0; i < 10000000 ; i++) { 
    // en expensive for loop 
}    

的問題,我面對的圖像不會加載調用該函數在瀏覽器中,直到for循環完成執行,但是不清楚爲什麼圖像會一直等到for循環結束。任何人都可以幫忙如何在不等待循環完成執行的情況下加載它?

+0

'context.drawImage' should be 'ctx.drawImage' – grateful

+1

當你說「*不加載*」時,你的意思是「不渲染」是正確的?這是因爲這是JavaScript的工作原理。它是單線程的,如果你執行一個for循環,它會阻塞任何東西,直到執行過程結束。將你的循環拆分成多個較小的循環,用超時或者在requestAnimationFrame中調用它們。 – Kaiido

回答

2

JavaScript是單線程的,因此瀏覽器在循環運行時無法更新屏幕。

爲了解決瀏覽器使用延遲呼吸的時刻。這當然會使代碼運行異步,因此可能需要回調機制,具體取決於代碼的下一步行動。

例子:

renderImage(ctx, img, width, height); 

setTimeout(function() { 
    for(var i = 0; i < 10000000 ; i++) { 
    // en expensive for loop 
    } 
    // call next step 
}, 9); // delay some arbitrary ms 

如果循環是長期運行的,你可以考慮在多個段拆分它或使用WebWorker

見這些答案對如何拆分循環:

特別提示:您不必使用裁剪參數繪製調整後的圖像,只需提供寬度和高度:

ctx.drawImage(img, 0, 0, W, H); 
+0

嗨感謝你的回答。 'requestAnimationFrame'不起作用,但'setTimeout'完美工作。任何想法爲什麼? –

+0

@MuhammadRaihanMuhaimin原則上應該是相同的,唯一的區別是setTimeout需要指定的超時值(> = 4 ms)。如果瀏覽器較舊,您可能需要爲rquestAnimationFrame填充一個polyfill。 – K3N

+1

@ K3N我正在使用chrome。如果我刪除超時變量並將其替換爲window.requestAnimationFrame,它將停止工作,直到循環結束。 –

0

您是否嘗試先加載圖像,然後運行繪圖?

var img = new Image(); 
var i = 0; 
img.onload = function(){ 
    //draw... 
    animate(); 
}; 
img.src = 'source.jpg'; 
function animate(){ 
    if(i<10000000) { 
     requestAnimationFrame(animate); 
     render(); 
    } 
} 

function render(){ 
    //draw 
} 
+0

是的,我遵循上面的方法,但這不起作用 –

+0

你嘗試'requestAnimationFrame'嗎? –

+0

'for'循環太快,您應該使用專爲繪圖而設計的方法,如'setinterval'或'requestAnimationFrame' https://developer.mozilla.org/es/docs/Web/API/Window/requestAnimationFrame –