Cap.Alvez
Cap.Alvez

Reputation: 1373

can't load images correctly in javascript

I am doing an image search program using javascript. I type in a name and, by using a xml database, it retrieves the source of the images which are related to that name to be drawn in the canvas.

But the problem is: After the images are drawn, I need to store the properties of every image in order to recognize the region when I click over the canvas, so I can open a new window with the original-sized image.

If I use the img.onload function it only loads the same image over and over again:

function paint(arrImg){
        //the arrImg is an array with the sources of the images
        var w = canvas.width, h = canvas.height, x = 0, y = 0, dw = 300, dh = 300, i, t, r, count = arrImg.length;
         imageRegions = [];

        for(i = 0; i < count; i++) {
            var img = new Image();
            img.onload = function(){
                ctx.drawImage(img, x, y, dw, dh);

                imageRegions.push({image: img, x:x, y:y, width:dw, height:dh});

                x += dw+10;

                if (x >= w) {
                    x = 0;
                    y += dh+10;
                }
            }
            img.src = arrImg[i];
        }
    }

And if I ignore the img.onload function it only draws if I refresh the page after the search, but the images are all there correctly.

I know this might not be necessary but just in case here is the rest of the related code:

var canvas = document.querySelector("canvas");
    var ctx=canvas.getContext("2d");
    //arrImg store the sources of images found
    var arrImg = [];
    //global var
    var imageRegions;

    var localStorageRow = localStorage.getItem(localStorage.key(i)) ;

    var author_query = getUrlVars()["txtA"];

    if (typeof(author_query) == "undefined" || author_query === "" )
    {
    }
    else {
        for ( var i = 0 ; i < localStorage.length;  i++)
        {
            var localStorageRow = localStorage.getItem(localStorage.key(i));
            //document.write(localStorageRow);
            if (window.DOMParser)
            {
                var parser=new DOMParser();
                xmlDoc=parser.parseFromString(localStorageRow,"text/xml");      //text/xml

            }

            else // Internet Explorer
            {
                xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
                xmlDoc.async=false;
                xmlDoc.loadXML(localStorageRow);
            }

            for ( var k = 0 ; k < xmlDoc.firstChild.childNodes.length ; k++ )
            {
                if ( xmlDoc.firstChild.childNodes[k].nodeName === "title" )
                {
                    //document.write(xmlDoc.firstChild.childNodes[k].textContent);
                    var auth_row = xmlDoc.firstChild.childNodes[k].textContent;
                    var authMatch = auth_row.match(new RegExp(author_query, "i"));

                    if ( authMatch )
                    {

                        for ( var p = 0 ; p < xmlDoc.firstChild.childNodes.length ; p ++ )
                        {
                            if ( xmlDoc.firstChild.childNodes[p].nodeName == 'path' )
                            {

                                document.getElementById("results_ID").innerHTML += xmlDoc.firstChild.childNodes[p].textContent+"<br />";

                                var src = xmlDoc.firstChild.childNodes[p].textContent;

                                arrImg.push(src);

                            }
                        }
                    }
                }
            }
        }

        //resize the canvas for the number of images
        resizeCanvas(arrImg.length);
        //draw the images
        paint(arrImg);

    }


    function paint(arrImg){
        var w = canvas.width, h = canvas.height, x = 0, y = 0, dw = 300, dh = 300, i, t, r, count = arrImg.length;
         imageRegions = [];

        for(i = 0; i < count; i++) {
            var img = new Image();
            img.src = arrImg[i];
            img.onload = function(){
                ctx.drawImage(img, x, y, dw, dh);

                imageRegions.push({image: img, x:x, y:y, width:dw, height:dh});

                x += dw+10;

                if (x >= w) {
                    x = 0;
                    y += dh+10;
                }
            }
        }
    }

    //if I click over the image displays the original image in another window
    canvas.onclick = function(e) {

        /// adjust coordinates to be relative to canvas
        var rect = canvas.getBoundingClientRect(),
                x = e.clientX - rect.left,
                y = Math.round(e.clientY - rect.top),
                i, r;

        for(i = 0; r = imageRegions[i]; i++) {

            /// image detected? 
            if (x > r.x && x < r.x + r.width &&  y > r.y && y < r.y + r.height) {

                window.open(r.image.src, r.image);
                return;
            }
        }
    }

Thanks in advance.

Upvotes: 1

Views: 1290

Answers (1)

Delta
Delta

Reputation: 4328

Inside of the onload event, do not refer to the img variable directly, instead, use this

That means, replace these lines:

ctx.drawImage(img, x, y, dw, dh);    
imageRegions.push({image: img, x:x, y:y, width:dw, height:dh});

With these:

ctx.drawImage(this, x, y, dw, dh);
imageRegions.push({image: this, x:x, y:y, width:dw, height:dh});

http://jsfiddle.net/BEbWX/1/

Upvotes: 1

Related Questions