0

I'm using SlidesJS, which is a very customizable plugin for pagination of slideshows.

This is my initialization.

$('.slides').slidesjs
({
    width: 300,
    height: 300,
    navigation: false,             // It's for swiping in an iOS web app
    pagination: false,
    generatePagination: false
});

However, I don't want the slideshow to wrap "the other way around". I don't know if there is a term for this, so I painted this illustration:

Green = Next
Blue = Previous

slidesjs wraparound

What I want is the swipes which go from 4 -> 1 or from 1 -> 4 to be disabled. I haven't found a built in feature or property for this. But, is there a reasonable workaround?

bytecode77
  • 14,163
  • 30
  • 110
  • 141
  • Do you mean that once slideshow reaches `#4` the slideshow should be disabled? – guest271314 Jul 16 '16 at 00:24
  • You sould be able to go from 4 to 3, but not from 4 to one by swiping to the right. Maybe "overflowing" is the right term here? – bytecode77 Jul 16 '16 at 00:24
  • Have not tried `slidejs`, though documentation provides a `complete` callback for each slide where `number` is slide number at end of animation. If `#4` is reached you could disable or reset slideshow? Is expected result `#1` ->`#4`, `#4` -> `#3`? Or stop at `#4`, stop at `#1`? – guest271314 Jul 16 '16 at 00:27
  • This callback could potentially work, but some of the slides only have two pages, so comparing numbers would not tell me the direction swiped. – bytecode77 Jul 16 '16 at 00:30
  • Have a look at line 451 of `jquery.slide.js` I think the key is there. I just downloaded it... so... Don't ask me what to do next!! lol But this looks like what you need to fix : `if (next === this.data.total) {next = 0;}` – Louys Patrice Bessette Jul 16 '16 at 00:36
  • Line 451 appears to be within body `._slide` function. You could probably implement process without using a plugin – guest271314 Jul 16 '16 at 00:43
  • @guest271314 I' talking about line 451 of the downloaded .zip file `jquery.slide.js` from http://www.slidesjs.com/ – Louys Patrice Bessette Jul 16 '16 at 00:44
  • If I understood, this can be helpfull http://thinsoldier.github.io/externals/slidesjs/examples/thn-validate-before-next/ – daremachine Jul 16 '16 at 00:46
  • https://github.com/nathansearles/Slides/blob/SlidesJS-3/source/jquery.slides.js#L451 ? – guest271314 Jul 16 '16 at 00:46
  • Exactly @guest271314... I think this is the key. But what to do with it depends on what bytecode77 wants to do... ;) – Louys Patrice Bessette Jul 16 '16 at 00:47
  • @daremachine this doesn't work with swiping (tested in Chrome dev tools) ; guest271314 this is the right place, but just changing the lines will result in strange behavior. There's probably a lot more to change, which I'm currently looking into. – bytecode77 Jul 16 '16 at 00:53
  • The big question is what do you want to happen when last image is diplayed + left swipe. (Same question for first image + right swipe)... Just disable ? Like no swipe effect ? – Louys Patrice Bessette Jul 16 '16 at 00:57
  • @bytecode77 callback, it tell you direction in start is different number than complete right? – daremachine Jul 16 '16 at 00:58
  • look for idea on Mike answer http://stackoverflow.com/questions/6543478/how-to-stop-and-reset-slides-jquery-js – daremachine Jul 16 '16 at 01:00

1 Answers1

2

Guys! I made it.
It took a couple hours.

The initial recreated problem is here

And my working solution, as explained below, is here.

I found where to put a switch to this looping effect.
AND I setted it as a new option ==> looping (true/false) !!!
If the looping option is set to false... It won't loop.

defaults = {
  width: 940,
  height: 528,
  start: 1,
  navigation: {
    active: true,
    effect: "slide"
  },
  pagination: {
    active: true,
    effect: "slide"
  },
  play: {
    active: false,
    effect: "slide",
    interval: 5000,
    auto: false,
    swap: true,
    pauseOnHover: false,
    restartDelay: 2500
  },
  effect: {
    slide: {
      speed: 500
    },
    fade: {
      speed: 300,
      crossfade: true
    }
  },
  callback: {
    loaded: function() {},
    start: function() {},
    complete: function() {}
  },
  looping: false                    // Looping effect from last image to first and vice-versa
};



I slightly modified the Plugin.prototype._slide function to achieve this.
I added a new condition based on a var which I called OK_Proceed.

This var is true by default.
Its value becomes false when trying to go to the image index -1 or data.total... But only if the looping option is set to false.

I wished to preserve the original function...
;)

var OK_Proceed=true;                                // ADDED var
    console.log( this.options.looping );
    if (next === -1) {
      if( this.options.looping ){
        next = this.data.total - 1;
      }else{
          OK_Proceed=false;
      }
    }
    if (next === this.data.total) {
      if( this.options.looping ){
          next = 0;
      }else{
          OK_Proceed=false;
      }
    }

