Looping images in carousel

Hi all

Demo here - http://www.ttmt.org.uk/slideshow/index-2.html

jsfiddle here - http://jsfiddle.net/VNHWz/

I know there are lots of carousel plugins but none of them do what I want.

I want a responsive image carousel that is the full width of the window.

At the moment I’m having problems getting the images to loop.

I thouhgt I might be able to do it checking the position of the first image and then moving it behind the last image when it’s off the screen

The carousel has 4 images and it looks like it might work when the first image is placed behind the last image but then it just stops.

Is this the best way to do this? Can anyone see where I’m going wrong?


<!DOCTYPE html>
<html lang="en">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />

  <!--jQuery-->
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>

  <!--css-->

  <style type="text/css">
    *{
      margin:0;
      padding:0;
    }
    .carousel{
      overflow:hidden;
      white-space:nowrap;

    }
    .img{
      display:inline;
      position:relative;
      max-width:900px;
      height:auto;
    }
  </style>


  <!--[if lt IE 9]>
	     <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->

  <title>Title of the document</title>
  </head>

<body>

  <section >
		<div class="carousel">
      <div class="img"><img src="images/slide-show-1.jpg" /></div>
      <div class="img"><img src="images/slide-show-2.jpg" /></div>
      <div class="img"><img src="images/slide-show-3.jpg" /></div>
      <div class="img"><img src="images/slide-show-4.jpg" /></div>
    </div>
	</section>
	
  <script>

    function slide(){

      var img = $('.img');
      var firstImg = img.first();
      var lastImg = img.last()
      var firstImagePos = firstImg.position().left;

      img.animate({left:firstImagePos-900});

      //alert('First image is '+$('.img img').first().attr('src') + '\
' + 'And First Image Pos is '+firstImagePos);

      if(firstImagePos < -900){
        firstImg.insertAfter(lastImg);
      }

    }

    setInterval(function() {
      //slide();
    }, 2000);


  </script>

</body>

</html>


I want a responsive image carousel that is the full width of the window.

bxSlider will happily work across the full screen width.

<!DOCTYPE html>
<html lang="en">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />

  <!--jQuery-->

  <!--css-->

  <style type="text/css">
    *{
      margin:0;
      padding:0;
    }
    .carousel{
      position:absolute;
      left:0px;
      top:0px;
      width:100%;
      height:350px;
      overflow:hidden;
      white-space:nowrap;

    }
    .img{
      float:left;
      position:relative;
      max-width:900px;
      height:auto;
      border:solid red 0px;
    }
  </style>



  <title>Title of the document</title>
  </head>

<body>

	 <div id="carousel" class="carousel">
      <div >
       <div id="img" class="img"><img src="http://www.ttmt.org.uk/slideshow/images/slide-show-1.jpg" /></div>
       <div class="img"><img src="http://www.ttmt.org.uk/slideshow/images/slide-show-2.jpg" /></div>
       <div class="img"><img src="http://www.ttmt.org.uk/slideshow/images/slide-show-3.jpg" /></div>
       <div class="img"><img src="http://www.ttmt.org.uk/slideshow/images/slide-show-4.jpg" /></div>
      </div>
    </div>


<script>

