Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New options for add preview percentage and number of buffer panels #61

Closed
wants to merge 6 commits into from
164 changes: 99 additions & 65 deletions src/swipeview.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,16 @@ var SwipeView = (function (window, document) {
var i,
div,
className,
left,
pageIndex;

this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
this.options = {
text: null,
numberOfPages: 3,
numberOfBufferPages: 2,
previewPercentage: 0,
pageWidth: null,
snapThreshold: null,
hastyPageFlip: false,
loop: true
Expand All @@ -85,12 +89,13 @@ var SwipeView = (function (window, document) {

this.refreshSize();

for (i=-1; i<2; i++) {
for (i=this.lowestPageIndex; i<=this.highestPageIndex; 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 + '%';
div.id = 'swipeview-masterpage-' + (i+(this.options.numberOfBufferPages/2));
left = i * this.computedPagePercentage + this.options.previewPercentage;
div.style.cssText = cssVendor + 'transform:translateZ(0);position:absolute;top:0;height:100%;width:' + this.computedPagePercentage + '%;left:' + left + '%';
if (!div.dataset) div.dataset = {};
pageIndex = i == -1 ? this.options.numberOfPages - 1 : i;
pageIndex = i < 0 ? this.options.numberOfPages + i : i;
div.dataset.pageIndex = pageIndex;
div.dataset.upcomingPageIndex = pageIndex;

Expand All @@ -101,7 +106,6 @@ var SwipeView = (function (window, document) {
}

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);
Expand All @@ -117,12 +121,17 @@ var SwipeView = (function (window, document) {
};

SwipeView.prototype = {
currentMasterPage: 1,
currentMasterPage: undefined,
x: 0,
page: 0,
pageIndex: 0,
customEvents: [],

onResize: function (fn) {
this.wrapper.addEventListener('swipeview-resize', fn, false);
this.customEvents.push(['resize', fn]);
},

onFlip: function (fn) {
this.wrapper.addEventListener('swipeview-flip', fn, false);
this.customEvents.push(['flip', fn]);
Expand Down Expand Up @@ -164,7 +173,20 @@ var SwipeView = (function (window, document) {
refreshSize: function () {
this.wrapperWidth = this.wrapper.clientWidth;
this.wrapperHeight = this.wrapper.clientHeight;
this.pageWidth = this.wrapperWidth;
if (this.options.pageWidth) {
this.computedPagePercentage = Math.ceil(this.options.pageWidth / this.wrapperWidth * 1000) / 10;
this.options.previewPercentage = Math.ceil((100 - this.computedPagePercentage) / 2);
}
else {
this.computedPagePercentage = 100 - (2 * this.options.previewPercentage);
}
this.options.numberOfBufferPages = Math.ceil(this.options.numberOfBufferPages / 2) * 2;
if (!this.currentMasterPage) {
this.currentMasterPage = this.options.numberOfBufferPages / 2;
}
this.lowestPageIndex = -(this.options.numberOfBufferPages / 2);
this.highestPageIndex = this.options.numberOfBufferPages / 2;
this.pageWidth = this.wrapperWidth * (this.computedPagePercentage / 100);
this.maxX = -this.options.numberOfPages * this.pageWidth + this.wrapperWidth;
this.snapThreshold = this.options.snapThreshold === null ?
Math.round(this.pageWidth * 0.15) :
Expand All @@ -179,14 +201,12 @@ var SwipeView = (function (window, document) {
},

goToPage: function (p) {
var i;
var i,
bufferSize = this.options.numberOfBufferPages + 1,
bufferPerSide = this.options.numberOfBufferPages / 2,
leftIndex,
rightIndex;

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;
Expand All @@ -195,32 +215,31 @@ var SwipeView = (function (window, document) {

this.currentMasterPage = (this.page + 1) - Math.floor((this.page + 1) / 3) * 3;

this.masterPages[this.currentMasterPage].className = this.masterPages[this.currentMasterPage].className + ' swipeview-active';
this.masterPages[this.currentMasterPage].style.left = this.page * this.computedPagePercentage + this.options.previewPercentage + '%';
this.masterPages[this.currentMasterPage].style.visibility = ''; //Reset visiblity for non-looping mode
this.masterPages[this.currentMasterPage].dataset.upcomingPageIndex = this.page;

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 + '%';
for (i=1; i<=bufferPerSide; i++) {
leftIndex = (bufferSize + this.currentMasterPage - i) % bufferSize;
rightIndex = (bufferSize + this.currentMasterPage + i) % bufferSize;

//Reset visiblity for non-looping mode
this.masterPages[leftIndex].style.visibility = '';
this.masterPages[rightIndex].style.visibility = '';

this.masterPages[leftIndex].style.left = this.page * this.computedPagePercentage - (this.computedPagePercentage * i) + this.options.previewPercentage + '%';
this.masterPages[rightIndex].style.left = this.page * this.computedPagePercentage + (this.computedPagePercentage * i) + this.options.previewPercentage + '%';

this.masterPages[leftIndex].dataset.upcomingPageIndex = (this.options.numberOfPages + ((this.page - i) % this.options.numberOfPages)) % this.options.numberOfPages;
this.masterPages[rightIndex].dataset.upcomingPageIndex = (this.options.numberOfPages + ((this.page + i) % this.options.numberOfPages)) % this.options.numberOfPages;

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;
//If we are not looping, hide the boundary crossing pages
if (!this.options.loop && i === 1) {
if (p === 0)
this.masterPages[leftIndex].style.visibility = 'hidden';
if (p === this.options.numberOfPages - 1)
this.masterPages[rightIndex].style.visibility = 'hidden';
}
}

this.__flip();
Expand Down Expand Up @@ -275,10 +294,26 @@ var SwipeView = (function (window, document) {
this.slider.style[transform] = 'translate(' + x + 'px,0)' + translateZ;
},

__layout: function () {
var i,
el,
left;

for (i=this.lowestPageIndex; i<=this.highestPageIndex; i++) {
el = this.slider.children[(i+(this.options.numberOfBufferPages/2))];
left = i * this.computedPagePercentage + this.options.previewPercentage;
el.style.cssText = cssVendor + 'transform:translateZ(0);position:absolute;top:0;height:100%;width:' + this.computedPagePercentage + '%;left:' + left + '%';
}
},

__resize: function () {
this.__event('resize');

this.refreshSize();
this.slider.style[transitionDuration] = '0s';
this.__pos(-this.page * this.pageWidth);
this.__layout(); //layout divs based on new viewport size
this.goToPage(this.pageIndex); //goto page to reset offsets
},

__start: function (e) {
Expand Down Expand Up @@ -363,20 +398,22 @@ var SwipeView = (function (window, document) {
if (!this.initiated) return;

var point = hasTouch ? e.changedTouches[0] : e,
dist = Math.abs(point.pageX - this.startX);
dist = Math.abs(point.pageX - this.startX),
duration;

this.initiated = false;

if (!this.moved) return;

if (!this.options.loop && (this.x > 0 || this.x < this.maxX)) {
duration = Math.floor(500 * dist / this.pageWidth); //at carousel boundary, animate back
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.slider.style[transitionDuration] = (duration ? duration : Math.floor(300 * dist / this.snapThreshold)) + 'ms';
this.__pos(-this.page * this.pageWidth);
return;
}
Expand All @@ -386,43 +423,32 @@ var SwipeView = (function (window, document) {

__checkPosition: function () {
var pageFlip,
bufferPerSide = this.options.numberOfBufferPages / 2,
bufferSize = this.options.numberOfBufferPages + 1,
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 + '%';
pageFlip = this.__indexShift(this.currentMasterPage, bufferPerSide, bufferSize);
pageFlipIndex = this.__indexShift(this.page, -bufferPerSide, this.options.numberOfPages);
this.currentMasterPage = this.__indexShift(this.currentMasterPage, -1, bufferSize);

pageFlipIndex = this.page - 1;
this.masterPages[pageFlip].style.left = this.page * this.computedPagePercentage - (this.computedPagePercentage * bufferPerSide) + this.options.previewPercentage + '%';
} 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 + '%';
pageFlip = this.__indexShift(this.currentMasterPage, -bufferPerSide, bufferSize);
pageFlipIndex = this.__indexShift(this.page, bufferPerSide, this.options.numberOfPages);
this.currentMasterPage = this.__indexShift(this.currentMasterPage, 1, bufferSize);

pageFlipIndex = this.page + 1;
this.masterPages[pageFlip].style.left = this.page * this.computedPagePercentage + (this.computedPagePercentage * bufferPerSide) + this.options.previewPercentage + '%';
}

// 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;
Expand All @@ -431,7 +457,12 @@ var SwipeView = (function (window, document) {

// 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.directionX > 0)
pageFlip = this.__indexShift(pageFlip, (this.options.numberOfBufferPages / 2 - 1), bufferSize);
else
pageFlip = this.__indexShift(pageFlip, -(this.options.numberOfBufferPages / 2 - 1), bufferSize);

this.masterPages[pageFlip].style.visibility = newX === 0 || newX <= this.maxX ? 'hidden' : '';
}

if (this.x == newX) {
Expand All @@ -442,11 +473,14 @@ var SwipeView = (function (window, document) {
}
},

__indexShift: function (index, value, size) {
return (size + ((index + value) % size)) % size;
},

__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
for (var i=0; i<=this.options.numberOfBufferPages; i++) {
this.masterPages[i].dataset.pageIndex = this.masterPages[i].dataset.upcomingPageIndex;
}
},
Expand All @@ -468,4 +502,4 @@ var SwipeView = (function (window, document) {
}

return SwipeView;
})(window, document);
})(window, document);