简体   繁体   English

JavaScript中的drawImage(Canvas)

[英]drawImage in JavaScript (Canvas)

I have an array of image objects which hold all the necessary info like path,x, y, w, h. 我有一个图像对象数组,其中包含所有必要的信息,如路径,x,y,w,h。 Now i want to draw all those images on canvas in a loop.. but when i do so, it only draws the first image. 现在我想在一个循环中在画布上绘制所有这些图像..但是当我这样做时,它只绘制第一个图像。 Here is the 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); 
        }
    }
}

i checked all the info in the shapes array... inside the if condition, before calling drawImage function, all the info of each image is correct but for some strange reason it doesn't display images except the 'last' in the array (the one which pops out last) 我检查了形状数组中的所有信息...在if条件内,在调用drawImage函数之前,每个图像的所有信息都是正确的但是由于某些奇怪的原因它不显示除了数组中的'last'之外的图像(最后弹出的那个)

Your image loading code is faulty. 您的图像加载代码有问题。

Each image will take time to load and by then you have overwritten var img with another new Image(); 每个图像都需要一些时间来加载,然后你用另一个新的Image()覆盖var img;

Here's an example of an image loader that executes only after all the images have been loaded and are ready to be drawn: 这是一个图像加载器的示例,只有在所有图像都已加载并准备好绘制之后才会执行:

[ Warning: untested code -- some adjustments may be required! [警告:未经测试的代码 - 可能需要进行一些调整! ] ]

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

}

I don't understand why you're using pop() to get your object data. 我不明白为什么你使用pop()来获取你的对象数据。 You could instead access each object using shapes[i] notation and, as a bonus, store image handles in each object: 您可以使用shapes [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); 
        }
    }
}

It was the problem of some sort of closure... like, the loop finishing before images getting loaded or something. 这是某种关闭的问题......比如,在图像加载之前完成循环或其他什么。 The solution that worked for me was putting all the image loading code in a separate function and calling that function from the loop: 对我有用的解决方案是将所有图像加载代码放在一个单独的函数中并从循环中调用该函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM