Ich habe eine Reihe von Bildobjekten, die alle notwendigen Informationen wie Pfad, x, y, w, h enthalten. Jetzt möchte ich all diese Bilder in einer Schleife auf Leinwand zeichnen. Aber wenn ich das tue, zeichnet es nur das erste Bild. Hier ist der Code:

for(var i=0; i<shapes.length; i++)
{
    var A = shapes.pop();
    if(A.name == 'image' && A.pageNum == pNum)
    {
        var img = new Image();
        img.src = A.path;
        img.onload = function() {
            context.drawImage(img, A.x, A.y, A.w, A.h); 
        }
    }
}

Ich habe alle Informationen im Shapes-Array überprüft ... innerhalb der if-Bedingung, bevor ich die drawImage-Funktion aufrufe, sind alle Informationen jedes Bildes korrekt, aber aus irgendeinem seltsamen Grund werden keine Bilder außer dem 'letzten' im Array angezeigt ( derjenige, der zuletzt herausspringt)

1
Abdul Jabbar 5 Dez. 2013 im 23:19

3 Antworten

Beste Antwort

Es war das Problem einer Art Schließung ... wie das Beenden der Schleife, bevor Bilder geladen wurden oder so. Die Lösung, die für mich funktioniert hat, bestand darin, den gesamten Bildladecode in eine separate Funktion zu stellen und diese Funktion aus der Schleife aufzurufen:

if(A.name == 'image' && A.pageNum == pNum)
{
    displayImage(A.path, A.x, A.y, A.w, A.h);

}
function displayImage(path, x, y, w, h)
{
    var img = new Image();
    img.src = path;

    img.onload = function() {
        context.drawImage(img, x, y, w, h);
    }
}
0
Abdul Jabbar 5 Dez. 2013 im 21:05

Ich verstehe nicht, warum Sie pop () verwenden, um Ihre Objektdaten abzurufen. Sie können stattdessen mit der Shapes [i] -Notation auf jedes Objekt zugreifen und als Bonus Bildhandles in jedem Objekt speichern:

for(var i=0; i<shapes.length; i++)
{
    if(shapes[i].name == 'image' && shapes[i].pageNum == pNum)
    {
        shapes[i].img = new Image();
        shapes[i].img.src = shapes[i].path;
        shapes[i].img.onload = function() {
            context.drawImage(shapes[i].img, shapes[i].x, shapes[i].y, shapes[i].w, shapes[i].h); 
        }
    }
}
0
Doulat Khan 26 Juli 2017 im 13:10

Ihr Bildladecode ist fehlerhaft.

Das Laden jedes Bildes dauert einige Zeit. Bis dahin haben Sie var img mit einem anderen neuen Bild () überschrieben.

Hier ist ein Beispiel für einen Bildlader, der erst ausgeführt wird, nachdem alle Bilder geladen wurden und zum Zeichnen bereit sind:

[Warnung: ungetesteter Code - möglicherweise sind einige Anpassungen erforderlich! ]]

// image loader

var imageURLs=[];  // put the paths to your images in this array
var imagesOK=0;
var imgs=[];
imageURLs.push("");
loadAllImages(start);

function loadAllImages(callback){
    for (var i=0; i<imageURLs.length; i++) {
        var img = new Image();
        imgs.push(img);
        img.onload = function(){ 
            imagesOK++; 
            if (imagesOK>=imageURLs.length ) {
                callback();
            }
        };
        img.onerror=function(){alert("image load failed");} 
        img.crossOrigin="anonymous";
        img.src = imageURLs[i];

        // note: instead of this last line, you can probably use img.src=shapes[i].path;
    }      
}

function start(){

    // the imgs[] array holds fully loaded images
    // the imgs[] are in the same order as imageURLs[]

    for(var i=0;i<shapes.length;i++){
        var shape=shapes[i];
        context.drawImage(imgs[i],shape.x,shape.y,shape.w,shape.h);
    }

}
3
markE 5 Dez. 2013 im 20:20