bytecode77 bytecode77 - 4 months ago 18
Javascript Question

Disable "wrap around" in SlidesJS

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?

Answer

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.

Comments