cycle2 icon indicating copy to clipboard operation
cycle2 copied to clipboard

Scroll the carousel more than one slide at a time

Open daltonrooney opened this issue 12 years ago • 37 comments

I have a carousel that's set to show four slides, and I'd like it to advance four slides at a time to the next group. Is there any way to do that?

daltonrooney avatar Feb 25 '13 18:02 daltonrooney

Have exactly the same issue/question. Maybe it's possible with some nifty callback on the next button, but I can not get it to work.

DannyJasper avatar Feb 26 '13 14:02 DannyJasper

Instead of showing four slides, show one slide with 4 elements in. Then the cycle just happily displays the outer groups, and you get the same visual effect.

Something like (this won't work without adjustment!):

<div class="cycle">
  <div class="group">
    <img src="img1.png" />
    <img src="img2.png" />
  </div>
  <div class="group">
    <img src="img3.png" />
    <img src="img4.png" />
  </div>
</div>

mpettitt avatar Feb 26 '13 14:02 mpettitt

@mpettitt That's what I ended up doing, but if you have an odd number of items in your carousel, then it won't be continuous. http://cl.ly/1l2k1D133t2U

I'd like the ability to create a continuous carousel but advance the entire row in one shot.

daltonrooney avatar Feb 26 '13 15:02 daltonrooney

This is a feature I plan to add, just haven't had time. I have a lot of work to do on the carousel implementation.

malsup avatar Mar 01 '13 14:03 malsup

I've been playing around a bit and came up with the following solution, while we wait for something more official. You can choose the number of slides it "hops" with the setting data-cycle-carousel-hops

@@ -6,6 +6,10 @@
     if ( opts.fx !== 'carousel' )
         return;

+    function _modulo(m,n) {
+        return ((m%n)+n)%n;
+    }
+    
     API.getSlideIndex = function( el ) {
         var slides = this.opts()._carouselWrap.children();
         var i = slides.index( el );
@@ -17,10 +21,47 @@
         var count = opts.reverse ? -1 : 1;
         if ( opts.allowWrap === false && ( opts.currSlide + count ) > opts.slideCount - opts.carouselVisible )
             return;
-        opts.API.advanceSlide( count );
+        opts.API.advanceSlide( count * opts.carouselHops );
         opts.API.trigger('cycle-next', [ opts ]).log('cycle-next');
     };
-
+    
+    API.prev = function() {
+        var opts = this.opts();
+        if ( opts.busy && ! opts.manualTrump )
+            return;
+        var count = opts.reverse ? 1 : -1;
+        if ( opts.allowWrap === false && ( opts.currSlide + count ) < 0 )
+            return;
+
+        opts.API.advanceSlide( count * opts.carouselHops );
+        opts.API.trigger('cycle-prev', [ opts ]).log('cycle-prev');
+    };
+    
+    API.calcFirstSlide = function() {
+        var opts = this.opts();
+        var firstSlideIndex;
+        firstSlideIndex = parseInt( opts.startingSlide || 0, 10 );
+        if (firstSlideIndex >= opts.slides.length || firstSlideIndex < 0)
+            firstSlideIndex = 0;
+
+        opts.currSlide = firstSlideIndex;
+        opts.nextSlide = _modulo(firstSlideIndex + opts.carouselHops * (opts.reverse ? -1 : 1), opts.slideCount);
+    };
+    
+    API.calcNextSlide = function(){
+        opts.currSlide = opts.nextSlide;
+        opts.nextSlide = _modulo(opts.currSlide + opts.carouselHops * (opts.reverse ? -1 : 1), opts.slideCount);
+    }
+
+    API.advanceSlide = function( val ) {
+        var opts = this.opts();
+        clearTimeout(opts.timeoutId);
+        opts.timeoutId = 0;
+        opts.nextSlide = _modulo(opts.currSlide + val, opts.slides.length);
+
+        opts.API.prepareTx( true,  val >= 0 );
+        return false;
+    };
 });


@@ -46,6 +87,12 @@
         if (opts.carouselVisible && opts.carouselVisible > opts.slideCount)
             opts.carouselVisible = opts.slideCount - 1;
         var visCount = opts.carouselVisible || opts.slides.length;
+        
+        if( opts.carouselVisible )
+            opts.carouselHops = Math.min(opts.carouselHops || 1, opts.slideCount - opts.carouselVisible + 1);
+        else
+            opts.carouselHops = Math.min(opts.carouselHops || 1, opts.slideCount - 1);
+
         var slideCSS = { display: vert ? 'block' : 'inline-block', position: 'static' };

         // required styles
