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 : "
Have a fresh tip? Share with Coderwall community!
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