You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

13 lines
9.0 KiB
Plaintext

(function($,window,document,undefined){var MAX_EXCEED=30;var VISIBLE_RANGE=90;var DEFAULT_ITEM_HEIGHT=40;var BLUR_WIDTH=10;var rad2deg=$.rad2deg=function(rad){return rad/(Math.PI/180);};var deg2rad=$.deg2rad=function(deg){return deg*(Math.PI/180);};var platform=navigator.platform.toLowerCase();var userAgent=navigator.userAgent.toLowerCase();var isIos=(userAgent.indexOf('iphone')>-1||userAgent.indexOf('ipad')>-1||userAgent.indexOf('ipod')>-1)&&(platform.indexOf('iphone')>-1||platform.indexOf('ipad')>-1||platform.indexOf('ipod')>-1);var Picker=$.Picker=function(holder,options){var self=this;self.holder=holder;self.options=options||{};self.init();self.initInertiaParams();self.calcElementItemPostion(true);self.bindEvent();};Picker.prototype.findElementItems=function(){var self=this;self.elementItems=[].slice.call(self.holder.querySelectorAll('li'));return self.elementItems;};Picker.prototype.init=function(){var self=this;self.list=self.holder.querySelector('ul');self.findElementItems();self.height=self.holder.offsetHeight;self.r=self.height/2-BLUR_WIDTH;self.d=self.r*2;self.itemHeight=self.elementItems.length>0?self.elementItems[0].offsetHeight:DEFAULT_ITEM_HEIGHT;self.itemAngle=parseInt(self.calcAngle(self.itemHeight*0.8));self.hightlightRange=self.itemAngle/2;self.visibleRange=VISIBLE_RANGE;self.beginAngle=0;self.beginExceed=self.beginAngle-MAX_EXCEED;self.list.angle=self.beginAngle;if(isIos){self.list.style.webkitTransformOrigin="center center "+self.r+"px";}};Picker.prototype.calcElementItemPostion=function(andGenerateItms){var self=this;if(andGenerateItms){self.items=[];}
self.elementItems.forEach(function(item){var index=self.elementItems.indexOf(item);self.endAngle=self.itemAngle*index;item.angle=self.endAngle;item.style.webkitTransformOrigin="center center -"+self.r+"px";item.style.webkitTransform="translateZ("+self.r+"px) rotateX("+(-self.endAngle)+"deg)";if(andGenerateItms){var dataItem={};dataItem.text=item.innerHTML||'';dataItem.value=item.getAttribute('data-value')||dataItem.text;self.items.push(dataItem);}});self.endExceed=self.endAngle+MAX_EXCEED;self.calcElementItemVisibility(self.beginAngle);};Picker.prototype.calcAngle=function(c){var self=this;var a=b=parseFloat(self.r);c=Math.abs(c);var intDeg=parseInt(c/self.d)*180;c=c%self.d;var cosC=(a*a+b*b-c*c)/(2*a*b);var angleC=intDeg+rad2deg(Math.acos(cosC));return angleC;};Picker.prototype.calcElementItemVisibility=function(angle){var self=this;self.elementItems.forEach(function(item){var difference=Math.abs(item.angle-angle);if(difference<self.hightlightRange){item.classList.add('highlight');}else if(difference<self.visibleRange){item.classList.add('visible');item.classList.remove('highlight');}else{item.classList.remove('highlight');item.classList.remove('visible');}});};Picker.prototype.setAngle=function(angle){var self=this;self.list.angle=angle;self.list.style.webkitTransform="perspective(1000px) rotateY(0deg) rotateX("+angle+"deg)";self.calcElementItemVisibility(angle);};Picker.prototype.bindEvent=function(){var self=this;var lastAngle=0;var startY=null;var isPicking=false;self.holder.addEventListener($.EVENT_START,function(event){isPicking=true;event.preventDefault();self.list.style.webkitTransition='';startY=(event.changedTouches?event.changedTouches[0]:event).pageY;lastAngle=self.list.angle;self.updateInertiaParams(event,true);},false);self.holder.addEventListener($.EVENT_END,function(event){isPicking=false;event.preventDefault();self.startInertiaScroll(event);},false);self.holder.addEventListener($.EVENT_CANCEL,function(event){isPicking=false;event.preventDefault();self.startInertiaScroll(event);},false);self.holder.addEventListener($.EVENT_MOVE,function(event){if(!isPicking){return;}
event.preventDefault();var endY=(event.changedTouches?event.changedTouches[0]:event).pageY;var dragRange=endY-startY;var dragAngle=self.calcAngle(dragRange);var newAngle=dragRange>0?lastAngle-dragAngle:lastAngle+dragAngle;if(newAngle>self.endExceed){newAngle=self.endExceed}
if(newAngle<self.beginExceed){newAngle=self.beginExceed}
self.setAngle(newAngle);self.updateInertiaParams(event);},false);self.list.addEventListener('tap',function(event){elementItem=event.target;if(elementItem.tagName=='LI'){self.setSelectedIndex(self.elementItems.indexOf(elementItem),200);}},false);};Picker.prototype.initInertiaParams=function(){var self=this;self.lastMoveTime=0;self.lastMoveStart=0;self.stopInertiaMove=false;};Picker.prototype.updateInertiaParams=function(event,isStart){var self=this;var point=event.changedTouches?event.changedTouches[0]:event;if(isStart){self.lastMoveStart=point.pageY;self.lastMoveTime=event.timeStamp||Date.now();self.startAngle=self.list.angle;}else{var nowTime=event.timeStamp||Date.now();if(nowTime-self.lastMoveTime>300){self.lastMoveTime=nowTime;self.lastMoveStart=point.pageY;}}
self.stopInertiaMove=true;};Picker.prototype.startInertiaScroll=function(event){var self=this;var point=event.changedTouches?event.changedTouches[0]:event;var nowTime=event.timeStamp||Date.now();var v=(point.pageY-self.lastMoveStart)/(nowTime-self.lastMoveTime);var dir=v>0?-1:1;var deceleration=dir*0.0006* -1;var duration=Math.abs(v/deceleration);var dist=v*duration/2;var startAngle=self.list.angle;var distAngle=self.calcAngle(dist)*dir;var srcDistAngle=distAngle;if(startAngle+distAngle<self.beginExceed){distAngle=self.beginExceed-startAngle;duration=duration*(distAngle/srcDistAngle)*0.6;}
if(startAngle+distAngle>self.endExceed){distAngle=self.endExceed-startAngle;duration=duration*(distAngle/srcDistAngle)*0.6;}
if(distAngle==0){self.endScroll();return;}
self.scrollDistAngle(nowTime,startAngle,distAngle,duration);};Picker.prototype.scrollDistAngle=function(nowTime,startAngle,distAngle,duration){var self=this;self.stopInertiaMove=false;(function(nowTime,startAngle,distAngle,duration){var frameInterval=13;var stepCount=duration/frameInterval;var stepIndex=0;(function inertiaMove(){if(self.stopInertiaMove)return;var newAngle=self.quartEaseOut(stepIndex,startAngle,distAngle,stepCount);self.setAngle(newAngle);stepIndex++;if(stepIndex>stepCount-1||newAngle<self.beginExceed||newAngle>self.endExceed){self.endScroll();return;}
setTimeout(inertiaMove,frameInterval);})();})(nowTime,startAngle,distAngle,duration);};Picker.prototype.quartEaseOut=function(t,b,c,d){return-c*((t=t/d-1)*t*t*t-1)+b;};Picker.prototype.endScroll=function(){var self=this;if(self.list.angle<self.beginAngle){self.list.style.webkitTransition="150ms ease-out";self.setAngle(self.beginAngle);}else if(self.list.angle>self.endAngle){self.list.style.webkitTransition="150ms ease-out";self.setAngle(self.endAngle);}else{var index=parseInt((self.list.angle/self.itemAngle).toFixed(0));self.list.style.webkitTransition="100ms ease-out";self.setAngle(self.itemAngle*index);}
self.triggerChange();};Picker.prototype.triggerChange=function(force){var self=this;setTimeout(function(){var index=self.getSelectedIndex();var item=self.items[index];if($.trigger&&(index!=self.lastIndex||force===true)){$.trigger(self.holder,'change',{"index":index,"item":item});}
self.lastIndex=index;typeof force==='function'&&force();},0);};Picker.prototype.correctAngle=function(angle){var self=this;if(angle<self.beginAngle){return self.beginAngle;}else if(angle>self.endAngle){return self.endAngle;}else{return angle;}};Picker.prototype.setItems=function(items){var self=this;self.items=items||[];var buffer=[];self.items.forEach(function(item){if(item!==null&&item!==undefined){buffer.push('<li>'+(item.text||item)+'</li>');}});self.list.innerHTML=buffer.join('');self.findElementItems();self.calcElementItemPostion();self.setAngle(self.correctAngle(self.list.angle));self.triggerChange(true);};Picker.prototype.getItems=function(){var self=this;return self.items;};Picker.prototype.getSelectedIndex=function(){var self=this;return parseInt((self.list.angle/self.itemAngle).toFixed(0));};Picker.prototype.setSelectedIndex=function(index,duration,callback){var self=this;self.list.style.webkitTransition='';var angle=self.correctAngle(self.itemAngle*index);if(duration&&duration>0){var distAngle=angle-self.list.angle;self.scrollDistAngle(Date.now(),self.list.angle,distAngle,duration);}else{self.setAngle(angle);}
self.triggerChange(callback);};Picker.prototype.getSelectedItem=function(){var self=this;return self.items[self.getSelectedIndex()];};Picker.prototype.getSelectedValue=function(){var self=this;return(self.items[self.getSelectedIndex()]||{}).value;};Picker.prototype.getSelectedText=function(){var self=this;return(self.items[self.getSelectedIndex()]||{}).text;};Picker.prototype.setSelectedValue=function(value,duration,callback){var self=this;for(var index in self.items){var item=self.items[index];if(item.value==value){self.setSelectedIndex(index,duration,callback);return;}}};if($.fn){$.fn.picker=function(options){this.each(function(i,element){if(element.picker)return;if(options){element.picker=new Picker(element,options);}else{var optionsText=element.getAttribute('data-picker-options');var _options=optionsText?JSON.parse(optionsText):{};element.picker=new Picker(element,_options);}});return this[0]?this[0].picker:null;};$.ready(function(){$('.mui-picker').picker();});}})(window.mui||window,window,document,undefined);