我正在使用 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;
}
}
}
提前致谢。
答案 0 :(得分: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});