var zxcCarousel={

 Auto:function(id,ms){
  var o=this['zxv'+id],oop=this;
  o?o.to=setTimeout(function(){ oop.rotate(o,true); },ms||500):null;
 },

 Pause:function(id){
  var o=this['zxv'+id];
  if (o){
   clearTimeout(o.to);
   o.auto=false;
  }
 },

 init:function(o){
  var id=o.CarouselID,ms=o.Animation,h=o.AutoHold,srt=o.AutoStart,p=document.getElementById(id),s=p?p.getElementsByTagName('DIV')[0]:null;
  if (s){
   s.style.width='50000px';
   s.style.position='absolute';
   s.style.left='0px';
   var clds=s.childNodes,ary=[],z0=0;
   for (;z0<clds.length;z0++){
    if (clds[z0].nodeType==1){
     ary.push(clds[z0]);
    }
   }
   o.id=id;
   o.p=p;
   o.s=[s,'left'];
   o.ary=ary;
   o.c=0;
   o.ms=typeof(ms)=='number'&&ms>20?ms:1000;
   o.hold=typeof(h)=='number'&&h>20?h:o.ms*4;
   this['zxv'+id]=o;
   typeof(srt)=='number'&&srt>=0?this.Auto(o.id,srt):null;
  }
 },

 rotate:function(o,a){
   this.Pause(o.id);
   o.auto=a===true;
   this.animate(o,o.s,0,-o.ary[o.c].offsetWidth,new Date(),o.ms,o.ary[o.c]);
 },

 animate:function(o,a,f,t,srt,mS,nxt){
  clearTimeout(a[4]);
  var oop=this,ms=new Date()-srt,n=(t-f)/mS*ms+f;
  if (isFinite(n)){
   a[0].style[a[1]]=n+'px';
  }
  if (ms<mS){
   a[4]=setTimeout(function(){ oop.animate(o,a,f,t,srt,mS,nxt); },10);
  }
  else {
   a[0].appendChild(nxt);
   a[0].style[a[1]]='0px';
   o.c=++o.c%o.ary.length;
   o.auto?oop.Auto(o.id,o.hold):null;
  }
 }

}

zxcCarousel.init({
 CarouselID:'carousel',
 Animation:1000,
 AutoHold:2000,
 AutoStart:2000
});
</script>

</body>

</html>























This is something I whipped up a moment ago.

The carousel functions to rotate images with a variable time setting and you can set individual intervals (in milliseconds) as well as that the looping is infinite with no counters, the array is simply rotated to allow the next image on the stack to be used.

I haven’t included any nice fancy functions to this as its meant to be an ideas framework to build on.

Please take this as a constructive piece of criticism, learn JavaScript before jumping in to JQuery, you often find the answer is far simpler and from a personal point of view, I hate the stuff, it is not true programming.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<script>

Array.prototype.getImage = function(){
	var tmp = this.shift(); // get an image object off the stack
	this.push(tmp);	// put it back on the stack at the end
	return tmp; // return copy of the object.
}

Object.prototype.update = function(o){
	try{
		for(p in o)
			if(p!="duration") this[p] = o[p];
		return true;
	}catch(e){
		return false;
	}
}

// the main bit...
carousel = {
	id:false,
	images:[],
	add:function(img,name,title,height,width,duration){
		// add to stack
		carousel.images.push({"src":img,"name":name,"title":title,"height":height,"width":width,"duration":duration});
	},
	next:function(){
		if(carousel.images.length){
			img = carousel.images.getImage(); // get the next img in the stack
			carousel.id.update(img); // update the target
			carousel.auto = setTimeout("carousel.next();",img.duration); // set the duration to next change
			}
	},	
	init:function(){
		if(!carousel.id) carousel.id = document.getElementById("carousel") || false;
		if(carousel.id){
			clearInterval(carousel.auto); // clear the current event timer
			carousel.auto = setTimeout("carousel.next();",250); // set a timeout
		}
	},
	auto:setInterval("carousel.init()",2000) // use a 2 second count to call the initialize function

}

// add some images to the carousel
carousel.add("DSCN1418.JPG","Hill","Hills Viewed from afar",1000,750,5000);
carousel.add("DSCN1419.JPG","Sea","Sea view from a cliff top",1000,750,5000);
carousel.add("DSCN1420.JPG","Air","Parachute Jump",1000,750,5000);
carousel.add("DSCN1421.JPG","Volcano","Erupting Volcano",1000,750,5000);
carousel.add("DSCN1422.JPG","Car","My favorite Car",1000,750,5000);
</script>

</head>


<body><div><img id="carousel" name="carousel" src="" height="" width="" title="" /></div>
</body>

</html>

Nice work, Vic and \\.\ . It’s nice to see solutions that don’t depend of jQuery. :slight_smile:

Hi there,

