/* * S6 1.5.1 - 3D Mobile Touch Slider * http://www.idangero.us/sliders/s6/ * * Copyright 2012-2013, Vladimir Kharlampidi * The iDangero.us * http://www.idangero.us/ * * Licensed under iDangero.us Regular License (RL): * http://www.idangero.us/index.php?content=article&id=21 * * Updated on: November 18, 2013 */ (function($){ $.fn.s6 = function(params){ var _this = $(this) if ( _this.length==0 ) return _this; //Default Parameters var defaults = { mode : 'horizontal', // or 'vertical' touchRatio : 1, dynamicShadow:false, dynamicShadowOffset:20, dynamicShadowScale:0.9, speed : 500, followFinger:true, freeMode : false, freeModeFluid : false, setPerspective: true, perspective:1000, simulateTouch: true, autoPlay:false, grabCursor:true, onlyExternal : false, createPagination : true, createBackFaces: true, pagination : false, paginationElement: 'span', paginationClickable: false, preventLinks : true, keyboardControl: false, shortSwipes: true, resizeEvent : 'auto', //or 'resize' or 'orientationchange' //Auto Resize autoResize : true, //Namespace slideElement : 'div', slideClass : 's6-slide', wrapperClass : 's6-wrapper', paginationClass: 's6-pagination-switch', paginationActiveClass : 's6-active-switch' } params = params || {}; for (var prop in defaults) { if (! (prop in params)) { params[prop] = defaults[prop] } } //Some default vars var isScrolling; var isHorizontal = params.mode=='horizontal'; //Check to prevent double init if ( _this.find('.s6-slide-top').length>0 ) return //3D Test function isSupport3D() { var div = document.createElement('div'); div.id = 'test3d'; var s3d=false; if("webkitPerspective" in div.style) s3d=true; if("MozPerspective" in div.style) s3d=true; if("OPerspective" in div.style) s3d=true; if("MsPerspective" in div.style) s3d=true; if("perspective" in div.style) s3d=true; /* Test with Media query for Webkit to prevent FALSE positive*/ if(s3d && ("webkitPerspective" in div.style) ) { var st = document.createElement('style'); st.textContent = '@media (-webkit-transform-3d), (transform-3d), (-moz-transform-3d), (-o-transform-3d), (-ms-transform-3d) {#test3d{height:5px}}' document.getElementsByTagName('head')[0].appendChild(st); document.body.appendChild(div); s3d = div.offsetHeight === 5;; st.parentNode.removeChild(st); div.parentNode.removeChild(div); } return s3d; } //WP8 IE10 Fix if (params.mode=='horizontal') _this.addClass('s6-wp8-horizontal') else _this.addClass('s6-wp8-vertical') if (!isSupport3D() || window.navigator.msPointerEnabled) { if (window.Swiper) { _this.css({overflow:'hidden'}); _this.find('.'+params.slideClass) .css('float','left') .css('position','relative') .css('visibility','visible') return new Swiper(_this.selector, params) } } //Default Faces BG params.faces = params.faces || {}; params.faces.left = params.faces.left || '#555' params.faces.right = params.faces.right || '#888' params.faces.top = params.faces.top || '#888' params.faces.bottom = params.faces.bottom || '#555' //s6 object var _isSafari = navigator.userAgent.indexOf('Safari')>=0 && navigator.userAgent.indexOf('Chrome')<0 && navigator.userAgent.indexOf('Android')<0; var _isUiWebView = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent) && navigator.userAgent.indexOf('Android')<0; var s6 = { container : _this, wrapper : _this.find('.' + params.wrapperClass), slides : _this.find('.' + params.slideClass), params : params, touches : {}, rotates : {}, times : {}, isSupport3D : isSupport3D(), activeSlide : 0, isSafari : _isSafari, isUiWebView : _isUiWebView } //isHorizontal Function function isH() { return s6.params.mode=='horizontal' } //Init Slider Dimensions s6.init = function() { s6.width = _this.width() s6.height = _this.height() var factor = isH() ? s6.width : s6.height s6.wrapper.css({ width : s6.width, height: s6.height, '-moz-transform-origin': s6.width/2+'px '+factor/2+'px -'+factor/2+'px', '-webkit-transform-origin': s6.width/2+'px '+factor/2+'px -'+factor/2+'px', '-ms-transform-origin': s6.width/2+'px '+factor/2+'px -'+factor/2+'px', '-o-transform-origin': s6.width/2+'px '+factor/2+'px -'+factor/2+'px', 'transform-origin': s6.width/2+'px '+factor/2+'px -'+factor/2+'px' }) s6.wrapper.find('.' + params.slideClass).css({ width: s6.width, height: s6.height }) } s6.init() //Set Transform styles if (s6.params.setPerspective===true) { s6.container.css({ '-webkit-perspective': s6.params.perspective, '-moz-perspective': s6.params.perspective, '-ms-perspective': s6.params.perspective, '-o-perspective': s6.params.perspective, 'perspective': s6.params.perspective }) } s6.wrapper.find('.' + params.slideClass).css({ width: s6.width, height: s6.height }) //Check number of Slides to enable infinite mode s6.numOfSlides = s6.wrapper.find('.s6-slide').length if (s6.numOfSlides!=4) s6.inf = true else s6.inf = false //Hide All Slides in infinite mode on initialization if (s6.inf) { s6.slides.not(':eq(0)').hide() } // function setSide(e,side) { if (!e) return; var t = ''; var isSafari = s6.isSafari || s6.isUiWebView; var origin = false; switch(side) { case 'front' : { t = 'translate3d(0px, 0px, 0px) rotateY(0deg)'; if (isSafari) { if (isH()) t = 'translate3d(0px, 0px, '+s6.width/2+'px) rotateY(0deg)'; else t = 'translate3d(0px, 0px, '+s6.height/2+'px) rotateY(0deg)'; if(isH()) origin = '50% 50% '+s6.width/2+'px'; else origin = '50% 50% '+s6.height/2+'px'; } }; break; case 'right': { if (isH()) { t = 'translate3d('+(s6.width/2)+'px, 0px, '+(-s6.width/2)+'px) rotateY(90deg)' } else t = 'translate3d('+(s6.width-s6.height/2)+'px, 0px, '+(-s6.height/2)+'px) rotateY(90deg)' }; break; case 'back': { if (isH()) { t = 'translate3d(0px, 0px, '+(-s6.width)+'px) rotateY(180deg)'; if (isSafari) { t = 'translate3d(0px, 0px, '+(-s6.width/2)+'px) rotateY(180deg)'; origin = '50% 50% '+-s6.width/2+'px' } } else { t = 'translate3d(0px, 0px, '+(-s6.height)+'px) rotateX(180deg)'; if (isSafari) { t = 'translate3d(0px, 0px, '+(-s6.height/2)+'px) rotateX(180deg)'; origin = '50% 50% '+-s6.height/2+'px' } } }; break; case 'left': { if (isH()) t = 'translate3d('+(-s6.width/2)+'px, 0px, '+(-s6.width/2)+'px) rotateY(-90deg)'; else t = 'translate3d('+(-s6.height/2)+'px, 0px, '+(-s6.height/2)+'px) rotateY(-90deg)'; }; break; case 'top': { if (isH()) t = 'translate3d(0px, '+(-s6.width/2)+'px, '+(-s6.width/2)+'px) rotateX(90deg)'; else t = 'translate3d(0px, '+(-s6.height/2)+'px, '+(-s6.height/2)+'px) rotateX(90deg)'; }; break; case 'bottom': { if (isH()) t = 'translate3d(0px, '+(s6.height-s6.width/2)+'px, '+(-s6.width/2)+'px) rotateX(-90deg)'; else t = 'translate3d(0px, '+(s6.height/2)+'px, '+(-s6.height/2)+'px) rotateX(-90deg)' }; break; } var es=e.style es.webkitTransform = es.MsTransform = es.msTransform = es.MozTransform = es.OTransform = es.transform = t if (isSafari && origin) { es.webkitTransformOrigin = es.transformOrigin = origin; } } //Set Slides on sides s6.setSlides = function() { s6.slides.each(function(){ $(this) .removeClass('s6-slide-top') .removeClass('s6-slide-left') .removeClass('s6-slide-right') .removeClass('s6-slide-bottom') .removeClass('s6-slide-front') .removeClass('s6-slide-back') }) //Set Slides Side-Classes if (!s6.inf) { s6.slides.eq(0).addClass('s6-slide-front') s6.slides.eq(2).addClass('s6-slide-back') if (isH()) { s6.slides.eq(1).addClass('s6-slide-right') s6.slides.eq(3).addClass('s6-slide-left') } else { s6.slides.eq(1).addClass('s6-slide-bottom') s6.slides.eq(3).addClass('s6-slide-top') } } else { s6.slides.eq(0).addClass('s6-slide-front') } s6.slides.each(function(){ if (s6.inf) return var slide = $(this) var _slide = slide[0] if ( slide.hasClass('s6-slide-front') ) { setSide(_slide,'front'); } if ( slide.hasClass('s6-slide-right') ) { setSide(_slide,'right'); } if ( slide.hasClass('s6-slide-left') ) { setSide(_slide,'left'); } if ( slide.hasClass('s6-slide-back') ) { setSide(_slide,'back'); } if ( slide.hasClass('s6-slide-top') ) { setSide(_slide,'top'); } if ( slide.hasClass('s6-slide-bottom')) { setSide(_slide,'bottom'); } }) //Dynamic Shadow if (s6.params.dynamicShadow) { if (s6.container.find('.s6-dynamic-shadow').length>0) { s6.container.find('.s6-dynamic-shadow').remove() } var scale = s6.params.dynamicShadowScale; var offset = s6.params.dynamicShadowOffset if (isH()) s6.wrapper.append('
') else s6.container.append('') s6.shadow = s6.container.find('.s6-dynamic-shadow') var shadowTransform = isH() ? ( 'scale3d('+scale+', 1, '+scale+') translate3d(0px, '+(s6.height-s6.width/2 + offset)+'px, '+(-s6.width/2 / scale)+'px) rotateX(-90deg)' ) : ( 'scale3d('+scale+', 1, '+scale+') translate3d(0px, '+(s6.height/2 + offset)+'px, '+(-s6.height/2/scale)+'px) rotateX(-90deg)' ) var ss = s6.shadow[0].style ss.webkitTransform = ss.MsTransform = ss.MozTransform = ss.OTransform = ss.transform = shadowTransform ss.width = s6.width+'px'; ss.height = (isH() ? s6.width : s6.height) + 'px' } //Add Sub-Faces if (isH()) { if (!s6.params.createBackFaces) return s6.wrapper.find('.s6-slide-top, .s6-slide-bottom').remove() s6.wrapper.append('') //Top Slide s6.wrapper.find('.s6-slide-top').css({ width: s6.width, height: s6.width, background: params.faces.top }) var ts = s6.wrapper.find('.s6-slide-top')[0] setSide(ts,'top'); //Bottom Slide s6.wrapper.find('.s6-slide-bottom').css({ width: s6.width, height: s6.width, background: params.faces.bottom }) var bs = s6.wrapper.find('.s6-slide-bottom')[0] setSide(bs,'bottom'); } else { if (!s6.params.createBackFaces) return s6.wrapper.find('.s6-slide-left, .s6-slide-right').remove() s6.wrapper.append('') //Left Slide s6.wrapper.find('.s6-slide-left').css({ width: s6.height, height: s6.height, background: params.faces.left }) var ls = s6.wrapper.find('.s6-slide-left')[0] setSide(ls,'left'); //Right Slide s6.wrapper.find('.s6-slide-right').css({ width: s6.height, height: s6.height, background: params.faces.right }) var rs = s6.wrapper.find('.s6-slide-right')[0] setSide(rs,'right'); } } s6.setSlides() //Set Visibility after all slides are transformed s6.wrapper.find('.'+s6.params.slideClass).css({visibility:'visible'}) /*========================= Grab Cursor ===========================*/ if (params.grabCursor) { s6.container[0].style.cursor = 'move'; s6.container[0].style.cursor = 'grab'; s6.container[0].style.cursor = '-moz-grab'; s6.container[0].style.cursor = '-webkit-grab'; } //Set Slides for infinite mode function setInfSlides(nextIndex, prevIndex) { var _rotate = isH() ? getRotate().y : getRotate().x var rotate = Math.abs(_rotate) rotate = rotate - Math.floor(rotate/360)*360 var nextIndex = (prevIndex===0 || nextIndex) ? nextIndex : s6.activeSlide+1 >= s6.numOfSlides ? 0 : s6.activeSlide+1 var prevIndex = (prevIndex===0 || prevIndex) ? prevIndex : s6.activeSlide-1 < 0 ? s6.numOfSlides-1 : s6.activeSlide-1 if (prevIndex==s6.activeSlide) { prevIndex = s6.activeSlide-1 < 0 ? s6.numOfSlides-1 : s6.activeSlide-1 } if (nextIndex==s6.activeSlide) { nextIndex = s6.activeSlide+1 >= s6.numOfSlides ? 0 : s6.activeSlide+1 } if(nextIndex===prevIndex && nextIndex > s6.activeSlide) { prevIndex = 'undefined' } var nextSlide = s6.slides.eq(nextIndex) var _nextSlide = nextSlide[0] var prevSlide = (prevIndex!='undefined') ? s6.slides.eq(prevIndex) : false var _prevSlide = prevSlide[0] //Hide Slides s6.slides.each(function(){ var index = $(this).index() if (index!=nextIndex&&index!=prevIndex&&index!=s6.activeSlide) { $(this).hide() } }) if (isH()) { if (rotate==0) { setSide(_nextSlide,'right'); setSide(_prevSlide,'left'); } if (rotate==90 || ( rotate==270&&_rotate>0 ) ) { setSide(_nextSlide,'back'); setSide(_prevSlide,'front'); } if (rotate===180) { setSide(_nextSlide,'left'); setSide(_prevSlide,'right'); } if ((rotate===270&&_rotate<0) || (rotate==90&&_rotate>0)) { setSide(_nextSlide,'front'); setSide(_prevSlide,'back'); } } else { if (rotate==0) { setSide(_nextSlide,'bottom'); setSide(_prevSlide,'top'); } if (rotate==90 || ( rotate==270&&_rotate<0 ) ) { setSide(_nextSlide,'back'); setSide(_prevSlide,'front'); } if (rotate===180) { setSide(_nextSlide,'top'); setSide(_prevSlide,'bottom'); } if ((rotate===270&&_rotate>0) || (rotate==90&&_rotate<0)) { setSide(_nextSlide,'front'); setSide(_prevSlide,'back'); } } nextSlide.show() if(prevIndex!='undefined') prevSlide.show() } //Resize Fix if (s6.params.autoResize) { if (params.resizeEvent=='auto') { if ('onorientationchange' in window) params.resizeEvent = 'orientationchange' else params.resizeEvent = 'resize' } window.addEventListener(params.resizeEvent, resizeS6Fix, false); } function resizeS6Fix() { s6.init() s6.setSlides() swipeReset(true) } //Add 'active' class to the front slide on start s6.wrapper.find('.s6-slide-front').addClass('s6-slide-active') //Pagination if (s6.params.pagination != false ) { if (s6.params.createPagination) { var paginationHTML = "" for (var i=1; i <= s6.slides.length; i ++ ) { paginationHTML+='<'+params.paginationElement+' class="'+s6.params.paginationClass+'">'+params.paginationElement+'>'; } $(s6.params.pagination).html(paginationHTML) if (params.paginationClickable) { $('.'+s6.params.paginationClass).on('click', function(){ s6.swipeTo($(this).index()) }) } } $(s6.params.pagination).children().eq(0).addClass( s6.params.paginationActiveClass ) } //Prevent Links s6.allowLinks = true; if (params.preventLinks) { s6.container.find('a').on('click', function(e){ if (!s6.allowLinks) { e.preventDefault(); return false; } }) } //Keyboard Control if (params.keyboardControl) { $(document).on('keydown', handleKeyboardKeys); } function handleKeyboardKeys (e) { var kc = e.keyCode || e.charCode; if (kc==37 || kc==39 || kc==38 || kc==40) { var inView = false; //Check that swiper should be inside of visible area of window var s6Offset = s6.container.offset(); var scrollLeft = $(window).scrollLeft() var scrollTop = $(window).scrollTop(); var windowWidth = $(window).width(); var windowHeight = $(window).height(); var s6Coord = [ [s6Offset.left, s6Offset.top], [s6Offset.left + s6.width, s6Offset.top], [s6Offset.left, s6Offset.top + s6.height], [s6Offset.left + s6.width, s6Offset.top + s6.height] ] for (var i=0; i