diff --git a/README.md b/README.md index de135e4..f1c7a95 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -SwipeView v0.12 - 2011-12-17 +SwipeView v1.0 - 2012-08-25 ============================ -Virtually infinite loop-able horizontal carousel for mobile webkit (in 4kb). +Virtually infinite loop-able horizontal carousel for desktop and mobile browsers. Read more at [cubiq.org](http://cubiq.org/swipeview) diff --git a/demo/gallery/style.css b/demo/gallery/style.css index 1f14124..c1217be 100644 --- a/demo/gallery/style.css +++ b/demo/gallery/style.css @@ -4,7 +4,15 @@ body { margin:0; background:#333; -webkit-user-select:none; - -webkit-text-size-adjust:none; + -moz-user-select:none; + -ms-user-select:none; + -o-user-select:none; + user-select:none; + -webkit-text-size-adjust:none; + -moz-text-size-adjust:none; + -ms-text-size-adjust:none; + -o-text-size-adjust:none; + text-size-adjust:none; color:#eee; font-family:helvetica; font-size:12px; @@ -27,6 +35,10 @@ body { padding:0; margin:0 0 0 -100px; -webkit-border-radius:10px; + -moz-border-radius:10px; + -ms-border-radius:10px; + -o-border-radius:10px; + border-radius:10px; } #nav li { @@ -35,6 +47,10 @@ body { width:14px; height:14px; line-height:14px; -webkit-border-radius:7px; + -moz-border-radius:7px; + -ms-border-radius:7px; + -o-border-radius:7px; + border-radius:7px; background:rgba(255,255,255,0.1); overflow:hidden; padding:0; @@ -59,9 +75,25 @@ body { #swipeview-slider > div { position:relative; display:-webkit-box; + display:-moz-box; + display:-ms-box; + display:-o-box; + display:box; -webkit-box-orient:vertical; + -moz-box-orient:vertical; + -ms-box-orient:vertical; + -o-box-orient:vertical; + box-orient:vertical; -webkit-box-pack:center; + -moz-box-pack:center; + -ms-box-pack:center; + -o-box-pack:center; + box-pack:center; -webkit-box-align:center; + -mox-box-align:center; + -ms-box-align:center; + -o-box-align:center; + box-align:center; overflow:hidden; } @@ -69,9 +101,25 @@ body { display:block; border:5px solid #eee; -webkit-box-shadow:0 2px 6px #000; + -moz-box-shadow:0 2px 6px #000; + -ms-box-shadow:0 2px 6px #000; + -o-box-shadow:0 2px 6px #000; + box-shadow:0 2px 6px #000; -webkit-border-radius:2px; + -moz-border-radius:2px; + -ms-border-radius:2px; + -o-border-radius:2px; + border-radius:2px; -webkit-transition-duration:.4s; + -moz-transition-duration:.4s; + -ms-transition-duration:.4s; + -o-transition-duration:.4s; + transition-duration:.4s; -webkit-transition-property:opacity; + -moz-transition-property:opacity; + -ms-transition-property:opacity; + -o-transition-property:opacity; + transition-property:opacity; opacity:1; pointer-events:none; } @@ -89,14 +137,42 @@ body { text-shadow:0 1px 0 #000; border-top:1px solid rgba(255,255,255,0.2); -webkit-border-top-left-radius:10px; + -moz-border-top-left-radius:10px; + -ms-border-top-left-radius:10px; + -o-border-top-left-radius:10px; + border-top-left-radius:10px; -webkit-border-top-right-radius:10px; + -moz-border-top-right-radius:10px; + -ms-border-top-right-radius:10px; + -o-border-top-right-radius:10px; + border-top-right-radius:10px; -webkit-transition-duration:.3s; + -moz-transition-duration:.3s; + -ms-transition-duration:.3s; + -o-transition-duration:.3s; + transition-duration:.3s; -webkit-transition-property:-webkit-transform; - -webkit-transform:translate3d(0,100%,0); + -moz-transition-property:-moz-transform; + -ms-transition-property:-ms-transform; + -o-transition-property:-o-transform; + transition-property:transform; + -webkit-transform:translate(0,100%) translateZ(0); + -moz-transform:translate(0,100%) translateZ(0); + -ms-transform:translate(0,100%); + -ms-transform:translate(0,100%) translateZ(0); + -o-transform:translate(0,100%); + -o-transform:translate(0,100%) translateZ(0); + transform:translate(0,100%) translateZ(0); } #swipeview-slider .swipeview-active span { - -webkit-transform:translate3d(0,0,0); + -webkit-transform:translate(0,0) translateZ(0); + -moz-transform:translate(0,0) translateZ(0); + -ms-transform:translate(0,0); + -ms-transform:translate(0,0) translateZ(0); + -o-transform:translate(0,0); + -o-transform:translate(0,0) translateZ(0); + transform:translate(0,0) translateZ(0); } #wrapper > div > .swipeview-loading { @@ -109,11 +185,21 @@ body { #wrapper > div > .swipeview-loading img, #swipeview-slider img.loading { - -webkit-transition-duration:0; + -webkit-transition-duration:0s; opacity:0; } #wrapper > div > .swipeview-loading span { - -webkit-transition-duration:0; - -webkit-transform:translate3d(0,100%,0); + -webkit-transition-duration:0s; + -moz-transition-duration:0s; + -ms-transition-duration:0s; + -o-transition-duration:0s; + transition-duration:0s; + -webkit-transform:translate(0,100%) translateZ(0); + -moz-transform:translate(0,100%) translateZ(0); + -ms-transform:translate(0,100%); + -ms-transform:translate(0,100%) translateZ(0); + -o-transform:translate(0,100%); + -o-transform:translate(0,100%) translateZ(0); + transform:translate(0,100%) translateZ(0); } \ No newline at end of file diff --git a/src/swipeview.js b/src/swipeview.js index 7a8174f..56b0a00 100644 --- a/src/swipeview.js +++ b/src/swipeview.js @@ -1,14 +1,58 @@ /*! - * SwipeView v0.10 ~ Copyright (c) 2011 Matteo Spinelli, http://cubiq.org + * SwipeView v1.0 ~ Copyright (c) 2012 Matteo Spinelli, http://cubiq.org * Released under MIT license, http://cubiq.org/license */ -var SwipeView = (function(){ - var hasTouch = 'ontouchstart' in window, +var SwipeView = (function (window, document) { + var dummyStyle = document.createElement('div').style, + vendor = (function () { + var vendors = 't,webkitT,MozT,msT,OT'.split(','), + t, + i = 0, + l = vendors.length; + + for ( ; i < l; i++ ) { + t = vendors[i] + 'ransform'; + if ( t in dummyStyle ) { + return vendors[i].substr(0, vendors[i].length - 1); + } + } + + return false; + })(), + cssVendor = vendor ? '-' + vendor.toLowerCase() + '-' : '', + + // Style properties + transform = prefixStyle('transform'), + transitionDuration = prefixStyle('transitionDuration'), + + // Browser capabilities + has3d = prefixStyle('perspective') in dummyStyle, + hasTouch = 'ontouchstart' in window, + hasTransform = !!vendor, + hasTransitionEnd = prefixStyle('transition') in dummyStyle, + + // Helpers + translateZ = has3d ? ' translateZ(0)' : '', + + // Events resizeEvent = 'onorientationchange' in window ? 'orientationchange' : 'resize', startEvent = hasTouch ? 'touchstart' : 'mousedown', moveEvent = hasTouch ? 'touchmove' : 'mousemove', endEvent = hasTouch ? 'touchend' : 'mouseup', cancelEvent = hasTouch ? 'touchcancel' : 'mouseup', + transitionEndEvent = (function () { + if ( vendor === false ) return false; + + var transitionEnd = { + '' : 'transitionend', + 'webkit' : 'webkitTransitionEnd', + 'Moz' : 'transitionend', + 'O' : 'oTransitionEnd', + 'ms' : 'MSTransitionEnd' + }; + + return transitionEnd[vendor]; + })(), SwipeView = function (el, options) { var i, @@ -35,7 +79,7 @@ var SwipeView = (function(){ div = document.createElement('div'); div.id = 'swipeview-slider'; - div.style.cssText = 'position:relative;top:0;height:100%;width:100%;-webkit-transition-duration:0;-webkit-transform:translate3d(0,0,0);-webkit-transition-timing-function:ease-out'; + div.style.cssText = 'position:relative;top:0;height:100%;width:100%;' + cssVendor + 'transition-duration:0;' + cssVendor + 'transform:translateZ(0);' + cssVendor + 'transition-timing-function:ease-out'; this.wrapper.appendChild(div); this.slider = div; @@ -44,7 +88,7 @@ var SwipeView = (function(){ for (i=-1; i<2; i++) { div = document.createElement('div'); div.id = 'swipeview-masterpage-' + (i+1); - div.style.cssText = '-webkit-transform:translateZ(0);position:absolute;top:0;height:100%;width:100%;left:' + i*100 + '%'; + div.style.cssText = cssVendor + 'transform:translateZ(0);position:absolute;top:0;height:100%;width:100%;left:' + i*100 + '%'; if (!div.dataset) div.dataset = {}; pageIndex = i == -1 ? this.options.numberOfPages - 1 : i; div.dataset.pageIndex = pageIndex; @@ -63,13 +107,15 @@ var SwipeView = (function(){ this.wrapper.addEventListener(startEvent, this, false); this.wrapper.addEventListener(moveEvent, this, false); this.wrapper.addEventListener(endEvent, this, false); - this.slider.addEventListener('webkitTransitionEnd', this, false); + this.slider.addEventListener(transitionEndEvent, this, false); + // in Opera >= 12 the transitionend event is lowercase so we register both events + if ( vendor == 'O' ) this.slider.addEventListener(transitionEndEvent.toLowerCase(), this, false); /* if (!hasTouch) { this.wrapper.addEventListener('mouseout', this, false); }*/ }; - + SwipeView.prototype = { currentMasterPage: 1, x: 0, @@ -108,7 +154,7 @@ var SwipeView = (function(){ this.wrapper.removeEventListener(startEvent, this, false); this.wrapper.removeEventListener(moveEvent, this, false); this.wrapper.removeEventListener(endEvent, this, false); - this.slider.removeEventListener('webkitTransitionEnd', this, false); + this.slider.removeEventListener(transitionEndEvent, this, false); /* if (!hasTouch) { this.wrapper.removeEventListener('mouseout', this, false); @@ -144,14 +190,14 @@ var SwipeView = (function(){ p = p < 0 ? 0 : p > this.options.numberOfPages-1 ? this.options.numberOfPages-1 : p; this.page = p; this.pageIndex = p; - this.slider.style.webkitTransitionDuration = '0'; + this.slider.style[transitionDuration] = '0s'; this.__pos(-p * this.pageWidth); this.currentMasterPage = (this.page + 1) - Math.floor((this.page + 1) / 3) * 3; this.masterPages[this.currentMasterPage].className = this.masterPages[this.currentMasterPage].className + ' swipeview-active'; - if (this.currentMasterPage == 0) { + if (this.currentMasterPage === 0) { this.masterPages[2].style.left = this.page * 100 - 100 + '%'; this.masterPages[0].style.left = this.page * 100 + '%'; this.masterPages[1].style.left = this.page * 100 + 100 + '%'; @@ -211,7 +257,8 @@ var SwipeView = (function(){ case resizeEvent: this.__resize(); break; - case 'webkitTransitionEnd': + case transitionEndEvent: + case 'otransitionend': if (e.target == this.slider && !this.options.hastyPageFlip) this.__flip(); break; } @@ -225,12 +272,12 @@ var SwipeView = (function(){ */ __pos: function (x) { this.x = x; - this.slider.style.webkitTransform = 'translate3d(' + x + 'px,0,0)'; + this.slider.style[transform] = 'translate(' + x + 'px,0)' + translateZ; }, __resize: function () { this.refreshSize(); - this.slider.style.webkitTransitionDuration = '0'; + this.slider.style[transitionDuration] = '0s'; this.__pos(-this.page * this.pageWidth); }, @@ -256,7 +303,7 @@ var SwipeView = (function(){ /* var matrix = getComputedStyle(this.slider, null).webkitTransform.replace(/[^0-9-.,]/g, '').split(','); this.x = matrix[4] * 1;*/ - this.slider.style.webkitTransitionDuration = '0'; + this.slider.style[transitionDuration] = '0s'; this.__event('touchstart'); }, @@ -329,7 +376,7 @@ var SwipeView = (function(){ // Check if we exceeded the snap threshold if (dist < this.snapThreshold) { - this.slider.style.webkitTransitionDuration = Math.floor(300 * dist / this.snapThreshold) + 'ms'; + this.slider.style[transitionDuration] = Math.floor(300 * dist / this.snapThreshold) + 'ms'; this.__pos(-this.page * this.pageWidth); return; } @@ -380,7 +427,7 @@ var SwipeView = (function(){ newX = -this.page * this.pageWidth; - this.slider.style.webkitTransitionDuration = Math.floor(500 * Math.abs(this.x - newX) / this.pageWidth) + 'ms'; + this.slider.style[transitionDuration] = Math.floor(500 * Math.abs(this.x - newX) / this.pageWidth) + 'ms'; // Hide the next page if we decided to disable looping if (!this.options.loop) { @@ -413,5 +460,12 @@ var SwipeView = (function(){ } }; + function prefixStyle (style) { + if ( vendor === '' ) return style; + + style = style.charAt(0).toUpperCase() + style.substr(1); + return vendor + style; + } + return SwipeView; -})(); \ No newline at end of file +})(window, document); \ No newline at end of file