-
Notifications
You must be signed in to change notification settings - Fork 118
/
Copy pathflipsnap.min.js
1 lines (1 loc) · 9.95 KB
/
flipsnap.min.js
1
(function(root,factory){if(typeof define==="function"&&define.amd){define([],factory)}else if(typeof exports==="object"){module.exports=factory()}else{root.Flipsnap=factory()}})(this,function(){var div=document.createElement("div");var prefix=["webkit","moz","o","ms"];var saveProp={};var support=Flipsnap.support={};var gestureStart=false;var DISTANCE_THRESHOLD=5;var ANGLE_THREHOLD=55;support.transform3d=hasProp(["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"]);support.transform=hasProp(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"]);support.transition=hasProp(["transitionProperty","WebkitTransitionProperty","MozTransitionProperty","OTransitionProperty","msTransitionProperty"]);support.addEventListener="addEventListener"in window;support.mspointer=window.navigator.msPointerEnabled;support.cssAnimation=(support.transform3d||support.transform)&&support.transition;var eventTypes=["touch","mouse"];var events={start:{touch:"touchstart",mouse:"mousedown"},move:{touch:"touchmove",mouse:"mousemove"},end:{touch:"touchend",mouse:"mouseup"}};if(support.addEventListener){document.addEventListener("gesturestart",function(){gestureStart=true});document.addEventListener("gestureend",function(){gestureStart=false})}function Flipsnap(element,opts){return this instanceof Flipsnap?this.init(element,opts):new Flipsnap(element,opts)}Flipsnap.prototype.init=function(element,opts){var self=this;self.element=element;if(typeof element==="string"){self.element=document.querySelector(element)}if(!self.element){throw new Error("element not found")}if(support.mspointer){self.element.style.msTouchAction="pan-y"}opts=opts||{};self.distance=opts.distance;self.maxPoint=opts.maxPoint;self.disableTouch=opts.disableTouch===undefined?false:opts.disableTouch;self.disable3d=opts.disable3d===undefined?false:opts.disable3d;self.transitionDuration=opts.transitionDuration===undefined?"350ms":opts.transitionDuration+"ms";self.threshold=opts.threshold||0;self.currentPoint=0;self.currentX=0;self.animation=false;self.timerId=null;self.use3d=support.transform3d;if(self.disable3d===true){self.use3d=false}if(support.cssAnimation){self._setStyle({transitionProperty:getCSSVal("transform"),transitionTimingFunction:"cubic-bezier(0,0,0.25,1)",transitionDuration:"0ms",transform:self._getTranslate(0)})}else{self._setStyle({position:"relative",left:"0px"})}self.refresh();eventTypes.forEach(function(type){self.element.addEventListener(events.start[type],self,false)});return self};Flipsnap.prototype.handleEvent=function(event){var self=this;switch(event.type){case events.start.touch:self._touchStart(event,"touch");break;case events.start.mouse:self._touchStart(event,"mouse");break;case events.move.touch:self._touchMove(event,"touch");break;case events.move.mouse:self._touchMove(event,"mouse");break;case events.end.touch:self._touchEnd(event,"touch");break;case events.end.mouse:self._touchEnd(event,"mouse");break;case"click":self._click(event);break}};Flipsnap.prototype.refresh=function(){var self=this;self._maxPoint=self.maxPoint===undefined?function(){var childNodes=self.element.childNodes,itemLength=-1,i=0,len=childNodes.length,node;for(;i<len;i++){node=childNodes[i];if(node.nodeType===1){itemLength++}}return itemLength}():self.maxPoint;if(self.distance===undefined){if(self._maxPoint<0){self._distance=0}else{self._distance=self.element.scrollWidth/(self._maxPoint+1)}}else{self._distance=self.distance}self._maxX=-self._distance*self._maxPoint;self.moveToPoint()};Flipsnap.prototype.hasNext=function(){var self=this;return self.currentPoint<self._maxPoint};Flipsnap.prototype.hasPrev=function(){var self=this;return self.currentPoint>0};Flipsnap.prototype.toNext=function(transitionDuration){var self=this;if(!self.hasNext()){return}self.moveToPoint(self.currentPoint+1,transitionDuration)};Flipsnap.prototype.toPrev=function(transitionDuration){var self=this;if(!self.hasPrev()){return}self.moveToPoint(self.currentPoint-1,transitionDuration)};Flipsnap.prototype.moveToPoint=function(point,transitionDuration){var self=this;transitionDuration=transitionDuration===undefined?self.transitionDuration:transitionDuration+"ms";var beforePoint=self.currentPoint;if(point===undefined){point=self.currentPoint}if(point<0){self.currentPoint=0}else if(point>self._maxPoint){self.currentPoint=self._maxPoint}else{self.currentPoint=parseInt(point,10)}if(support.cssAnimation){self._setStyle({transitionDuration:transitionDuration})}else{self.animation=true}self._setX(-self.currentPoint*self._distance,transitionDuration);if(beforePoint!==self.currentPoint){self._triggerEvent("fsmoveend",true,false);self._triggerEvent("fspointmove",true,false)}};Flipsnap.prototype._setX=function(x,transitionDuration){var self=this;self.currentX=x;if(support.cssAnimation){self.element.style[saveProp.transform]=self._getTranslate(x)}else{if(self.animation){self._animate(x,transitionDuration||self.transitionDuration)}else{self.element.style.left=x+"px"}}};Flipsnap.prototype._touchStart=function(event,type){var self=this;if(self.disableTouch||self.scrolling||gestureStart){return}self.element.addEventListener(events.move[type],self,false);document.addEventListener(events.end[type],self,false);var tagName=event.target.tagName;if(type==="mouse"&&tagName!=="SELECT"&&tagName!=="INPUT"&&tagName!=="TEXTAREA"&&tagName!=="BUTTON"){event.preventDefault()}if(support.cssAnimation){self._setStyle({transitionDuration:"0ms"})}else{self.animation=false}self.scrolling=true;self.moveReady=false;self.startPageX=getPage(event,"pageX");self.startPageY=getPage(event,"pageY");self.basePageX=self.startPageX;self.directionX=0;self.startTime=event.timeStamp;self._triggerEvent("fstouchstart",true,false)};Flipsnap.prototype._touchMove=function(event,type){var self=this;if(!self.scrolling||gestureStart){return}var pageX=getPage(event,"pageX");var pageY=getPage(event,"pageY");var distX;var newX;if(self.moveReady){event.preventDefault();distX=pageX-self.basePageX;newX=self.currentX+distX;if(newX>=0||newX<self._maxX){newX=Math.round(self.currentX+distX/3)}self.directionX=distX===0?self.directionX:distX>0?-1:1;var isPrevent=!self._triggerEvent("fstouchmove",true,true,{delta:distX,direction:self.directionX});if(isPrevent){self._touchAfter({moved:false,originalPoint:self.currentPoint,newPoint:self.currentPoint,cancelled:true})}else{self._setX(newX)}}else{var triangle=getTriangleSide(self.startPageX,self.startPageY,pageX,pageY);if(triangle.z>DISTANCE_THRESHOLD){if(getAngle(triangle)>ANGLE_THREHOLD){event.preventDefault();self.moveReady=true;self.element.addEventListener("click",self,true)}else{self.scrolling=false}}}self.basePageX=pageX};Flipsnap.prototype._touchEnd=function(event,type){var self=this;self.element.removeEventListener(events.move[type],self,false);document.removeEventListener(events.end[type],self,false);if(!self.scrolling){return}var newPoint=-self.currentX/self._distance;newPoint=self.directionX>0?Math.ceil(newPoint):self.directionX<0?Math.floor(newPoint):Math.round(newPoint);if(newPoint<0){newPoint=0}else if(newPoint>self._maxPoint){newPoint=self._maxPoint}if(Math.abs(self.startPageX-self.basePageX)<self.threshold){newPoint=self.currentPoint}self._touchAfter({moved:newPoint!==self.currentPoint,originalPoint:self.currentPoint,newPoint:newPoint,cancelled:false});self.moveToPoint(newPoint)};Flipsnap.prototype._click=function(event){var self=this;event.stopPropagation();event.preventDefault()};Flipsnap.prototype._touchAfter=function(params){var self=this;self.scrolling=false;self.moveReady=false;setTimeout(function(){self.element.removeEventListener("click",self,true)},200);self._triggerEvent("fstouchend",true,false,params)};Flipsnap.prototype._setStyle=function(styles){var self=this;var style=self.element.style;for(var prop in styles){setStyle(style,prop,styles[prop])}};Flipsnap.prototype._animate=function(x,transitionDuration){var self=this;var elem=self.element;var begin=+new Date;var from=parseInt(elem.style.left,10);var to=x;var duration=parseInt(transitionDuration,10);var easing=function(time,duration){return-(time/=duration)*(time-2)};if(self.timerId){clearInterval(self.timerId)}self.timerId=setInterval(function(){var time=new Date-begin;var pos,now;if(time>duration){clearInterval(self.timerId);self.timerId=null;now=to}else{pos=easing(time,duration);now=pos*(to-from)+from}elem.style.left=now+"px"},10)};Flipsnap.prototype.destroy=function(){var self=this;eventTypes.forEach(function(type){self.element.removeEventListener(events.start[type],self,false)})};Flipsnap.prototype._getTranslate=function(x){var self=this;return self.use3d?"translate3d("+x+"px, 0, 0)":"translate("+x+"px, 0)"};Flipsnap.prototype._triggerEvent=function(type,bubbles,cancelable,data){var self=this;var ev=document.createEvent("Event");ev.initEvent(type,bubbles,cancelable);if(data){for(var d in data){if(data.hasOwnProperty(d)){ev[d]=data[d]}}}return self.element.dispatchEvent(ev)};function getPage(event,page){return event.changedTouches?event.changedTouches[0][page]:event[page]}function hasProp(props){return some(props,function(prop){return div.style[prop]!==undefined})}function setStyle(style,prop,val){var _saveProp=saveProp[prop];if(_saveProp){style[_saveProp]=val}else if(style[prop]!==undefined){saveProp[prop]=prop;style[prop]=val}else{some(prefix,function(_prefix){var _prop=ucFirst(_prefix)+ucFirst(prop);if(style[_prop]!==undefined){saveProp[prop]=_prop;style[_prop]=val;return true}})}}function getCSSVal(prop){if(div.style[prop]!==undefined){return prop}else{var ret;some(prefix,function(_prefix){var _prop=ucFirst(_prefix)+ucFirst(prop);if(div.style[_prop]!==undefined){ret="-"+_prefix+"-"+prop;return true}});return ret}}function ucFirst(str){return str.charAt(0).toUpperCase()+str.substr(1)}function some(ary,callback){for(var i=0,len=ary.length;i<len;i++){if(callback(ary[i],i)){return true}}return false}function getTriangleSide(x1,y1,x2,y2){var x=Math.abs(x1-x2);var y=Math.abs(y1-y2);var z=Math.sqrt(Math.pow(x,2)+Math.pow(y,2));return{x:x,y:y,z:z}}function getAngle(triangle){var cos=triangle.y/triangle.z;var radian=Math.acos(cos);return 180/(Math.PI/radian)}return Flipsnap});