I'm trying to make an image carousel/slider that automatically scrolls smoothly and loops using jQuery. Here's the function I'm using:
function spinCarousel() {
$("ul li:first-child").animate({ marginLeft: -200 }, 3000, 'linear', function () {
$("ul li:first-child").appendTo('ul');
$("ul li:last-child").css('margin-Left', 0);
spinCarousel();
});
}
And here's an illustration: https://jsfiddle.net/T_Recks/aa43n7g0/
I tried adding it to a local development site (replacing the text and colored backgrounds with images) and it seems to work nicely. However, I'd like to make a version that scrolls right instead of left, but haven't been able to figure it out. I've tried changing ".append" to ".prepend" and playing with the margin changes, but no luck so far.
Any suggestions?
I forked and retooled your JSFiddle to make it scroll from left to right. Check it out here: https://jsfiddle.net/1jw8xpqe/
Had to change a few things to get it working. First, the list is parsed to reverse the order of the slides and shift a couple of them so the leftmost one is "Item #1" when the slider initializes:
// reverse items
var list = $('ul');
var listItems = list.children('li');
list.append(listItems.get().reverse());
// rearrange last two items so first slide starts on left
list.prepend($('ul li:last-child').prev('li').andSelf());
Then a few CSS/JS tweaks: The slide animates the first li from -200px (defined in the CSS) to 0, and after each cycle, prepends the last item of the ul to the start at -200px. Hope this helps!
Related
I am trying to use this slider: http://codepen.io/zuraizm/pen/vGDHl
I need to have multiple sliders on the page, up to 10 maybe more. It is for a property listings page, and this is a really light slider.
Currently when you press next, it slides the images for every slider. I know its an ID issue, but is there a simple way to fix this without having to have tens of different id's?
UPDATE!
This is my updated pen, with the sliders working: http://codepen.io/LukeD1uk/pen/LEKBa But it appears each slider is loading the last LI in UL
I was thinking something like this...
function moveRight(slider) {
slider = $(slider);
slider.find('ul').animate({
left: - slideWidth
}, 200, function () {
slider.find('ul li:first-child').appendTo(slider.find('ul'));
slider.find('ul').css('left', '');
});
};
$('a.control_next').click(function () {
moveRight($(this).parent());
});
Makes it so that the only global selection is a.control_next and then the rest are scoped to where the click actually happened.
EDIT: There are some additional issues with selecting more than you want. Here's another fixed spot.
This
$('#slider ul li:last-child').prependTo('#slider ul');
Becomes this
$('.slider').each(function(slider){
slider = $(slider);
slider.find('ul li:last-child').prependTo(slider.find('ul'));
});
This takes the last image in each slider and prepends it to the list so the back button will work. You will run into additional issues if the picture width/height/count differ or if you choose to implement the checkbox autoscroll.
To fix those though you would need to implement a much better structure in the js so that each slider has it's own variables. I don't really have the time to go through and set that up, sorry.
I've been trying to adapt the following code to integrate with my CSS3 slider (animated and timed with keyframes) however as you can't use .animate in js when using css3 animations on the same element I either have to use one or the other.
JS I've adapted for my slider
The current js works in the sense that it navigates through the slides my only issue is that it doesn't 'slide' to each slide it jumps.
I'd really like to keep the slideshow as it is and just want to update my js so that the slide transition works. I'm not great with js so I've been finding it difficult to find a solution.
If anyone could give some advice or a solution to my problem it would be truly appreciated.
DEMO
JS
//grab the width and calculate left value
var item_width = $("#carousel .video-list li").outerWidth();
var left_value = item_width * (-1);
//if user clicked on prev button
$('#previous').click(function () {
//get the right position
var left_indent = parseInt($("#carousel .video-list").css('left')) + item_width;
//slide the item
$("#carousel .video-list").animate({'left' : left_indent}, function () {
//move the last item and put it as first item
$("#carousel .video-list li:first").before($("#carousel .video-list li:last"));
//set the default item to correct position
$("#carousel .video-list").css({'left' : left_value});
});
//cancel the link behavior
return false;
});
//if user clicked on next button
$('#next').click(function () {
//get the right position
var left_indent = parseInt($("#carousel .video-list").css('left')) - item_width;
//slide the item
$("#carousel .video-list").animate({'left' : left_indent}, function () {
//move the first item and put it as last item
$("#carousel .video-list li:last").after($("#carousel .video-list li:first"));
//set the default item to correct position
$("#carousel .video-list").css({'left' : left_value});
});
//cancel the link behavior
return false;
});
I don't see why .animate is needed, because I have used
transition: left 1s ease;
in my CSS to achieve the same things, with a smoother animation than I got with jQuery. I tried deleting the:
//slide the item
$("#carousel .video-list").animate(...
for the left and right. I also added some text to the html divs so that you can see how it's moving better. Sorry that I couldn't get it working, but I really feel that "transition" is what you need to look into. Here's the fiddle :)
...
I think your simplest solution would be to ditch the whole CSS animate, and build your own carousel:
Consider a film strip, which is a bunch of pictures lined up next to each other. Now consider a paper with a box cut-out, the size of one picture. We put the strip behind the paper, and see only one image. If we move the strip, we can change which image we see.
The film strip will be a div with { display: inline-block; } property, containing each of the videos. The box cut-out will be a div with { overflow: hidden } property. To move the strip, we simply use $('#strip').css({'left': positionofstripleft - widthofbox }) in our javascript. And for the animation, a simple setInterval(Nextfunction, 65000) to do what clicking next would do every 65 seconds.
Finally, a CSS transition will make the movements actually animated.
I am trying to create a customized carousel and it already has the following features:
You can move left and right with the mouse or by swipe on mobile/tablets.
You can move left or right with buttons.
However, the problem is that the buttons don't deactivate once the end of the div is reached. Instead, everything keeps shifting forever. See picture below:
Take a look at the jsFiddle: http://jsfiddle.net/vnkRw/2/
$("#left").click(function() {
$(".wrapper").stop(true, true).animate({left: "-=125px"}, 500);
});
$("#right").click(function() {
$(".wrapper").stop(true, true).animate({left: "+=125px"}, 500);
});
How can I deactivate the buttons once the end is reached? For example, when here:
The left button should deactivate since there are no more div's to show.
And, of course, the same for the right:
The Goal: Deactive buttons when end is reached.
something like
pos=slides=$(".wrapper > div").length;
$("#left").click(function() {
if(pos>3){$(".wrapper").stop(true, true).animate({left: "-=125px"}, 500);pos--;}
});
$("#right").click(function() {
if(pos<slides){$(".wrapper").stop(true, true).animate({left: "+=125px"}, 500);pos++;}
});
$('.carousel').kinetic();
There are some things to consider when doing carousel, I'll just get you started.
Will all items be the same width
Will all items have same margins
Will the things above be variable
It we presume that all the things above are static, the idea is for the scroll to right to not happen if the left position of wrapper is 0. And that's the easy part. For the other direction you have to take the number of all items, subtract the number of visible items (in your case 3) , multiply that by their width (including the margin) and all this providing all items are same width and with same margin .. and in the end you have to multiply that by -1, because your wrapper's left position becomes negative number. And in the end, if wrapper reached that position, you should not scroll it.
A visualization of the above mini-wall of text:
http://jsfiddle.net/vnkRw/4/
So I previously asked a question about how to create a banner like the one shown here and I got a really good answer to start me off. I have been working on it since and I'm having a lot of problems getting the animation to slide back to it's original position.
Here is my animation: http://jsfiddle.net/43nCF/ (don't click the green block first)
Issue: After the first time you toggle a block, clicking another block will not move it to the left.
I also have some other minor issues which I would be grateful if someone helped me with.
How do I get the width and the moving of the blocks to animate simultaneously like in the banner animation I am trying to replicate?
How do I get the block to slide back to the original position instead of just kind of 'transporting' there?
I am only beginner at jQuery so any help would be amazing.Thanks.
As for the positioning problem: you need to drop the left declaration in your second function.
Regarding making the animation act simultanous: animate both the right and the width property for each element, in one call:
function() {
var position = $.data(this, 'position');
var ind = $(this).index();
//moves image back to original position
$('#container div').each(
function() {
$(this).animate({
right: "",
width: 100
});
});
});
Working example here.
I see you have a response.
In case this version is of any help to you:
http://jsfiddle.net/vCbcz/
Instead of altering the divs other than the one being affected, I wrapped them all in a #slider div and adjusted that one's left margin to push it to the left.
$('#slider').animate({
marginLeft: '-' + ind * 105 + 'px'
});
and back
$('#slider').animate({
marginLeft: 0 + 'px'
});
There is a much easier way altogether of doing this. By using jQuery's scrollTo plugin, this can be done in a mere few lines of code, without using indices, calculations, or anything of that nature.
Live Demo http://jsfiddle.net/Jaybles/WEzny/
I have an image scroller that I am trying to implement. The image scrolling works, but it is moving vertically instead of horizontally. Here is what I got so far:
Next Image
$('#btnNext').click(function () {
//Calls new image with value true, meaning next image
newImage(true);
return false;
});
function newImage(direction) {
//Get the current selected item (with selected class), if none was found, get the first item
current_image = $('#imageGallery li.selected').length ? $('#imageGallery li.selected') : $('#imageGallery li:first');
//If determines slideshow direction
if (direction) { //Next image
//Get next sibling
next_image = (current_image.next().length) ? current_image.next() : $('#imageGallery li:first');
} else { //Previous image
//Get previous sibling
next_image = (current_image.prev().length) ? current_image.prev() : $('#imageGallery li:last');
}
//Clear selected class
$('#imageGallery li').removeClass('selected');
//Reassign selected class to current image
next_image.addClass('selected');
//Scroll images
$('#images').scrollTo(next_image, 800);
}
Update: Here are my quesions:
1) How do I edit this to make it move horizontally?
2) Is there a way to make an image scroller like this without using .scrollTo()?
I assume you want to make the gallery move horizontally, not vertically. (You say both in the question.) This is just a CSS issue: change the list to show horizontally (display: inline-block or float: left for instance) and the scrollTo plugin should do that for you.
It is possible to do this without the scrollTo plugin. The plugin uses the jQuery animate function to move around the page and, well, you can do the same if you want. :) Here's a quick jsFiddle that uses animate to move pictures in a gallery. Obviously it needs quite a bit of work (doesn't go back to the beginning at the last pic, only goes 1 way, doesn't calculate picture width, etc.), but it should hopefully give you an idea of how it can be done.
http://jsfiddle.net/meloncholy/KzBzT/