1

我正在使用javascript做一个图像搜索程序。我输入一个名称,然后通过使用xml 数据库,它检索与要在画布中绘制的该名称相关的图像的来源。

但问题是:绘制图像后,我需要存储每个图像的属性,以便在我单击画布时识别区域,这样我就可以打开一个带有原始大小图像的新窗口。

如果我使用 img.onload 函数,它只会一遍又一遍地加载相同的图像:

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

如果我忽略 img.onload 函数,它只会在搜索后刷新页面时绘制,但图像都正确存在。

我知道这可能没有必要,但以防万一这里是其余的相关代码:

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

提前致谢。

4

1 回答 1

1

onload事件内部,不要img直接引用变量,而是使用this

这意味着,替换这些行:

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

用这些:

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

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

于 2013-09-06T19:02:18.637 回答