@@ -194,14 +237,16 @@
             opts.API.opts()._currSlide = opts.nextSlide > maxCurr ? maxCurr : opts.nextSlide;
         }
         else {
-            if ( fwd && opts.nextSlide === 0 ) {
-                // moving from last slide to first
-                moveBy = this.getDim( opts, opts.currSlide, vert );
+            if ( fwd && opts.nextSlide < opts.currSlide ) {
+                // wrap around on the right
+                moveBy = this.getScroll( opts, vert, opts.currSlide, opts.slideCount-opts.currSlide );
+                moveBy += this.getScroll( opts, vert, 0, opts.nextSlide );
                 callback = this.genCallback( opts, fwd, vert, callback );
             }
-            else if ( !fwd && opts.nextSlide == opts.slideCount - 1 ) {
-                // moving from first slide to last
-                moveBy = this.getDim( opts, opts.currSlide, vert );
+            else if ( !fwd && opts.nextSlide > opts.currSlide ) {
+                // wrap around on the left
+                moveBy = this.getScroll( opts, vert, opts.nextSlide, opts.slideCount-opts.nextSlide );
+                moveBy += this.getScroll( opts, vert, 0, opts.currSlide );
                 callback = this.genCallback( opts, fwd, vert, callback );
             }
             else {

gabrielfin avatar May 08 '13 03:05 gabrielfin

@gabrielfin do you have a working example of your "hops" working? i'd love to see it in action, as i desperately need to find a way to step through multiple images at a time. thanks!

poisonkitty avatar Jun 17 '13 14:06 poisonkitty

@gabrielfin never mind, got it going. works great! thanks!!!

poisonkitty avatar Jun 17 '13 15:06 poisonkitty

@gabrielfin or @poisonkitty can one of you post the working code? I can't seem to get this to work properly. Thanks

ninedoors avatar Jul 18 '13 12:07 ninedoors

@gabrielfin or @poisonkitty I got it working, forgot was missing a ; from the copy paste. Thanks for the code @gabrielfin

ninedoors avatar Jul 18 '13 16:07 ninedoors

+1 for official solution,

the code pasted here works 50-50, going forward works ok, but going back shows empty slides (visibility:hidden)

davorpeic avatar Jan 20 '14 00:01 davorpeic

+1 here, too.

flyarrowplane avatar Mar 22 '14 22:03 flyarrowplane

+1 from me too.

phenaproxima avatar Mar 25 '14 19:03 phenaproxima

+1

@gabrielfin I'm using your soln as well. I have noticed tho as the above people have said that circular/wrap doesn't work properly ie (allowWrap=true) also the disabledClass functionality for your prev/next buttons doesn't work correctly when doing allowWrap=false

I am seeing my issues when you proceed to the end of your list of hops.

wmitchellUK avatar Mar 27 '14 20:03 wmitchellUK

or you can just hide some pagers, for example, you need to slide elements every 3rd, then you just need only #pager span:nth-child(3n+2),#pager span:nth-child(3n+3){display:none;}

asdat avatar Apr 20 '14 18:04 asdat

@asdat your CSS solution was easiest to implement +1

visutech avatar May 25 '14 08:05 visutech

yes, but it works only for pagers, next/prev slides only next or prev, for prev/next navigation better overwrite prev/next sliding without using prev/next from cycle2, later i'll make an example and show it

asdat avatar May 27 '14 16:05 asdat

Just curious if an official version is going to be implemented? The only reason we dont use Carousel is because it moves 1 at a time which quite frankly is very annoying and dont understand why one anyone would do that. The user has already seen ALL images in the row, he wants to see the next row without clicking x number of times. Thanks!

amityweb avatar Jun 04 '14 08:06 amityweb

@amityweb - it would be good if this could be added to the cycle carousel plugin, as I think it should reside with that. If you need a quick fix though, the css workaround does work (probably only on browsers that support the nth child).

visutech avatar Jun 04 '14 08:06 visutech

+1 - follow me on Twitter for chat about this @BenRacicot

I +1'ed this yesterday but was handcuffed to the project: I've built this (for a carousel type implementation), with some help, which works to move 3 slides at a time.

$('.slides').on('cycle-update-view', function (e, optionHash, slideOptionsHash, currSlideEl) {
    // +1 brings us current from the zero index
    currSlide = optionHash.currSlide + 1;
    fullCount = optionHash.slideCount;
});

$('.next').on( 'click', function() {
    $(this).prev('.slides').cycle('goto', currSlide + 2);
});

$('.prev').on( 'click', function() {
    var minus = currSlide - 4;
    $(this).next('.slides').cycle('goto', minus);
});

BenRacicot avatar Jun 17 '14 20:06 BenRacicot

@BenRacicot thanks for your work. this works somehow but is not "perfect". mine isn't eather, but lets call it improved.. currSlide + 2 could also make an invalid result, lets say your slideshow is 7 slides long and the current slide is 7, then next would be 9, but since 9 does not exist, the slideshow will do nothing. with this solution it jumps to slide 0 (zero-indexed).

plus i made it variable:

  1. if the current slide has class skip, then skip the next slide. if not proceed as normal (+1).
var cycle_all, cycle_next;

$(".slideshow").on("cycle-update-view", function (e, optionHash, slideOptionsHash, currSlideEl) {
    cycle_all = optionHash.slideCount;
    if ( $( currSlideEl ).is(".skip") ) {
        cycle_next = optionHash.currSlide + 2;
    } else {
        cycle_next = optionHash.currSlide + 1;
    }
    if ( cycle_next >= cycle_all ) {
        cycle_next = 0;
    }
});

$(".next").on( "click", function() {
    $(".slideshow").cycle( "goto", cycle_next );
});

(this only includes next since i don't needed prev..)

jnz31 avatar Jul 16 '14 13:07 jnz31

+1

This worked perfectly! Thank you!

che-wf avatar Sep 02 '14 19:09 che-wf

why don't you think about nested slideshows? for example n=3 you have HTML

<div class="cycle-slideshow" 
    data-cycle-fx=scrollHorz
    data-cycle-timeout=0
    data-cycle-slides="> div.slide"
    >
    <div class="cycle-prev"></div>
    <div class="cycle-next"></div>
    <div class="slide">
       <img src="http://malsup.github.io/images/p1.jpg">
       <img src="http://malsup.github.io/images/p2.jpg">
       <img src="http://malsup.github.io/images/p3.jpg">
    </div>
    <div class="slide">
       <img src="http://malsup.github.io/images/p4.jpg">
       <img src="http://malsup.github.io/images/p1.jpg">
       <img src="http://malsup.github.io/images/p2.jpg">
    </div>
</div>

then even pagers would work fine

the easiest decition fo sliding any n element is to slide n times next/prev HTML

<div class="prev"></div>
<div class="next"></div>
<div class="cycle-slideshow" 
    data-cycle-fx=scrollHorz
    data-cycle-timeout=0
    data-slides-perclick="3"
    >
    <img src="http://malsup.github.io/images/p1.jpg">
    <img src="http://malsup.github.io/images/p2.jpg">
    <img src="http://malsup.github.io/images/p3.jpg">
    <img src="http://malsup.github.io/images/p4.jpg">
    <img src="http://malsup.github.io/images/p1.jpg">
    <img src="http://malsup.github.io/images/p2.jpg">
</div>

JS

jQuery('div.next').click(function(){
  e.preventDefault();
  var count=jQuery('.cycle-slideshow').date('slides-perclick');
  for (i = 0; i < count; i++) { 
       jQuery('.cycle-slideshow').cycle('next');
  }
});
jQuery('div.prev').click(function(){
  e.preventDefault();
  var count=jQuery('.cycle-slideshow').date('slides-perclick');
  for (i = 0; i < count; i++) { 
       jQuery('.cycle-slideshow').cycle('prev');
  }
});

code not best, but easier to understand

asdat avatar Sep 02 '14 20:09 asdat

Did this ever get added to the official plugin?

mledwards avatar Oct 16 '14 15:10 mledwards

Same question, need to skip multiple images at once - is there an official way to do this?

MariuszDabrowski avatar Oct 29 '14 21:10 MariuszDabrowski

+1 for multple (like a slider) and if you do a web search there are a billion other people wanting to do this :+1:

shawnholt avatar Nov 13 '14 23:11 shawnholt

+1 waiting for this feature for a long time!

Seb33300 avatar Nov 19 '14 11:11 Seb33300

Is this feature implemented in the carousel plugin? The demo page still shows the carousel moving only one slide at a time. http://jquery.malsup.com/cycle2/demo/carousel.php

tangst avatar Dec 19 '14 16:12 tangst

Hi there! I just applied my patch to a fork so it's easier if anyone else wants to use it. I also fixed the issue with allowWrap=false and disabling the "next" button (@wmitchellUK). https://github.com/gabrielfin/cycle2/blob/issue-%23106/src/jquery.cycle2.carousel.js

gabrielfin avatar Dec 20 '14 03:12 gabrielfin

You little darling! :+1:

mledwards avatar Dec 23 '14 17:12 mledwards

@gabrielfin doesn't work with allow-wrap: false

KZNcode avatar Jan 12 '15 04:01 KZNcode