Last Updated: February 25, 2016
·
15.07K
· gaqzi

A pinch-zoom enabled slider gallery with Swiper and iScroll

In a project I worked on I had a slider gallery with magazine pages and
on most devices the pages could not be read unless they were zoomed
in. As this was a Cordova project the natural fit was a using pinch-zoom
as well as tap-to-zoom.

The easiest solution I found for zooming was [iScroll] and it
worked like a charm, after I made it forget about that it was in a
[Swiper] slider.

All pages were laid out with horizontal scrolling/swiping, this
technique should work as well with vertical just swap out originX
for originY and wrapperOffsetLeft for wrapperOffsetTop.

The areas of the iScroll code I read to get this setup:

HTML:

<div class="swiper-container">
  <div class="swiper-wraper">

      <div class="swiper-slide"> <img src="[...]"> </div>
      [... more slides ...]

  </div>
</div>

iScroll/Swiper setup:

var _enableZoom = _activateZoom: (function() {
  var scroller = undefined;

  return function(swiper) {
    if(scroller !== undefined) {
      scroller.destroy();
    }

    scroller = new iScroll(swiper.activeSlide(), {
      hideScrollbar: true,
      zoom: true,
      // So Swiper will not swipe/slide when zooming is enabled
      onZoomEnd: function(e) {
        var slide = $(this.wrapper);

        if(parseInt(this.scale) == 1) {
          slide.removeClass('swiper-no-swiping');
        } else {
          slide.addClass('swiper-no-swiping');
        }
      },
      // Since the images are inside of the swiper slide it
      // got a huge left offset, but the offset isn't really
      // part of the page/image since the page is completely
      // shown within the viewable area of the viewport. So
      // simply remove the wrapperOffsetLeft from the
      // calculation and be happy.
      //
      // touchstart: When pinch-zooming
      // touchend: When double-tap zooming
      onZoomStart: function(e) {
        if(e.type === 'touchstart') {
          this.originX = Math.abs(e.touches[0].pageX + e.touches[1].pageX) / 2 - this.x;
        } else if(e.type === 'touchend') {
          this.wrapperOffsetLeft = 0;
        }
      }
    })
  };
})();


$('.swiper-container').swiper({
  noSwiping: true, // So swiping can be disabled with a class
  onSlideChangeEnd: _enableZoom,
  onFirstInit: _enableZoom
});

[iScroll]: http://cubiq.org/iscroll-4
[Swiper]: http://www.idangero.us/sliders/swiper/

2 Responses
Add your response

timmyroseen: I set it on every image, when it swipes I check if the scroller variable is not undefined and then call destroy on it. I want to remember I had some issues when I had it cover the entire containing element.

over 1 year ago ·

It gaves me an error on the first .js line:
"Uncaught SyntaxError: Unexpected token : "

over 1 year ago ·

Have a fresh tip? Share with Coderwall community!

Post
Post a tip
Did you know?

JavaScript on a page runs with the privileges of that origin. One altered library, tag manager, or snippet can read inputs, change what people see, and call your APIs as the user.

Security insights from Cside