Rotating images using jQuery Ajax

There are many ways to rotate images on a website.  In my case, I needed a way to rotate all images from a particular folder, and I wanted it so that I just have to dump images in the folder in order for the slideshow to pick them up.  ** NOTE: if you want a more advanced setup with database driven slides visit my post about database driven slideshows

For this tutorial I'm going to use jQuery's framework and crossSlide, a plugin for jQuery which will allow smooth transitions between the images.  If you don't have it already, you can get jQuery at www.jquery.com and the crossSlide plugin at www.gruppo4.com/~tobia/cross-slide.shtml .  You'll also have to create a folder with images.  You'll get the best result if all images are identical in size.

A working example can be found at duboistechnologies.com .

Download the code here

Ok, first things first: we'll need a placeholder for the images.  We'll need to specify a fixed height for this placeholder too, otherwise the content below will be jumping up and down every time a new image is loaded:

<div id="imgcontainer" style="margin:0; width:46em; height:20em;">
<img src="img/ajax-loader.gif" style="margin-top:20%" alt="loading…" id="mainImg" />
</div>

I put an image in the div that will show an icon while the images are loaded…

Next step is to create a php page with some code to get all images from the folder.   The getfiles function will get all files and return a string that will be formatted so it can be parsed as separate objects by the javascript eval() function… but that's for later.  We just echo this string so our ajax call will pick it up.  The only thing you'll need to customize is the 'imagefolder'… change this to whatever the name or path is to your folder:

<?php

echo getfiles('imagefolder');

