Reputation: 1373
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
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});
Upvotes: 1