2013-12-05 4 views
1

У меня есть массив объектов изображения, которые содержат всю необходимую информацию, такую ​​как path, x, y, w, h. Теперь я хочу нарисовать все эти изображения на холсте в цикле. Но когда я это делаю, он рисует только первое изображение. Вот код:drawImage в JavaScript (Canvas)

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); 
     } 
    } 
} 

я проверил все данные в массиве формы ... внутри если условие, перед вызовом функции DrawImage, вся информация о каждом изображении является правильным, но по какой-то странной причине, что Безразлично» t отображает изображения, кроме «последнего» в массиве (тот, который всплывает последним)

+0

Может ли быть, что все изображения накладываются друг на друга? Вы добавляете все изображения в один холст. Вы проверили значения x и y для каждого изображения? – Poornima

+0

Yup, x и ys разные для каждого изображения ... –

ответ

0

Это была проблема какого-то закрытия ... вроде бы, цикл заканчивается перед загрузкой изображений или чем-то еще. Решение, которое сработало для меня, заключалось в том, чтобы поместить весь код загрузки изображения в отдельную функцию и вызвать эту функцию из цикла:

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

Возможно, вы могли бы подумать о том, чтобы дать markE несколько преимуществ за то, что вы привели к решению, которое вы нашли, выбирая/принимая его ответ. Также ознакомьтесь с моим загрузчиком изображений [YAIL] (https://github.com/AbdiasSoftware/YAIL-imageLoader-for-JavaScript). :-) – K3N

+0

oopsie ... done (: sorry im new на этом сайте, так что не знал об этом .. –

+0

Не беспокойтесь, мы все начали здесь свежими в какой-то момент :) – K3N

0

Я не понимаю, почему вы используете pop() для получения данных объекта. Вы могли бы вместо того, чтобы получить доступ к каждому объекту с помощью фигур [I] обозначения и, в качестве бонуса, хранить изображения ручки в каждом объекте:

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

Да, это полезно, но это не проблема ... если есть 3 изображения, цикл будет выполняться 3 раза, и будет отображаться только одно изображение. В этом и заключается проблема. –

+0

В этом случае MarkE, вероятно, имеет правильную причину того, что пойдет не так ... – KaliedaRik

+0

yea .. но что может быть решением этой проблемы? –

3

Ваша загрузка изображений код неисправности.

Для каждого изображения потребуется время для загрузки, и к тому времени вы перезаписали var img другим новым Image();

Вот пример загрузчика изображений, который выполняет только после того, как все изображения были загружены и готовы сделать:

[Warning: непроверенный код - некоторые корректировки могут быть необходимы! ]

// 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); 
    } 

} 
+0

Да, это похоже на проблему. Есть ли у вас какие-либо предложения о том, как заставить цикл ждать до того, как изображение завершит загрузку? –

+0

Несомненно. Я добавил пример кода в свой ответ. – markE

+0

Я вообще не понял, что происходит в этом коде: X –

Смежные вопросы