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:
- Pinch-to-zoom call onZoomStart
- Pinch-to-zoom calculate zooming
- Tap-to-zoom call onZoomStart
- Tap-to-zoom actually being done
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/
Written by Björn Andersson
Related protips
2 Responses
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.
It gaves me an error on the first .js line:
"Uncaught SyntaxError: Unexpected token : "