From 69dace127baefc22a6be666afdbb7068e7f8d21a Mon Sep 17 00:00:00 2001 From: Andrew Trice Date: Mon, 27 Aug 2012 20:32:03 -0400 Subject: [PATCH] added sample showing how to use cubiq's swipeview inside of a slidingview --- .DS_Store | Bin 6148 -> 6148 bytes .../03 - slidingView/03 - swipeview/.DS_Store | Bin 0 -> 6148 bytes .../03 - swipeview/index.html | 206 ++++++++ .../03 - slidingView/03 - swipeview/style.css | 90 ++++ .../03 - swipeview/swipeview.js | 474 ++++++++++++++++++ 5 files changed, 770 insertions(+) create mode 100644 samples/03 - slidingView/03 - swipeview/.DS_Store create mode 100644 samples/03 - slidingView/03 - swipeview/index.html create mode 100755 samples/03 - slidingView/03 - swipeview/style.css create mode 100755 samples/03 - slidingView/03 - swipeview/swipeview.js diff --git a/.DS_Store b/.DS_Store index 69cce95cb53da6ed18fffb3d3f714c351c3158bc..cf0263d498603c0c9606f9d7732496f1e0e52a2b 100644 GIT binary patch delta 91 zcmZoMXfc@JFUrioz`)4BAi%(o!;s2QoKl>elaxRCBI9ytkPJIRF+(ClE<*vbY<|vU eZpM=W%s{y!hGdA2{2a#37a2L&HnVg5#XU^6?%Uw!~5 CkqrX? diff --git a/samples/03 - slidingView/03 - swipeview/.DS_Store b/samples/03 - slidingView/03 - swipeview/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 + + + Sliding View Sample + + + + + + + + + + + + + + + + + + +
+ +
+

Three Laws of Robotics

+
+ +