When this OK_Proceed is false : The script bypasses the animate function entierely.
It is replaced by a small 10px "bounce" effect.

The only thing left to do is to reset the data.animating value:

$.data(_this, "animating", false);

So here is the full function:

Plugin.prototype._slide = function(number) {            console.log("Line 430 - _slide: ");
  var $element, currentSlide, direction, duration, next, prefix, slidesControl, timing, transform, value,
    _this = this;
  $element = $(this.element);
  this.data = $.data(this);                             console.log( JSON.stringify( $.data(this) ) );
  if (!this.data.animating && number !== this.data.current + 1) {
    $.data(this, "animating", true);
    currentSlide = this.data.current;               console.log("Line 437 - currentSlide: "+currentSlide);
    if (number > -1) {
      number = number - 1;
      value = number > currentSlide ? 1 : -1;               console.log("Line 440 - value: "+value);
      direction = number > currentSlide ? -this.options.width : this.options.width;
      next = number;
    } else {
      value = this.data.direction === "next" ? 1 : -1;
      direction = this.data.direction === "next" ? -this.options.width : this.options.width;
      next = currentSlide + value;                  console.log("Line 446 - next: "+next);
    }   var OK_Proceed=true;                                // ADDED var
    console.log( this.options.looping );
    if (next === -1) {
      if( this.options.looping ){
        next = this.data.total - 1;
      }else{
          OK_Proceed=false;
      }
    }
    if (next === this.data.total) {
      if( this.options.looping ){
          next = 0;
      }else{
          OK_Proceed=false;
      }
    }
    if(OK_Proceed){this._setActive(next);                           // ADDED condition
    slidesControl = $(".slidesjs-control", $element);
    if (number > -1) {
      slidesControl.children(":not(:eq(" + currentSlide + "))").css({
        display: "none",
        left: 0,
        zIndex: 0
      });
    }
    slidesControl.children(":eq(" + next + ")").css({
      display: "block",
      left: value * this.options.width,
      zIndex: 10
    });
    this.options.callback.start(currentSlide + 1);
    if (this.data.vendorPrefix) {
      prefix = this.data.vendorPrefix;
      transform = prefix + "Transform";
      duration = prefix + "TransitionDuration";
      timing = prefix + "TransitionTimingFunction";
      slidesControl[0].style[transform] = "translateX(" + direction + "px)";
      slidesControl[0].style[duration] = this.options.effect.slide.speed + "ms";
      return slidesControl.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd", function() {
        slidesControl[0].style[transform] = "";
        slidesControl[0].style[duration] = "";
        slidesControl.children(":eq(" + next + ")").css({
          left: 0
        });
        slidesControl.children(":eq(" + currentSlide + ")").css({
          display: "none",
          left: 0,
          zIndex: 0
        });
        $.data(_this, "current", next);
        $.data(_this, "animating", false);
        slidesControl.unbind("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd");
        slidesControl.children(":not(:eq(" + next + "))").css({
          display: "none",
          left: 0,
          zIndex: 0
        });
        if (_this.data.touch) {
          _this._setuptouch();
        }
        return _this.options.callback.complete(next + 1);
      });
    } else {
      return slidesControl.stop().animate({
        left: direction
      }, this.options.effect.slide.speed, (function() {
        slidesControl.css({
          left: 0
        });
        slidesControl.children(":eq(" + next + ")").css({
          left: 0
        });
        return slidesControl.children(":eq(" + currentSlide + ")").css({
          display: "none",
          left: 0,
          zIndex: 0
        }, $.data(_this, "current", next), $.data(_this, "animating", false), _this.options.callback.complete(next + 1));
      }));
    } } else { 
    console.log("HERE");
    $.data(_this, "animating", false);
    console.log( JSON.stringify( $.data(this) ) );

    // Bouncing effect
    $(".slidesjs-control").stop().animate( { "left" : "-=10px" }, 100, "easeInOutBounce", function(){
        $(".slidesjs-control").animate( { "left" : "+=10px" }, 100, "easeInOutBounce");
    });

     }                      // End added condition
  }
};

I cleaned this code from all the console.logs and created a zip file ready to use.




The day after EDIT
There was two other functions to modify in order to make the "touch" behave the same as mouse clicked links... The .zip file above also reflects these changes...

Function modified for click is : _slide.
Functions modified for click are : _setuptouch and _touchmove.

Two classes are available for you to modify : bounceForward and bounceBackward.

