Javascript Slideshow Code

I prefer writing all my web-design code from scratch. So I use only text editors to write HTML directly, and raw JavaScript (no jQuery etc). While working on a javascript slideshow for Artarium, I came across a lot of problems in transitioning the images. My javascript was changing the src for the image, but I needed to also resize it to the dimensions of the new image before displaying it. Finally, after a lot of time, effort and fruitless migrations to online tutorials and troubleshooters, I came up with the exact configuration that works. On a transition the image disappears, resizes, then reappears. In between this, if the next image takes too long to load, you could display some loading animation, as I did. Just put an animated gif there permanently with a lower z-index than the photo. This will cause it to show between transitions. For the transitions itself you could use a CSS3 transition of opacity as I did and not have to worry about further code for transition effects.

Here is the JavaScript code with some explanatory comments. I have added a preloading function and keyboard navigation. I have not explained everything in detail as I have assumed the user will have standard web-designing experience, in which case this should very well suffice.

JavaScript:

function keyNavigate(e) //to enable slideshow navigation using right and left arrow keys
{
    if(e.which==39)
         pre_next();
    else if (e.which==37)
        pre_previous();
}

var i=0,imax=n; //put the # of slideshow images as n here

function imagearray() //prepares things on page load and starts preloading images
{
    preloader=new Image()
    var j=0;
    captions = new Array();
    captions = ['caption1', 'caption2', ... 'caption n'];
    document.photo.src="directory/photo1.jpg"; //assumes photos are in 'directory'
    document.getElementById('navigation-count').innerHTML="0/"+(imax); //sets slide number
    for(j=1; j    {
        filename="directory/photo"+j+".jpg"; //assumes photos are 'photo1.jpg', 'photo2.jpg' etc
        preloader.src=filename;
    }
}

var imgHeight;
var imgWidth;
var newImg;

function resize() //to resize as image changes
{
    imgHeight = this.height;
    imgWidth = this.width;
    if (imgWidth/imgHeight < 2.25) //any desired criterion
    {
        document.photo.style.height='355px'; //or whatever else
    }
    else
    {
        document.photo.style.width="95%";
    }
    document.photo.style.opacity=1; //photo appears only after it has been resized
    document.getElementById('caption').innerHTML=captions[i-1]; //caption changes
    document.getElementById('caption').style.opacity=1; //caption appears
    document.getElementById('navigation-count').innerHTML=(i)+"/"+(imax); //slide count changes
    return true;
}

function pre_next() //to ensure resizing occurs after picture disappears
{
    document.photo.style.opacity=0;
    document.getElementById('caption').style.opacity=0;
    setTimeout("next()",500);
}

function next()
{
    if (i==imax)
    {i=0;}
    i++;
    newImg=new Image();
    newImg.src="directory/photo"+i+".jpg";
    document.photo.src=newImg.src;
    newImg.onload = resize; //resize function is called
}

function pre_previous()
{
    document.photo.style.opacity=0;
    document.getElementById('caption').style.opacity=0;
    setTimeout("previous()",500);
}

function previous()
{
    if (i==1)
    {i=imax+1;}
    i--;
    newImg=new Image();
    newImg.src="directory/photo"+i+".jpg";
    document.photo.src=newImg.src;
    newImg.onload = resize;
}

This JavaScript alone does not suffice. Here’s some things you need to do with the HTML for this to work:

  1. The image element which changes in the slideshow should have a name=”photo” attribute (used on line 17 etc. of the JavaScript).
  2. Add <body onload = “imagearray(), next()”  onkeydown=”keyNavigate(event)”>  to the HTML body. The next() is required to display the first photo and initialize the caption and slide count.
  3. The slide transition occurs by pre_next() and pre_previous() functions. So any event that you want will trigger a transition should call these functions (as used in the keyboard navigation part), not next() or previous().
  4. The ‘caption’ div in the HTML holds the caption, while the ‘navigation-count’ div holds the slide number. Place them as you require.

You can find this code at work in any gallery at Artarium, unless I change it in the future. If you hit a block using this code, there’s nothing a couple of Google searches won’t clear for you. If there’s a problem that persists even after you have done your research thoroughly, leave a comment (be specific) with your e-mail and I promise to try to help.

Simplest Javascript Fade Animation

[UPDATE: There’s now a much better (shorter, cleaner, more modern) solution than using Javascript to fade elements in and out. Add a CSS3 transition property (tutorial here) to the elements you want to fade, then use Javascript only to set the opacity to the changed value. The transition will happen by itself. Although yes, the CSS3 sets a single fixed transition duration. If you want the fade animation on the same element occurring for different durations at different times, this code is still the only way out.]

I needed a simple code for Javascript fade animation, i.e. fading in and out of HTML elements, but couldn’t find online exactly what I wanted. Borrowing on the fundamental animation mechanism from this page, which is the closest I got, I wrote my own short code. It works in all major browsers (Chrome, Firefox, Opera, Safari, IE). The same code works for both fading in and out, from whatever initial opacity value to whatever final value, depending on the arguments of the function. In the code, the arguments you can specify are the following: eid is the id of the HTML element you wish to run the fade on. The fade goes from the initial CSS opacity value initOp to the final value finalOp in time TimeToFade measured in milliseconds. You don’t have to specify the last parameter, time, which you’ll see if you look at the HTML that I’ve shown afterwards.

Javascript

function fade(eid, initOp, finalOp, TimeToFade, time)
{
	if (initOp==0)
	{
		document.getElementById(eid).style.visibility="visible";
	}
	var curTick = new Date().getTime();
	var elapsedTicks = curTick - time;
	var newOp = initOp+(finalOp-initOp)*elapsedTicks/TimeToFade;
	if (Math.abs(newOp-initOp)&gt;Math.abs(finalOp-initOp))
	{
		document.getElementById(eid).style.opacity=finalOp;
		if (finalOp==0)
		{
			document.getElementById(eid).style.visibility="hidden"
		}
		return;
	}
	document.getElementById(eid).style.opacity=newOp;
	setTimeout("fade( '" + eid + "'," + initOp + "," + finalOp + "," + TimeToFade + "," + time + ")", TimeToFade/100);
}

HTML

<div id="box">;
<input type="button" onclick="fade('box', 1, 0.3, 5000, new Date().getTime())" value="Fade"/>;
</div>

If you choose your element to be a div, all child elements in the div also fade. In the HTML, put the last argument of the function exactly as given. On clicking the button, this example fades out the box div from an opacity value of 1 to 0.3. If you fade it from 0.2 to 0.8, let’s say, it will fade in. Usually you would require to set initOp to whatever was the element’s opacity at the time you start the animation, but in general you could set it to something different, in which case the opacity of the element will sharply change to initOp the moment the animation function is called, then start its transition to finalOp.

I can’t include an example in this WordPress blog, but you can see this code in action in multiple fade animations at my homepage. [EDIT: Now I don’t use my code any more; I use the CSS3 transition like I mentioned.]

If you look at the Javascript again, you’ll see that the fade() function calls itself via the setTimeout() in the last line. The setTimeout delay has been chosen as 1/100th of the duration of your fade animation. You could also set this as a fixed number in milliseconds.  This delay does not determine the duration of the animation, only how many times fade() manages to run in that duration and the opacity value is updated. The shorter this delay, the smoother the fade animation; the longer, the choppier. It may however not always be a good idea to set it as something very small like 1 ms, say for long, slow fades, for which the fast, repeated computations for miniscule opacity changes are usually unnecessary.

Want to learn HTML? Design a website!

The quote went something like the following: ‘The best way to teach yourself something is to write a book about it.’ I found out the truth of this statement over the past few days, when I was designing the Inquivesta 2011 website.

A week back, I knew more about shearing sheep than I did about writing HTML and CSS.

Today I am more or less familiar with both, and I rather like doing it. It is, of course, difficult to sit down to design a website without having had any sort of training, formal or informal, in HTML or CSS. But one wonderful thing about this approach is that you learn fastest this way. Yes, there remain loopholes and gaps in the thoery and understanding, but the fact that you change the code and continously check how it affects the result is a quick and interesting way to learn the code. If you go for a class of Web Designing, it’ll be boring. It’s the same way with drums. I found out that playing the lessons and studying the notation was boring. Of course, it’s important for a solid grounding, but it requires patience, which everyone seems to be running out of these days. Instead, you think of a pattern and try to pick it up, jam with some friends, have fun, it’s great that way. It’s just like health food doesn’t taste great, but junk food is heaven.

Debsankha, who is also part of our Design Team, once came up with the idea of learning French by watching Frenchmovies with English subtitles. It’s the same attitude. But now you see why it’s not health food: you learn it quick, but you don’t learn it well. Anyway, I guess he dropped the idea because foreign movies are hard to find. But an idea just struck me: why didn’t he just watch English movies with French subtitles?

Anyway, some crap monkey in the system is blocking the website that provides the hit counter for the Inquivesta website, so that’s a bit irritating.

It’s taking up a lot of my time, this Inquivesta. Sure, I’m learning stuff. I learnt to design documents and brochures, and HTML and CSS, and now I’m indulging in a bit of Webmaster tools, but it’s pushing out the other stuff that I must do for the grades. I keep recalling the Stay Hungry, Stay Foolish speech, but I know inside that it’s not going to help me when my Karma comes around.