function getfiles($folder=", $extensions='.*')
{

// path:
$folder = trim($folder);
$folder = ($folder == ") ? './' : $folder;

// validate folder
if (!is_dir($folder)){ die('invalid folder given!'); }

// create files array
$files = array();

// open directory
if ($dir = @opendir($folder)){

// get all files:
while($file = readdir($dir)){

if (!preg_match('/^\.+$/', $file) and
preg_match('/\.('.$extensions.')$/', $file)){

// feed the array:
$files[] = $file;
}
}
// close directory
closedir($dir);
}
else {
die('Could not open the folder "'.$folder.'"');
}

if (count($files) == 0){
die('No files where found :-( ');
}
// shuffle the array so we have a random sequence of images
shuffle($files);

$return = ";
foreach($files as $file){
// format the string so we can later parse it into objects in javascript
$return .= "{'src':'{$folder}/{$file}'},";
}
$return = "[".substr($return, 0,-1)."]";

// return the string:
return $return;

}

?>

What we need to do now is set up an ajax call that gets the string of images the above function found in my images folder.  We'll also have to include the jquery and crossSlide packages:

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.cross-slide.js"></script>

<script type="text/javascript">
$(document).ready(function(){loadImage();})

function loadImage(){
// getimage.php is the php file that gets my images from the images folder
$.post("getimage.php", function(data){
if(data.length >0) {
// evaluate the string to a group of objects
myObject = eval(data);
// create a slideshow with the image objects and drop them in the placeholder
$('#imgcontainer').crossSlide({sleep:5,fade:2},myObject);
}
});

}
</script>

That's all there is to it.  This is a great alternative to flash and is much less cpu intensive!

Was this post helpful? Buy me a drink :-)

31 thoughts on “Rotating images using jQuery Ajax

  1. Kevin,

    I am just learning PHP and found your code. I want to do something similar on a website, (not on go2cas.com – I didn't create that), but a personal one, so I thought I would try it.

    I have been at it for 3 days – I've downloaded several debuggers, but cannot get the getimages.php file to run – I'm testing on a WAMP server on my laptop. This is the error I get:

    Parse error: parse error, expecting `')" in C:\wamp\www\jquerytest\php\getimage.php on line 5

    I tried typing it in the debugger file one line at a time – on line 5 it wanted a second " – so I put that in. Then the file was fine until I got to the end and it said: Unexpected EOF . Expected variable ${. I was hoping you could shed some light on this – if you can take a minute, I would appreciate it.

    The photos on your site are awesome.

    Regards,
    Mary Ann Gerney

  2. Apparently wordpress (the software this blog is using) transforms my ' and " quotes into italic quotes: “`’” . So if you're copying the code you'll have to do a search/replace for these characters.

  3. How many files did you create for this example(html, php and js)? where did you put them? I think I get most of the exercise, however, I can´t seem to get it working because I think I place de PHP in the wrong place. Could you please clarify this. Thanks.

    Very cool site btw.

  4. I made it!! after a few hours of tinkering (sometimes desperate tinkering, je,je,je), I got it!!!

    I thought the code had some bugs (I can see you corrected those), so I took the liberty of watching the "working code" from your site (via Firefox-Firebug), and basically went comparing from there.

    The thing that had me most was writing the correct path for the images. Basically considering where the Jquery is read and passing down the correct path in the $return.

    Anyway I see billions of possibilities combining this code with Drupal, "CCK" and "VIEWS" modules.

    Thanks for everything, reallly useful stuff.
    Best regards from Costa Rica.
    Miguel

  5. This is just what I have been looking for. Thank you for reading my mind and making such a great tutorial.

    Cheers,

    Matt

  6. Any tips on making this display 3 images in a row from that directory? And being sure not to repeat the same image in the 3 displayed. Or to at least make this work with 3 images each randoming from 1 of 3 image folders?

    Dax

  7. Hey I have one question regarding link to an image. How can I give link to these rotating images?

  8. Alex, If you want to add a link from each slide you'll most likely need to save the image file locations together with a corresponding link into an array or database. That's kind of out of the scope of this tutorial. I did write another slideshow with that functionality, if I have a some time this week I'll post it in another article.

  9. I am also looking out similar kind of functionality, link to rotating images, Kevin can you please let me know whenever you upload the new article.
    Thanks in advance.

  10. Hey,
    Thanks for this slideshow. This is just what I have been looking for.

    Just one thing:
    funktion getfiles has two paramters: $folder and $extensions
    What could stay in $extensions.

    I would need the read out the filename. Is it maybe posibly to read the filename out and put him on the top of the image?

    Thanks in advance.

  11. This is perfect for what I need, except I need to have images resized to fit within a specific size. I can change the box size, but this just crops the images, instead of resizing. Any way to do this?

  12. One more question. It looks like if there are non image files in the folder that has the images, the script fails. Any way to have the script ignore non image files? Maybe just a list extensions that are valid?

  13. @Pingitzer: since we're returning a string of all image paths to ajax it would be hard to parse this. Take a look at the other more advanced slideshow tutorial in my blog (link is at the top of this article), that will probably be more suited.

  14. Austin, resizing the images is kind of out of the scope of this article – you'll want to resize the images before you upload them to the folder. As for filtering only image files out of the folder, you can modify the following line to look for only jpg, gif, png etc in the last 3 characters of the string:
    if (!preg_match('/^\.+$/', $file) and preg_match('/\.('.$extensions.')$/', $file)){

  15. Hi Kevin and thank you for this great script :)

    i have some hard time with it.
    i'm trying to use it in a CMS MS website.

    i did everything well (i thought), i think all my url are good..
    but i have all those errors :

    string(122) "Smarty error: [in tpl_head:24 line 18]: syntax error: unrecognized tag: loadImage(); (Smarty_Compiler.class.php, line 446)" string(111) "Smarty error: [in tpl_head:24 line 18]: syntax error: unrecognized tag " (Smarty_Compiler.class.php, line 590)" string(436) "Smarty error: [in tpl_head:24 line 20]: syntax error: unrecognized tag: // getimage.php is the php file that gets my images from the images folder $.post("getimage.php", function(data){ if(data.length >0) { // evaluate the string to a group of objects myObject = eval(data); // create a slideshow with the image objects and drop them in the placeholder $('#imgcontainer').crossSlide({sleep:5,fade:2 (Smarty_Compiler.class.php, line 446)" string(111) "Smarty error: [in tpl_head:24 line 20]: syntax error: unrecognized tag " (Smarty_Compiler.class.php, line 590)"

    a LOT right? if you have any idea where i can search to fix it.
    Thank you

  16. You may need to give me more information but it sounds like you may need to set your variables in the php and/or the smarty template file. Does that help?

  17. Awesome post, this helped me out A LOT! We've got a webcam here at the museum I work at that's capturing images of the Mississippi River every 15 minutes, and then it FTPs the JPGs onto our webserver. I used a slightly-modified version of this script to put together a page that illustrates the rising water as the river floods – the crossfade plugin is really, really nice!

    Now I'm trying to think of a way to show how the photos relate to each other sequentially so that if you catch part of the slideshow (it's playing on a kiosk here), you'll know where you're at in the series.

    Can you think of a good way to implement something that would count the total number of images in the directory, then output where you're at as it rotates? Like an "Image 3 of 32" line of text that'd dynamically appear with the images? Could I use jQuery for that, or would it be PHP, or some combination of the two? It seems like it'd be simple enough, but I'm having a tough time coming up with a good approach! Any ideas?

    Thanks again for the helpful article!

  18. Hi Sarah, thanks for the nice comment!

    I played around with the code and I think your best option is to hack into the cross-slide.js file a little bit: go to around line 210 where you should find the following:

    if (p.href)
    elm = jQuery(format('<a href="{0}" rel="nofollow"><img src="{1}"/></a>', p.href, p.src));
    else
    elm = jQuery(format('<img src="{0}"/>', p.src));

    Below is the replacement code. The last line is what you're going to need to change. Basically, I added a div wrapper (since the code subsequently looks for the children of the image container, we need to keep the number of elements the same). This wrapper contains the original img code and a new div. This new div will contain your page number. variable i is the loop number starting at 0 so we need to increment that by 1. plan.length is the total number of images in your folder. You're probably going to need to play around with the css of the div a bit more but I think this should get you started:

    if (p.href){
    elm = jQuery(format('<a href="{0}" rel="nofollow"><img src="{1}"/></a>', p.href, p.src));
    }
    else{
    q = i+1;
    elm = jQuery(format('<div><img src="{0}"/><div style="position:relative; background:white; top:-35px;width:500px">image {1} of {2} </div></div>', p.src, q, plan.length));
    }

  19. Awesome – that worked perfectly! I was trying to hack together something similar basing my code on a part of the basic lightbox plugin, which also shows an image counter, and it was just getting messy. And it didn't work.

    If you're interested, you can check out our flood cam here: http://www.sciencebuzz.org/postcards/uploads/phenology/webcam/

    It's a little prettier on our kiosk in the river gallery, so stop by sometime if you're ever in St. Paul!

    Thanks again!

  20. Cool, thanks! got it working right away. One Problem i have:
    It seems, it starts to rotate only after all images are loaded.
    Since I load a lot BIG images, it would be cool if the rotation would start as soon as a 2nd pic is there, and then gradually adds more pic's to the show, as they are downloaded.

  21. 1 steps more :
    if dont have a img to show:

    if(plan.length == 0){
    self.empty().css({
    overflow: 'hidden',
    padding: 0
    });
    return ;
    }

  22. The code works great. Very effective and simple.
    I really need a way to resize the images, at least keep the height constant.
    could you please point me to some code/example I could add to achieve this?

    Thank you so much!

  23. Hey Kevin!
    Awesome job on this script. I tinkered w/ it locally and couldn't get it to work, much to my frustration. Then I uploaded to a test folder and it works flawlessly!
    Awesome job, I love it.
    Quick question. I'd like to use this along w/ Galleria so it can display thumbnails as well that are selectable.
    Is this possible. Could you give me some pointers on where to start. I'll send you the code once I get it working, just need a little kickstart.
    Thanks again!
    Kevin

  24. I love this simple example, I have been looking for something that does this for months. I am having a problem, however, adding it into a current html page. When I change the path for my image folder and load the included .php file by itself, the slideshow works wonderfully: http://oregontrailvet.com/index_files/rotate_images/index.php

    However, when I add it to the sidebar of my page, it never loads correctly. In the chrome debugging console I get the following error on line 40 of the cross-slide script: "container element does not have its own width and height"

    Here is the page I am adding it to: http://oregontrailvet.com/thankyou.html

    Any ideas?

  25. Nevermind, I figured it out. After I defined the measurements as pixels, it started to work. Thanks for this awesome code!

  26. Fantastic goods from you, man. I've understand your stuff previous to and you are just extremely excellent. I actually like what you've acquired here, certainly like what you're stating and the way in which you say it. You make it enjoyable and you still take care of to keep it smart. I cant wait to read far more from you. This is actually a wonderful website.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>