I'm building an auto-rotating image-carousel with jquery and I'm trying to get the images to rotate infinitely rather than when it reaches the last image, it 'rewinds' back to the first image and starts again. Unfortunately, I'm rather new at the jquery game, so I'm having some trouble getting this to work. I've tried piecing together code I've found in tutorials online and modifying it to fit my code, but no luck. I think I might have to clone the existing images to appear after they cycle through, but I'm not sure what direction to go in. Any assistance is greatly appreciated. Here's the code I'm working with below:
HTML:
<div class="main_view">
<div style="width:165px; height:98px; margin:0; padding:0; border:0;">
<img src="/content/template_images/wanalogo-blackBG-165x98.png" />
</div>
<div class="window">
<ul class="image_reel">
<li><a href="/MLB/Philadelphia-Phillies-Tickets" title="Phillies"><img src="/content/template_images/Banners/SideBanner/imgscroll1.jpg" alt="Phillies" /></a></li>
<li><a href="/NFL/Philadelphia-Eagles-Tickets" title="Eagles"><img src="/content/template_images/Banners/SideBanner/imgscroll2.jpg" alt="Eagles" /></a></li>
<li><a href="/NHL/Philadelphia-Flyers-Tickets" title="Flyers"><img src="/content/template_images/Banners/SideBanner/imgscroll3.jpg" alt="Flyers" /></a></li>
<li><a href="/NBA/Philadelphia-76ers-Tickets" title="76ers"><img src="/content/template_images/Banners/SideBanner/imgscroll4.jpg" alt="76ers" /></a></li>
<li><a href="/NCAA-Basketball" title="NCAA Basketball"><img src="/content/template_images/Banners/SideBanner/imgscroll8.jpg" alt="NCAA Basketball" /></a></li>
<li><a href="/Concerts-Tickets" title="Concerts"><img src="/content/template_images/Banners/SideBanner/imgscroll5.jpg" alt="Concerts" /></a></li>
<li><a href="/Theatre-Tickets" title="Theatre"><img src="/content/template_images/Banners/SideBanner/imgscroll6.jpg" alt="Theatre" /></a></li>
<li><a href="/Other-Events-Tickets" title="Family Events"><img src="/content/template_images/Banners/SideBanner/imgscroll7.jpg" alt="Family Events" /></a></li>
</ul>
</div>
<div style="width:170px; height:290px; border:0; padding:0; margin: -290px 0px 0px 0px;">
<img src="/content/template_images/black-fade-border-170x290.png" />
</div>
<div class="botTextBox">
<center>
<div class="botText">
<a href="/MLB/Philadelphia-Phillies-Tickets" title="Phillies">Phillies</p></a>
<a href="/NFL/Philadelphia-Eagles-Tickets" title="Eagles"><p>Eagles</p></a>
<a href="/NHL/Philadelphia-Flyers-Tickets" title="Flyers"><p>Flyers</p></a>
<a href="/NBA/Philadelphia-76ers-Tickets" title="76ers"><p>76ers</p></a>
<a href="/NCAA-Basketball" title="NCAA Basketball"><p>NCAA Basketball</p></a>
<a href="/Concerts-Tickets" title="Concerts"><p>Concert</p></a>
<a href="/Theatre-Tickets" title="Theatre"><p>Theatre</p></a>
<a href="/Other-Events-Tickets" title="Family Events"><p>Family Event</p></a>
</div>
</center>
</div>
<div class="paging">
<a href="#" rel="1">1</a>
<a href="#" rel="2">2</a>
<a href="#" rel="3">3</a>
<a href="#" rel="4">4</a>
<a href="#" rel="5">5</a>
<a href="#" rel="6">6</a>
<a href="#" rel="7">7</a>
<a href="#" rel="8">8</a>
</div>
</div>
Javascript
$(document).ready(function() {
$(".paging").show();
$(".paging a:first").addClass("active");
var imageWidth = $(".window").width();
var imageSum = $(".image_reel img").size();
var imageReelWidth = imageWidth * imageSum;
$(".image_reel").css({'width' : imageReelWidth});
rotate = function(){
var triggerID = $active.attr("rel") - 1; //Get number of times to slide
var image_reelPosition = triggerID * imageWidth; //Determines the distance the image reel needs to slide
$(".paging a").removeClass('active'); //Remove all active class
$active.addClass('active'); //Add active class (the $active is declared in the rotateSwitch function)
//Slider Animation
$(".image_reel").animate({
left: -image_reelPosition
}, 750 );
$(".botText").animate({
left: -image_reelPosition
}, 750 );
};
//Rotation and Timing Event
rotateSwitch = function(){
play = setInterval(function(){ //Set timer - this will repeat itself every X seconds
$active = $('.paging a.active').next(); //Move to the next paging
if ( $active.length === 0) { //If paging reaches the end...
$active = $('.paging a:first'); //go back to first
}
rotate(); //Trigger the paging and slider function
}, 1500); //Timer speed in milliseconds (7 seconds)
};
rotateSwitch(); //Run function on launch
//On Hover
$(".image_reel a").hover(function() {
clearInterval(play); //Stop the rotation
}, function() {
rotateSwitch(); //Resume rotation timer
});
//On Click
$(".paging a").click(function() {
$active = $(this); //Activate the clicked paging
//Reset Timer
clearInterval(play); //Stop the rotation
rotate(); //Trigger rotation immediately
rotateSwitch(); // Resume rotation timer
return false; //Prevent browser jump to link anchor
});
});
Edit- CSS:
.main_view {
float: left;
overflow:hidden;
position: relative;
width:170px;
height:475px;
background-color:black;
border:0;
margin:2px;
padding:2px 0px 2px 0px;
text-align:center;
}
.window {
height:290px; width:170px;
overflow: hidden;
position: relative;
background-color:black;
border:0;
padding:0px;
margin:0px;
}
.image_reel {
position: absolute;
top: 0; left: 0;
margin-left:-40px;
}
.image_reel img {float: left;}
.botTextBox {
height:87px; width:1360px;
overflow:hidden;
position:relative;
background:url(/content/template_images/black-side-bottom-170x87.png) no-repeat;
margin:0px;
padding:0px;
}
.botText {
position:relative;
top:0; left:0;
margin:32px 0px 0px 0px;
padding:0;
text-align:center;
}
.botText p {width:170px; float: left;}
.paging {
position: absolute;
bottom: 40px; right: -7000px;
width: 178px; height:47px;
z-index: 100;
text-align: center;
line-height: 40px;
display: none;
}
.paging a {
padding: 5px;
text-decoration: none;
color: #fff;
}
.paging a.active {
font-weight: bold;
background: #920000;
border: 1px solid #610000;
-moz-border-radius: 3px;
-khtml-border-radius: 3px;
-webkit-border-radius: 3px;
}
.paging a:hover {font-weight: bold;}
...actually you can see the flash banner on the right that i'm trying to replace with a jquery one...
Once again, I really appreciate any help with this. Like I said, I'm kinda new at working with jQuery and I've been stumbling over this all day. Thanks a million.
The problem with your carousel is that the block of images remains one giant block, so when you get to the end, you must slide all the way back to the first image to loop, and this is what causes that "rewind" look.
What I would do instead is:
number % length
)Below is an example implementation with a recursive function.
I create a slider function that makes use of jQuery's .animate()
. In the call back of .animate()
I call the slider function again after a brief pause casued by setTimeout()
.
The example below is quite simple, you can adjust it easily to for example show the slivers of the previous and next image and other things.... This is just to illustrate a simple implementation of an infinite slide with a limited number of images.
I added in a simple implementation of how to show a changing caption under the gallery. The information for the caption is taken from the images HTML codes. This caption could also be placed under each image and slid along with the image.
$(function() {
var showing = 0; // which image is showing
var imgs = []; // array to hold images HTML
// Put image elements into an array
imgs = $("#gallery img").toArray();
var numberOf = imgs.length;
// Remove all but first image from DOM
$("#slider").html("");
$("#slider").html(imgs[0]);
// Add title text div
$("#gallery").after('<a id="title"/>');
// The recursive slider function
var nextImage = function() {
// Add next image (only use increment once!)
$("#slider").append(imgs[++showing % numberOf]);
// Show image title
$("#title").html($(imgs[showing % numberOf]).attr("title"));
// Link to original
$("#title").attr("href", $(imgs[showing % numberOf]).attr("src"));
// Animate the slider
$("#slider").animate({
left: '-=200'
}, 2000, function() {
// Remove image to the left
$("#slider img:first").remove();
// Reset CSS
$("#slider").css("left", "0px");
// Call animationg function again
setTimeout(function() {nextImage(); }, 1000);
});
}
nextImage(); // Call next image for the first time
});
The static HTML would consist of:
<div id="gallery">
<div id="slider">
... the images here ...
</div>
</div>
PS: to see the conveyor belt effect at work look at this.
.animate()
.append()
.css()
:first
selector.html()
.length
.remove()
setTimeout()
.toArray()
Peter Ajtai has a nice summary of one method, but I have another one which only requires adding a few lines to your script.
Basically it clones the first image, text and pager link and adds it to the end. When the animation ends on the last image (which is now actually the first), the left positioning of the window is reset to zero and the animation resumes. I tried to add comments with [NEW]
so you can more easily find the changes. And, I made a demo so hopefully it will be clear.
$(document).ready(function() {
$(".paging").show();
$(".paging a:first").addClass("active");
var imageWidth = $(".window").width();
// [NEW] add one, since we are adding the first image to the end
var imageSum = $(".image_reel img").size() + 1;
var imageReelWidth = imageWidth * imageSum;
// [NEW] included modifying width of botTextBox
$(".image_reel, .botTextBox").css({'width' : imageReelWidth });
// [NEW] clone first image & text and add it to the end, include dummy paging
$(".image_reel li:first").clone().appendTo( $(".image_reel") );
$(".botText a:first").clone().appendTo( $(".botText") );
$(".paging").append('<a href="#" rel="' + imageSum + '"></a>'); // don't include the number in the link
rotate = function(){
var triggerID = $active.attr("rel") - 1; //Get number of times to slide
var image_reelPosition = triggerID * imageWidth; //Determines the distance the image reel needs to slide
$(".paging a").removeClass('active'); //Remove all active class
$active.addClass('active'); //Add active class (the $active is declared in the rotateSwitch function)
// [NEW] Slider Animation
$(".image_reel, .botText").animate({
left: -image_reelPosition
}, 750, function(){
// [NEW] callback function (called when animation is done)
if (triggerID == imageSum - 1) {
// if we're back to the first image, reset the window position
$(".image_reel, .botText").css('left',0);
}
});
};
//Rotation and Timing Event
rotateSwitch = function(){
play = setInterval(function(){ //Set timer - this will repeat itself every X seconds
$active = $('.paging a.active').next(); //Move to the next paging
if ( $active.length === 0) { // If paging reaches the end...
// [NEW] go back to second image (the first is now the last)
$active = $('.paging a:eq(1)');
}
rotate(); //Trigger the paging and slider function
}, 1500); //Timer speed in milliseconds (7 seconds)
};
rotateSwitch(); //Run function on launch
//On Hover
$(".image_reel a").hover(function(){
clearInterval(play); //Stop the rotation
}, function(){
rotateSwitch(); //Resume rotation timer
});
//On Click
$(".paging a").click(function() {
$active = $(this); //Activate the clicked paging
//Reset Timer
clearInterval(play); //Stop the rotation
rotate(); //Trigger rotation immediately
rotateSwitch(); // Resume rotation timer
return false; //Prevent browser jump to link anchor
});
});
Oh and one last thing... I added the missing <p>
in front of the Phillies botText
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With