The lastest demo is here. Try it on a touch enabled device.

Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
  • This is what I tried, too. And it causes wonky behavior so it's not entirely fixing it. – bytecode77 Jul 16 '16 at 01:02
  • I'm not sure how to put this. Maybe *undefined behavior* is the right technical term here. Basically, a blank page is displayed. – bytecode77 Jul 16 '16 at 01:04
  • Also instead of canceling the event and bringing back the page, I would rather bounce it, like if "there was nothing there". Just like bouncing is implemented in iOS with the page itself. – bytecode77 Jul 16 '16 at 01:06
  • This line `value = this.data.direction === "next" ? 1 : -1;` is a clue (line 444). There is something about data "direction" – Louys Patrice Bessette Jul 16 '16 at 01:07
  • I just found that `this.data.direction` can hold one of these 2 values `next` or `previous`... See between lines 223 and 250. --- (I just added the @guest271314's github link.. for line refs... Thanks again guest271314 !!) – Louys Patrice Bessette Jul 16 '16 at 01:15
  • Hoo... Getting fuzzed here. See what hapens to `direction` on line 445: If value == next -> direction = `-this.options.width` else -> direction = `this.options.width`....... Then used on lline 474 as an integrer +px.... Ayayaille.... Am I getting lost ? .oO(lol) – Louys Patrice Bessette Jul 16 '16 at 01:33
  • At first, I would like to thank you for the effort you have spent on this! However, I tested it using Chrome dev tools and its touch feature. When overswiping, it doesn't bounce, but stays. Is there a solution to make it bounce? – bytecode77 Jul 16 '16 at 16:40
  • You mean... To clearly show that the swipe has been triggered ? It could be added to the `else` part of the added condition... I guess. – Louys Patrice Bessette Jul 16 '16 at 16:43
  • It's hard to explain, but I'll make a video of it when I'm back home :) – bytecode77 Jul 16 '16 at 16:59
  • Sorry to keep you waiting. I uploaded a video of what I mean here: http://sendvid.com/pin0ktd1 – bytecode77 Jul 17 '16 at 13:51
  • Outch! This really is surprising. ehw.... I think the fct `touchmove` also needs a fix. Did you try it on pc ? – Louys Patrice Bessette Jul 17 '16 at 14:52
  • Ok... I found something in `setuptouch` Hang on! ;) – Louys Patrice Bessette Jul 17 '16 at 14:59
  • Hey... I think I fixed the touch issue. Try this : https://www.bessetteweb.com/SO/38406561/2016-07-14-jsSlides-with-looping-option2.html – Louys Patrice Bessette Jul 17 '16 at 16:50
  • 1
    Very close! :) Do you think you can implement bouncing as well? – bytecode77 Jul 17 '16 at 16:58
  • Updated.... I could play a long time to make a smooter bounce effect... Maybe. I'll let you know When I'll be satisfied of it. ;) – Louys Patrice Bessette Jul 17 '16 at 17:12
  • That's not what I meant with bouncing. Bouncing is the effect that you get when you swipe down a list and try to swipe further than the actual list goes. Try it in any list and drag it to the bottom and then try to drag it further. It's hard to put in words, but I think this is my best way of putting it. – bytecode77 Jul 17 '16 at 17:55
  • Where I actually am... Is that I added a class named `bounceBackward` when trying to swipe to picture "-1" and `bounceFoward` when trying to swipe to picture "total"... So the animation is in CSS @keyFrame. It could be whatever you want. I could update the .zip flie for you to play with. ;) But I still have a problem to fix since the image strangely don't *always* end at `left:0px`. – Louys Patrice Bessette Jul 17 '16 at 18:03
  • .zip file is upgraded on my server. Try it. ;) It the [same link](https://www.bessetteweb.com/SO/38406561/zip/SlidesJS-with-looping-option.zip) as in the answer... I made a readme.txt – Louys Patrice Bessette Jul 17 '16 at 18:33
  • For people to now... I fixed the @Keyframe 100% `left:0px` not always obeying with [this SO answer](http://stackoverflow.com/a/6210785/2159528) which I wish I could upvote more than once. :D – Louys Patrice Bessette Jul 17 '16 at 18:42
  • This is what I meant with bouncing: http://www.imagebam.com/image/2a28e5495462628 - Once you swipe too far, you can drag into an empty space until you remove your finger, then it moves back. How can this be applied to your solution? – bytecode77 Jul 17 '16 at 18:48
  • I tried to use to value of "touchend - touchstart"... But it creates a strange bug when the image has been translated to more than the half of the screen. The plugin releases it as it was not the current image anymore. It becomes complex... If what I already done wasn't. ;) If I find something... I'll let you know for sure. But not today. – Louys Patrice Bessette Jul 17 '16 at 19:04
  • I think that playing with the @keyframe I "inserted" into it (in the HTML file) would simulate something close to what you want. – Louys Patrice Bessette Jul 17 '16 at 19:09
  • 1
    Anyway, you gave me a very good start and thank you so much for your time you spent on this! +1!! – bytecode77 Jul 17 '16 at 19:14