2016-06-19 6 views
1

Hallo blockiert ziehen Ich habe eine folgende FunktionLeinwand Bild von Code darunter

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

ich von einer anderen Funktion

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

Das Problem der Funktion nenne ich das Bild bin vor nicht geladen im Browser, bis die for-Schleife die Ausführung beendet, jedoch ist nicht klar, warum das Bild warten soll, bis die for-Schleife beendet ist. Jeder kann helfen? Wie kann ich es laden, ohne auf die Ausführung der Schleife zu warten?

+0

'context.drawImage' sollte sein 'ctx.drawImage' – grateful

+1

Wenn Sie" * nicht laden * "sagen, meinen Sie" nicht rendern "richtig? Es ist, weil so Javascript funktioniert. Es ist single-threaded und wenn Sie eine for-Schleife wie diese ausführen, wird alles blockiert, bis der Ausführungsprozess abgeschlossen ist. Teilen Sie Ihre Schleife in mehrere kleinere auf, rufen Sie sie mit einem Timeout oder innerhalb eines requestAnimationFrame auf. – Kaiido

Antwort

2

JavaScript ist single threaded damit der Browser von der Aktualisierung des Bildschirms verhindert wird, während die Schleife läuft.

Um zu lösen geben Sie dem Browser einen Moment zum Atmen mit einer Verzögerung. Dies führt natürlich dazu, dass der Code asynchron läuft, so dass möglicherweise ein Callback-Mechanismus erforderlich ist, abhängig von der nächsten Bewegung des Codes.

Beispiel:

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 

Wenn die Schleife lang andauernde Sie in mehrere Segmente aufzuteilen, um es in Erwägung ziehen könnte oder eine WebWorker verwenden.

Sehen Sie diese Antworten, wie die Schleife zu spalten:

Bonus-Tipp: Sie müssen nicht die Clipping-Parameter verwenden, um eine Größe geänderte Bild zu zeichnen, nur Breite und Höhe angeben:

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

Hallo Danke für die Antwort. 'requestAnimationFrame' funktioniert nicht aber' setTimeout' funktioniert einwandfrei. Irgendeine Idee warum? –

+0

@MuhammadRaihanMuhaimin sollte im Prinzip gleich sein, der einzige Unterschied ist, dass setTimeout einen Timeout-Wert (> = 4 ms) benötigt. Bei älteren Browsern benötigen Sie möglicherweise einen Polyfill für rquestAnimationFrame. – K3N

+1

@ K3N Ich verwende Chrom. Wenn ich die Zeitlimitvariable entferne und sie durch window.requestAnimationFrame ersetze, hört sie auf zu arbeiten, bis die Schleife beendet ist. –

0

Haben Sie versucht, zuerst das Bild zu laden und dann zu zeichnen?

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

Ja, ich befolgte den obigen Ansatz, aber das funktioniert nicht –

+0

Haben Sie mit 'requestAnimationFrame' versucht? –

+0

Die 'for' Schleife ist zu schnell, sollten Sie Methoden für das Zeichnen, wie 'setinterval' oder 'requestAnimationFrame' verwenden https://developer.mozilla.org/es/docs/Web/API/Window/requestAnimationFrame –