The Three Laws of Robotics (often shortened to The Three Laws or Three Laws) are a set of rules devised by the science fiction author Isaac Asimov and later added to. The rules are introduced in his 1942 short story "Runaround", although they were foreshadowed in a few earlier stories.

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+ + +
+
+ + + \ No newline at end of file diff --git a/samples/03 - slidingView/03 - swipeview/style.css b/samples/03 - slidingView/03 - swipeview/style.css new file mode 100755 index 0000000..830a1b2 --- /dev/null +++ b/samples/03 - slidingView/03 - swipeview/style.css @@ -0,0 +1,90 @@ +html, body { height:100%; } +body { + padding:0; + margin:0; + background:#fff; + -webkit-user-select:none; + -webkit-text-size-adjust:none; + color:#333; + font-family:helvetica; + font-size:12px; + text-align:center; +} + +h1 { + font-size:2em; + padding:20px 0; + margin:0; +} + +#wrapper { + width:100%; + min-width:320px; + height:150px; + background:#ddd; + border-top:1px solid #aaa; + border-bottom:1px solid #aaa; +} + +#nav { + position:absolute; + z-index:100; + top:8px; + width:200px; + height:20px; + left:50%; + background:rgba(0,0,0,0.75); + padding:0; + margin:0 0 0 -100px; + -webkit-border-radius:10px; +} + +#nav li { + display:block; + float:left; + width:14px; + height:14px; line-height:14px; + -webkit-border-radius:7px; + background:rgba(255,255,255,0.1); + overflow:hidden; + padding:0; + margin:3px 11px 0 0; + text-align:center; +} + +#nav li#prev { + margin-left:5px; + background:transparent; +} + +#nav li#next { + margin-right:0; + background:transparent; +} + +#nav li.selected { + background:rgba(255,255,255,0.4); +} + +#swipeview-slider > div { + position:relative; + display:-webkit-box; + -webkit-box-orient:vertical; + -webkit-box-pack:center; + -webkit-box-align:center; + overflow:hidden; +} + +#swipeview-slider span { + -webkit-box-sizing:border-box; + display:block; + text-align:center; + font-size:1.4em; + padding:0 20px; +} + +p { + padding:20px; + margin:0; + font-size:1.4em; +} diff --git a/samples/03 - slidingView/03 - swipeview/swipeview.js b/samples/03 - slidingView/03 - swipeview/swipeview.js new file mode 100755 index 0000000..15f304e --- /dev/null +++ b/samples/03 - slidingView/03 - swipeview/swipeview.js @@ -0,0 +1,474 @@ +/*! + * SwipeView v1.0 ~ Copyright (c) 2012 Matteo Spinelli, http://cubiq.org + * Released under MIT license, http://cubiq.org/license + */ +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, + div, + className, + pageIndex; + + this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; + this.options = { + text: null, + numberOfPages: 3, + snapThreshold: null, + hastyPageFlip: false, + loop: true + }; + + // User defined options + for (i in options) this.options[i] = options[i]; + + this.wrapper.style.overflow = 'hidden'; + this.wrapper.style.position = 'relative'; + + this.masterPages = []; + + div = document.createElement('div'); + div.id = 'swipeview-slider'; + 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; + + this.refreshSize(); + + for (i=-1; i<2; i++) { + div = document.createElement('div'); + div.id = 'swipeview-masterpage-' + (i+1); + 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; + div.dataset.upcomingPageIndex = pageIndex; + + if (!this.options.loop && i == -1) div.style.visibility = 'hidden'; + + this.slider.appendChild(div); + this.masterPages.push(div); + } + + className = this.masterPages[1].className; + this.masterPages[1].className = !className ? 'swipeview-active' : className + ' swipeview-active'; + + window.addEventListener(resizeEvent, this, false); + this.wrapper.addEventListener(startEvent, this, false); + this.wrapper.addEventListener(moveEvent, this, false); + this.wrapper.addEventListener(endEvent, 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, + page: 0, + pageIndex: 0, + customEvents: [], + + onFlip: function (fn) { + this.wrapper.addEventListener('swipeview-flip', fn, false); + this.customEvents.push(['flip', fn]); + }, + + onMoveOut: function (fn) { + this.wrapper.addEventListener('swipeview-moveout', fn, false); + this.customEvents.push(['moveout', fn]); + }, + + onMoveIn: function (fn) { + this.wrapper.addEventListener('swipeview-movein', fn, false); + this.customEvents.push(['movein', fn]); + }, + + onTouchStart: function (fn) { + this.wrapper.addEventListener('swipeview-touchstart', fn, false); + this.customEvents.push(['touchstart', fn]); + }, + + destroy: function () { + while ( this.customEvents.length ) { + this.wrapper.removeEventListener('swipeview-' + this.customEvents[0][0], this.customEvents[0][1], false); + this.customEvents.shift(); + } + + // Remove the event listeners + window.removeEventListener(resizeEvent, this, false); + this.wrapper.removeEventListener(startEvent, this, false); + this.wrapper.removeEventListener(moveEvent, this, false); + this.wrapper.removeEventListener(endEvent, this, false); + this.slider.removeEventListener(transitionEndEvent, this, false); + +/* if (!hasTouch) { + this.wrapper.removeEventListener('mouseout', this, false); + }*/ + }, + + refreshSize: function () { + this.wrapperWidth = this.wrapper.clientWidth; + this.wrapperHeight = this.wrapper.clientHeight; + this.pageWidth = this.wrapperWidth; + this.maxX = -this.options.numberOfPages * this.pageWidth + this.wrapperWidth; + this.snapThreshold = this.options.snapThreshold === null ? + Math.round(this.pageWidth * 0.15) : + /%/.test(this.options.snapThreshold) ? + Math.round(this.pageWidth * this.options.snapThreshold.replace('%', '') / 100) : + this.options.snapThreshold; + }, + + updatePageCount: function (n) { + this.options.numberOfPages = n; + this.maxX = -this.options.numberOfPages * this.pageWidth + this.wrapperWidth; + }, + + goToPage: function (p) { + var i; + + this.masterPages[this.currentMasterPage].className = this.masterPages[this.currentMasterPage].className.replace(/(^|\s)swipeview-active(\s|$)/, ''); + for (i=0; i<3; i++) { + className = this.masterPages[i].className; + /(^|\s)swipeview-loading(\s|$)/.test(className) || (this.masterPages[i].className = !className ? 'swipeview-loading' : className + ' swipeview-loading'); + } + + p = p < 0 ? 0 : p > this.options.numberOfPages-1 ? this.options.numberOfPages-1 : p; + this.page = p; + this.pageIndex = p; + 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) { + 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 + '%'; + + this.masterPages[2].dataset.upcomingPageIndex = this.page === 0 ? this.options.numberOfPages-1 : this.page - 1; + this.masterPages[0].dataset.upcomingPageIndex = this.page; + this.masterPages[1].dataset.upcomingPageIndex = this.page == this.options.numberOfPages-1 ? 0 : this.page + 1; + } else if (this.currentMasterPage == 1) { + this.masterPages[0].style.left = this.page * 100 - 100 + '%'; + this.masterPages[1].style.left = this.page * 100 + '%'; + this.masterPages[2].style.left = this.page * 100 + 100 + '%'; + + this.masterPages[0].dataset.upcomingPageIndex = this.page === 0 ? this.options.numberOfPages-1 : this.page - 1; + this.masterPages[1].dataset.upcomingPageIndex = this.page; + this.masterPages[2].dataset.upcomingPageIndex = this.page == this.options.numberOfPages-1 ? 0 : this.page + 1; + } else { + this.masterPages[1].style.left = this.page * 100 - 100 + '%'; + this.masterPages[2].style.left = this.page * 100 + '%'; + this.masterPages[0].style.left = this.page * 100 + 100 + '%'; + + this.masterPages[1].dataset.upcomingPageIndex = this.page === 0 ? this.options.numberOfPages-1 : this.page - 1; + this.masterPages[2].dataset.upcomingPageIndex = this.page; + this.masterPages[0].dataset.upcomingPageIndex = this.page == this.options.numberOfPages-1 ? 0 : this.page + 1; + } + + this.__flip(); + }, + + next: function () { + if (!this.options.loop && this.x == this.maxX) return; + + this.directionX = -1; + this.x -= 1; + this.__checkPosition(); + }, + + prev: function () { + if (!this.options.loop && this.x === 0) return; + + this.directionX = 1; + this.x += 1; + this.__checkPosition(); + }, + + handleEvent: function (e) { + switch (e.type) { + case startEvent: + this.__start(e); + e.preventDefault(); + e.stopPropagation(); + return false; + break; + case moveEvent: + this.__move(e); + break; + case cancelEvent: + case endEvent: + this.__end(e); + break; + case resizeEvent: + this.__resize(); + break; + case transitionEndEvent: + case 'otransitionend': + if (e.target == this.slider && !this.options.hastyPageFlip) this.__flip(); + break; + } + }, + + + /** + * + * Pseudo private methods + * + */ + __pos: function (x) { + this.x = x; + this.slider.style[transform] = 'translate(' + x + 'px,0)' + translateZ; + }, + + __resize: function () { + this.refreshSize(); + this.slider.style[transitionDuration] = '0s'; + this.__pos(-this.page * this.pageWidth); + }, + + __start: function (e) { + //e.preventDefault(); + + if (this.initiated) return; + + var point = hasTouch ? e.touches[0] : e; + + this.initiated = true; + this.moved = false; + this.thresholdExceeded = false; + this.startX = point.pageX; + this.startY = point.pageY; + this.pointX = point.pageX; + this.pointY = point.pageY; + this.stepsX = 0; + this.stepsY = 0; + this.directionX = 0; + this.directionLocked = false; + +/* var matrix = getComputedStyle(this.slider, null).webkitTransform.replace(/[^0-9-.,]/g, '').split(','); + this.x = matrix[4] * 1;*/ + + this.slider.style[transitionDuration] = '0s'; + + this.__event('touchstart'); + }, + + __move: function (e) { + if (!this.initiated) return; + + var point = hasTouch ? e.touches[0] : e, + deltaX = point.pageX - this.pointX, + deltaY = point.pageY - this.pointY, + newX = this.x + deltaX, + dist = Math.abs(point.pageX - this.startX); + + this.moved = true; + this.pointX = point.pageX; + this.pointY = point.pageY; + this.directionX = deltaX > 0 ? 1 : deltaX < 0 ? -1 : 0; + this.stepsX += Math.abs(deltaX); + this.stepsY += Math.abs(deltaY); + + // We take a 10px buffer to figure out the direction of the swipe + if (this.stepsX < 10 && this.stepsY < 10) { +// e.preventDefault(); + return; + } + + // We are scrolling vertically, so skip SwipeView and give the control back to the browser + if (!this.directionLocked && this.stepsY > this.stepsX) { + this.initiated = false; + return; + } + + e.preventDefault(); + + this.directionLocked = true; + + if (!this.options.loop && (newX > 0 || newX < this.maxX)) { + newX = this.x + (deltaX / 2); + } + + if (!this.thresholdExceeded && dist >= this.snapThreshold) { + this.thresholdExceeded = true; + this.__event('moveout'); + } else if (this.thresholdExceeded && dist < this.snapThreshold) { + this.thresholdExceeded = false; + this.__event('movein'); + } + +/* if (newX > 0 || newX < this.maxX) { + newX = this.x + (deltaX / 2); + }*/ + + this.__pos(newX); + }, + + __end: function (e) { + if (!this.initiated) return; + + var point = hasTouch ? e.changedTouches[0] : e, + dist = Math.abs(point.pageX - this.startX); + + this.initiated = false; + + if (!this.moved) return; + + if (!this.options.loop && (this.x > 0 || this.x < this.maxX)) { + dist = 0; + this.__event('movein'); + } + + // Check if we exceeded the snap threshold + if (dist < this.snapThreshold) { + this.slider.style[transitionDuration] = Math.floor(300 * dist / this.snapThreshold) + 'ms'; + this.__pos(-this.page * this.pageWidth); + return; + } + + this.__checkPosition(); + }, + + __checkPosition: function () { + var pageFlip, + pageFlipIndex, + className; + + this.masterPages[this.currentMasterPage].className = this.masterPages[this.currentMasterPage].className.replace(/(^|\s)swipeview-active(\s|$)/, ''); + + // Flip the page + if (this.directionX > 0) { + this.page = -Math.ceil(this.x / this.pageWidth); + this.currentMasterPage = (this.page + 1) - Math.floor((this.page + 1) / 3) * 3; + this.pageIndex = this.pageIndex === 0 ? this.options.numberOfPages - 1 : this.pageIndex - 1; + + pageFlip = this.currentMasterPage - 1; + pageFlip = pageFlip < 0 ? 2 : pageFlip; + this.masterPages[pageFlip].style.left = this.page * 100 - 100 + '%'; + + pageFlipIndex = this.page - 1; + } else { + this.page = -Math.floor(this.x / this.pageWidth); + this.currentMasterPage = (this.page + 1) - Math.floor((this.page + 1) / 3) * 3; + this.pageIndex = this.pageIndex == this.options.numberOfPages - 1 ? 0 : this.pageIndex + 1; + + pageFlip = this.currentMasterPage + 1; + pageFlip = pageFlip > 2 ? 0 : pageFlip; + this.masterPages[pageFlip].style.left = this.page * 100 + 100 + '%'; + + pageFlipIndex = this.page + 1; + } + + // Add active class to current page + className = this.masterPages[this.currentMasterPage].className; + /(^|\s)swipeview-active(\s|$)/.test(className) || (this.masterPages[this.currentMasterPage].className = !className ? 'swipeview-active' : className + ' swipeview-active'); + + // Add loading class to flipped page + className = this.masterPages[pageFlip].className; + /(^|\s)swipeview-loading(\s|$)/.test(className) || (this.masterPages[pageFlip].className = !className ? 'swipeview-loading' : className + ' swipeview-loading'); + + pageFlipIndex = pageFlipIndex - Math.floor(pageFlipIndex / this.options.numberOfPages) * this.options.numberOfPages; + this.masterPages[pageFlip].dataset.upcomingPageIndex = pageFlipIndex; // Index to be loaded in the newly flipped page + + newX = -this.page * this.pageWidth; + + 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) { + this.masterPages[pageFlip].style.visibility = newX === 0 || newX == this.maxX ? 'hidden' : ''; + } + + if (this.x == newX) { + this.__flip(); // If we swiped all the way long to the next page (extremely rare but still) + } else { + this.__pos(newX); + if (this.options.hastyPageFlip) this.__flip(); + } + }, + + __flip: function () { + this.__event('flip'); + + for (var i=0; i<3; i++) { + this.masterPages[i].className = this.masterPages[i].className.replace(/(^|\s)swipeview-loading(\s|$)/, ''); // Remove the loading class + this.masterPages[i].dataset.pageIndex = this.masterPages[i].dataset.upcomingPageIndex; + } + }, + + __event: function (type) { + var ev = document.createEvent("Event"); + + ev.initEvent('swipeview-' + type, true, true); + + this.wrapper.dispatchEvent(ev); + } + }; + + function prefixStyle (style) { + if ( vendor === '' ) return style; + + style = style.charAt(0).toUpperCase() + style.substr(1); + return vendor + style; + } + + return SwipeView; +})(window, document); \ No newline at end of file