This is how I would do it:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <base href="http://www.ttmt.org.uk/slideshow/" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
    
    <!--jQuery-->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    
    <!--css-->
    
    <style type="text/css">
      .carousel{
        overflow:hidden;
        white-space:nowrap;
      }
      .img{
        max-width:900px;
        height:auto;
      }
      #images{
        position: relative;
      }
    </style>
    
    <!--[if lt IE 9]>
         <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    
    <title>Title of the document</title>
  </head>
  
  <body>
    <section >
      <div class="carousel">
        <div id="images">
          <img class="img" src="images/slide-show-1.jpg" />
          <img class="img" src="images/slide-show-2.jpg" />
          <img class="img" src="images/slide-show-3.jpg" />
          <img class="img" src="images/slide-show-4.jpg" />
         </div>
      </div>
    </section>
    
    <script>
      function slide(){
        var currImage = $('.img').first(),
            currImageWidth = currImage.width();			
        
        $imageContainer.animate({right: currImageWidth}, function(){
          setTimeout(function(){
            $imageContainer.append(currImage.clone());
            currImage.remove();
            $imageContainer.css("right", 0);
          }, 500);
        });
      }
    
      setInterval(function() {
        slide();
      }, 2000);
      
      // Strip out text nodes otherwise there is a jump when the initial slides are removed.
      // This is UGLY. Head over to the CSS forum and ask someone who knows what they're doing, how to do this properly
      //
      var holder = document.getElementById("images");
      for (var i =0; i < holder.childNodes.length; i++){
        if(holder.childNodes[i].nodeType === 3){
          holder.removeChild(holder.childNodes[i])
        }
      }
      
      var $imageContainer = $("#images");
    </script>
  </body>
</html>

If you have any questions about what I’ve done, just let me know.

Here’s a demo.

While I agree with this in principle, animation is really one area where jQuery shines.
I hate doing animation in plain JS and you can be so much more productive in a fraction of the time using a library.

It depends on the coder and how they implement the animation (if any at all is needed at all), you can have very effective animations done in very few lines of code and why does one need to have a whole library to load up and become ready before use? The JQuery you have listed is weighted at 90.8 KB, Minecraft, a fully functional game is only 100KB by comparison.

My template albeit basic weighs in at 1.24 KB and Vic’s will be about the same, goes to say that around 1/90th the size says something. I imagine a full blown version with animation would be around 4KB tops.

Whilst I appreciate your reply, its a question of size and size affects loading speed and when I supply automated scripts I build in a couple of seconds delay because it does not matter how fast your internet is, network traffic and other overheads will cause delays in loading the page, you then have the weighting of the image to account for because not everyone will process images so they are “Net” ready.

All fair points.

However I don’t consider 90kb to be a massive price to pay for the functionality that jQuery brings.
You can easily make this back up again by optimising images, minifying CSS / HTML etc.

But, before you think that I’m a jQuery fanboy, have a look at this, which is a competition that I help organise and run, encouraging people to think beyond reaching for jQuery, just because they could.

Thanks all for your help.

Your code and ideas all look brilliant but I need more.

I thought I might be able to do this by breaking it down into sections but it might be better to explain the whole thing.

I want a responsive carosel that is the full width of the browser with one image in the middle then and the image before and after going off the window and for the carousel to scroll.

I think I might have found a soultion with the caroufredsel carousel - http://caroufredsel.dev7studios.com

It does most of what I want apart from the responsiveness, but I can sort of fake that with media queries.

My problem now is this carousel doesn’t load correctly until I resize the browser.

Does anyone know why the carousel doesn’t start without window resize, is there a way to fix this.

http://www.ttmt.org.uk/carousel/index.html

Loads fine for me in Chrome.

I’ve cleated caches and restarted but it dosen’t work for me in any browser

Does it load like this image

For me it does, yes.

I don’t understand then - I’ve been trying to get it to work for the past day.

Hm, very odd, it’s not working well for me now as the page loads, but it was fine before. Have you changed anything recently? (Like in the last half hour?)

I have moved it just now but it will be back in a minute

It’s back now - I haven’t done anything to the file, just had to move it.