I have two php files - index.php and loadimages.php.
The index page has a thumbnail gallery and a canvas. The images to thumbnail gallery is populated through loadimages.php. The following is the snippet of the code from loadimages.php:
for ($i=0; $i<count($files); $i++)
{
$num = $files[$i];
$filname = basename($num, ".jpg");
$filnam = substr($filname, -5);
echo '<figure class="item">';
echo '<img class="matchImages" onclick="clickedImage(this.id)" src="'.$num.'" id="thumbNails' . $filnam . ' "/>';
}
The above php code also has an onclick function clickedImage. In the index.php, i have this function which is as follows:
function clickedImage(clicked_id) {
localStorage.setItem("clickedImg", clicked_id);
var clickedImg = document.getElementById(clicked_id).src;
var clickedImg = clickedImg.replace(/^.*[\\\/]/, '');
var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
var thumbNails = document.getElementById("loaded_img_panel");
var pic = new Image();
pic.onload = function() {
canvas.width = pic.width;
canvas.height = pic.height;
ctx.drawImage(pic, 0,0)
}
thumbNails.addEventListener('click', function(event) {
pic.src = event.target.src;
});
}
The above code works without any errors. I want to build in a functionality where when the page is refreshed, I want to virtually click on the last clicked image so that the user stays on the same image before reload. I have created a eventlistener for this which is as follows:
window.addEventListener('load', function() {
var clickedImage = localStorage.getItem('clickedImg');
clickedImage(clickedImage);
})
This is not working, and the console returns Uncaught TypeError: clickedImage is not a function.
Both your function and your variable are named clickedImage:
var clickedImage = localStorage.getItem('clickedImg');
clickedImage(clickedImage);
Rename the variable to something else (e.g. clickedImageValue) and you should be good to go.
The problem you experience here is called variable shadowing, by the way.
Ok...I figured out the issue and posting this answer for completion sake and help someone who may need an answer. The problem in my code was in this line within my js:
thumbNails.addEventListener('click', function(event) {
pic.src = event.target.src;
});
Because I was invoking a click event within my function, the window.addEventListener is waiting for that click to happen. When I changed my code to this:
var clkImg = localStorage.getItem('clickedImage');
var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
var thumbNails = document.getElementById("loaded_img_panel");
var pic = new Image();
pic.onload = function() {
canvas.width = pic.width;
canvas.height = pic.height;
ctx.drawImage(pic, 0,0)
}
pic.src = clkImg;
everything started working fine.
I have a slider that starts at click on button and I want every image to be loaded at a offset of 200 px in comparison with the previous one. Here is the code:
var image1 = new Image()
image1.src = "img0.jpg"
var image2 = new Image()
image2.src = "img1.jpg"
var image3 = new Image()
image3.src = "img2.jpg"
var image4 = new Image()
image4.src = "img3.jpg"
var image5 = new Image()
image5.src = "img4.jpg"
var step = 1
function slideit() {
document.images.slide.src = eval("image" + step + ".src")
if (step < 5)
step++
else
step = 1
setTimeout("slideit()", 500)
}
<button onclick="slideit()">Try it</button>
<img src="img0.jpg" name="slide" width="100" height="100" position = "absolute">
I'd like to do this in JavaScript as I do not want to use jQuery in my code.
I actually don't get whats your question. Maybe you should be a bit more precise.
If you want to make a picture slider, then your approach doesn't seems to be right.
Hey this should work for you. I didn't had time to check it, so I hope there are no mistakes in it.
Just update the JS, you can leave the html.
Regards
var images = [
'image1.jpg',
'Image2.jpg',
'...'
];
function slideit()
{
var index = 0;
var container = document.getElementById('yourContainer');
var addPic = function()
{
var img = document.createElement('img');
img.src = images[index];
img.style.position = 'absolute';
img.style.left = index * 200 + 'px';
container.appendChild(img);
index++;
}
setInterval(addPic, 1000);
}
The code:
function CreateAndAnimateEnemyImg() {
var enemy = new Image();
enemy.src = 'enemy.jpg';
enemy.class = 'Enemy';
enemy.width = '30px';
enemy.height = '30px';
document.body.appendChild(enemy);
enemy.onload = function () {
alert('2. Image has fully loaded.');
$('.Enemy').animate({ 'right': '+=20px' });
}
}
$("#Start").click(function () {
CreateAndAnimateEnemyImg();
});
The weird behavior is that the alert is raised but no image is shown, nor the animation is working. Any help please?
Change your code:
enemy.className = 'Enemy';
enemy.width = '30'; // no px needed
enemy.height = '30';
http://jsfiddle.net/UqcqN/
You have two mistakes: if you set width property you don't have to provide units. And you should set className property instead of class.
It is also recommended to set src after onload handler.
You have to enemy.src = 'enemy.jpg'; AFTER you define: enemy.onload.
i think no need for giving string kind of 'px';
rtefer this http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_img_height
here is the complete demo Fiddle
function CreateAndAnimateEnemyImg() {
var enemy = new Image();
enemy.src = 'http://media.steampowered.com/apps/440/icons/icon_dueling_large.14fd9f2da0f24b2dfaac37d1600c821ddb6d3456.png';
enemy.class = 'Enemy';
enemy.width = '130';
enemy.height = '130';
document.body.appendChild(enemy);
enemy.onload = function () {
alert('2. Image has fully loaded.');
$('.Enemy').html(enemy);
console.log(enemy);
$('.Enemy').animate({ 'right': '+=20px' });
}
}
$("#Start").click(function () {
CreateAndAnimateEnemyImg();
});
I can't seem to figure out why this isn't working. I just have two simple functions: one that loads the image into an img node, and one that pluses an i variable. The second function fires after a timer event, + the count, and then fires the image() function again. Except it's not working.
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//XML Loaded, create the slideshow
alert(xmlhttp.responseText);
var slideShow = document.getElementById('slideShow');
var items = [];
var nl = xmlhttp.responseXML.getElementsByTagName('image');
var i = 0;
var t;
function image() {
var slideShowImg = document.getElementById('slideShowImg');
var nli = nl.item(i);
var src = nli.getAttribute('src').toString();
var width = parseInt(nli.getAttribute('width').toString());
var height = parseInt(nli.getAttribute('height').toString());
var imgNode = document.createElement('img');
imgNode.setAttribute('src', src);
imgNode.setAttribute('height', height);
imgNode.setAttribute('width', width);
slideShowImg.appendChild(imgNode);
t = setTimeout("nextImage()", 5000);
}
function nextImage() {
i++;
image();
}
image();
}
This line looks very suspicious:
t = setTimeout("nextImage()", 5000);
Try this instead:
t = setTimeout(nextImage, 5000);
Move the function definitions out of the if statement.
I've got a little problem here. I've been trying to do an image gallery with JavaScript but there's something that I got a problem with. I can get the image to resize when the first image load, but as soon as I load another image, it won't resize anymore! Since the user will be able to upload a lot of different size pictures, I really need to make it work.
I've checked for ready-to-use image gallery and such and nothing was doing what I need to do.
Here's my javascript:
function changeCurrentImage(conteneur)
{
var img = conteneur.getElementsByTagName("img");
var imgUrl = img[0].src;
var imgFirstPart = imgUrl.substring(0, imgUrl.lastIndexOf('.') - 9);
var imgLastPart = imgUrl.substring(imgUrl.lastIndexOf('.'));
var currentImg = document.getElementById('currentImage');
currentImg.src = imgFirstPart + "borne" + imgLastPart;
resize(document.getElementById('currentImage'), 375, 655);
}
function resize(img, maxh, maxw) {
var ratio = maxh/maxw;
if (img.height/img.width > ratio){
// height is the problem
if (img.height > maxh){
img.width = Math.round(img.width*(maxh/img.height));
img.height = maxh;
}
} else {
// width is the problem
if (img.width > maxw){
img.height = Math.round(img.height*(maxw/img.width));
img.width = maxw;
}
}
};
Here's the HTML (using ASP.Net Repeater):
<asp:Repeater ID="rptImages" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<a href="#">
<div id="thumbnailImageContainer1" onclick="changeCurrentImage(this)">
<div id="thumbnailImageContainer2">
<img id="thumbnailImage" src="<%# SiteUrl + Eval("ImageThumbnailPath")%>?rn=<%=Random()%>" alt="Photo" onload="resize(this, 60, 105)" />
</div>
</div>
</a>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
Most likely the image is not yet downloaded so img.height and img.width are not yet there. Technically you don't need to wait till the whole image is downloaded, you can poll the image in a timer until width and height are non-zero. This sounds messy but can be done nicely if you take the time to do it right. (I have an ImageLoader utility I made for this purpose....has only one timer even if it is handling multiple images at once, and calls a callback function when it has the sizes) I have to disagree with Marcel....client side works great for this sort of thing, and can work even if the images are from a source other than your server.
Edit: add ImageLoader utility:
var ImageLoader = {
maxChecks: 1000,
list: [],
intervalHandle : null,
loadImage : function (callback, url, userdata) {
var img = new Image ();
img.src = url;
if (img.width && img.height) {
callback (img.width, img.height, url, 0, userdata);
}
else {
var obj = {image: img, url: url, callback: callback,
checks: 1, userdata: userdata};
var i;
for (i=0; i < this.list.length; i++) {
if (this.list[i] == null)
break;
}
this.list[i] = obj;
if (!this.intervalHandle)
this.intervalHandle = setInterval(this.interval, 30);
}
},
// called by setInterval
interval : function () {
var count = 0;
var list = ImageLoader.list, item;
for (var i=0; i<list.length; i++) {
item = list[i];
if (item != null) {
if (item.image.width && item.image.height) {
item.callback (item.image.width, item.image.height,
item.url, item.checks, item.userdata);
ImageLoader.list[i] = null;
}
else if (item.checks > ImageLoader.maxChecks) {
item.callback (0, 0, item.url, item.checks, item.userdata);
ImageLoader.list[i] = null;
}
else {
count++;
item.checks++;
}
}
}
if (count == 0) {
ImageLoader.list = [];
clearInterval (ImageLoader.intervalHandle);
delete ImageLoader.intervalHandle;
}
}
};
Example usage:
var callback = function (width, height, url, checks, userdata) {
// show stuff in the title
document.title = "w: " + width + ", h:" + height +
", url:" + url + ", checks:" + checks + ", userdata: " + userdata;
var img = document.createElement("IMG");
img.src = url;
// size it to be 100 px wide, and the correct
// height for its aspect ratio
img.style.width = "100px";
img.style.height = ((height/width)*100) + "px";
document.body.appendChild (img);
};
ImageLoader.loadImage (callback,
"http://upload.wikimedia.org/wikipedia/commons/thumb/" +
"1/19/Caerulea3_crop.jpg/800px-Caerulea3_crop.jpg", 1);
ImageLoader.loadImage (callback,
"http://upload.wikimedia.org/wikipedia/commons/thumb/" +
"8/85/Calliphora_sp_Portrait.jpg/402px-Calliphora_sp_Portrait.jpg", 2);
With the way you have your code setup, I would try and call your resize function from an onload event.
function resize() {
var img = document.getElementById('currentImage');
var maxh = 375;
var maxw = 655;
var ratio = maxh/maxw;
if (img.height/img.width > ratio){
// height is the problem
if (img.height > maxh){
img.width = Math.round(img.width*(maxh/img.height));
img.height = maxh;
}
} else {
// width is the problem
if (img.width > maxw){
img.height = Math.round(img.height*(maxw/img.width));
img.width = maxw;
}
}
};
function changeCurrentImage(conteneur)
{
var img = conteneur.getElementsByTagName("img");
img.onload = resize;
var imgUrl = img[0].src;
var imgFirstPart = imgUrl.substring(0, imgUrl.lastIndexOf('.') - 9);
var imgLastPart = imgUrl.substring(imgUrl.lastIndexOf('.'));
var currentImg = document.getElementById('currentImage');
currentImg.src = imgFirstPart + "borne" + imgLastPart;
}
I would play around with that. Maybe use global variables for your maxH/W and image ID(s);
#Comments: No, I can't do that server side since it would refresh the page everytime someone click on a new image. That would be way too bothersome and annoying for the users.
As for the thumbnails, those image are already saved in the appropriate size. Only the big image that shows is about 33% of its size. Since we already have 3 images PER uploaded images, I didn't want to upload a 4th one for each upload, that would take too much server space!
As for the "currentImage", I forgot to add it, so that might be helful lol:
<div id="currentImageContainer">
<div id="currentImageContainer1">
<div id="currentImageContainer2">
<img id="currentImage" src="#" alt="" onload="resize(this, 375, 655)" />
</div>
</div>
</div>
#rob: I'll try the ImageLoader class, that might do the trick.
I found an alternative that is working really well. Instead of changing that IMG width and height, I delete it and create a new one:
function changeCurrentImage(conteneur)
{
var thumbnailImg = conteneur.getElementsByTagName("img");
var thumbnailImgUrl = thumbnailImg[0].src;
var newImgUrl = thumbnailImgUrl.replace("thumbnail", "borne");
var currentImgDiv = document.getElementById('currentImageContainer2');
var currentImg = currentImgDiv.getElementById("currentImage");
if (currentImg != null)
{
currentImgDiv.removeChild(currentImg);
}
var newImg = document.createElement("img");
newImageDiv = document.getElementById('currentImageContainer2');
newImg.id = "currentImage";
newImg.onload = function() {
Resize(newImg, 375, 655);
newImageDiv.appendChild(newImg);
}
newImg.src = newImgUrl;
}
Also, in case people wonder, you MUST put the .onload before the .src when assigning an a new source for an image!