Home  >  Article  >  Web Front-end  >  移动端 动画函数 的 封装_html/css_WEB-ITnose

移动端 动画函数 的 封装_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-24 11:29:391441browse

移动端 单页有时候 制作只用到简单的css3动画即可,我们简单封装一下,没必要引入zepto框架。

上面图片对应的 js

var leftsbox=document.getElementById("leftsbox");	  var boxdiv=leftsbox.getElementsByTagName("div");	  leftsbox.onclick=function(){		   for(var i=0;i<boxdiv.length;i++){			         var that=boxdiv[i];			 			 transform(that,{ translate3d:'220px,10px,0',left:'1em',opacity:0.2,perspective:'400px', rotateY:'30deg'},800,'cubic-bezier(0.15, 0.5, 0.25, 1.0)',function(){							   this.innerHTML='结束回调'+this.innerHTML;						},100*i);			} //for

再看看另外一种 常见的 如下图

上面对用的 js 代码

var nav=document.querySelector(".nav");			var nava=nav.getElementsByTagName("li");			var content=document.querySelector(".content");			var ulcontent=document.getElementById("ulcontent");			ulcontent.style.width=nav.offsetWidth*nava.length+'px';			for(var i=0;i<nava.length;i++) {				nava[i].index=i;				nava[i].onclick=function(){					var that=this;					var now=-(that.index)*content.offsetWidth+'px';					 transform(ulcontent,{translate3d:''+now+',0,0',},'linear',function(){					//console.log('success   回调函数');					})				}//click end			}

htm结构

<ul class="nav">	        <li ><a >首页</a></li>	        <li ><a >插件</a></li>	        <li ><a >新闻</a></li>	        <li ><a >其他</a></li>	    </ul>        <div class="content">        <ul id="ulcontent" >        <li ><img  src="../../images/1a.jpg" alt="移动端 动画函数 的 封装_html/css_WEB-ITnose" ></li>        <li ><img  src="../../images/2a.jpg" alt="移动端 动画函数 的 封装_html/css_WEB-ITnose" ></li>        <li ><img  src="../../images/3a.jpg" alt="移动端 动画函数 的 封装_html/css_WEB-ITnose" ></li>        <li   style="max-width:90%" >44444444444</li>        </ul>     </div>

基于zepto动画独立出来,语法类似zepto 动画

$("#some_element").animate(    {        opacity:0.25,        left:'50px',        color:'#abcdef',        rotateZ:'45deg',        translate3d:'0,10px,0'    },    500,    'ease-out',function(){  alert('回调'); })

改写后 独立与zepto的 动画函数 语法如下

transform(element,{ translate3d:'220px,10px,0',left:'1em',opacity:0.2,perspective:'400px', rotateY:'30deg'},duration,'linear',fn,delay);

关于兼容性:几乎与zepto一致 ,但是不支持 动画帧 keyframe,个人觉得  keyframe移动端 兼容性不是很好,尤其手机自带的浏览器(原生app 调用 内嵌H5页面,小问题还是蛮多的);

源码如下

//transform(obj,{translateX:'150px',left:'1em',opacity:0.2,perspective:'400px', rotateY:'40deg'},duration,'linear',fn,delay);               				;(function(window,document,undefined){var prefix = function() {  var div = document.createElement('div');//建立临时DIV容器  var cssText = '-webkit-transition:all .1s;-moz-transition:all .1s; -Khtml-transition:all .1s; -o-transition:all .1s; -ms-transition:all .1s; transition:all .1s;';  div.style.cssText = cssText;  var style = div.style;  var dom='';  if (style.webkitTransition) {	  dom ='webkit';  }  if (style.MozTransition) {    dom='moz';  }   if (style.khtmlTransition) {    dom='Khtml';  }    if (style.oTransition) {    dom='o';  }  if (style.msTransition) {    dom='ms';  }   div=null; ////去掉不必要的数据存储,便于垃圾回收   if(dom){////style.transition 情况	  return {		dom: dom,		lowercase: dom,		css: '-' + dom + '-',		js: dom[0].toUpperCase() + dom.substr(1)	  };   }else{	  return false;   }}();//alert(prefix.js);var transitionEnd=function () {  var el = document.createElement('div');  var transEndEventNames = {    WebkitTransition : 'webkitTransitionEnd',    MozTransition    : 'transitionend',    OTransition      : 'oTransitionEnd',    msTransition    : 'MSTransitionEnd',    transition       : 'transitionend'  };  for (var name in transEndEventNames) {    if (el.style[name] !== undefined) {	    return  transEndEventNames[name] ;    }  }    el=null;  return false;  }();//alert('支持'+transitionEnd);var supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i; //变形检测var dasherize=function (str) {    return str.replace(/::/g, '/') //将::替换成/    .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') //在大小写字符之间插入_,大写在前,比如AAAbb,得到AA_Abb    .replace(/([a-z\d])([A-Z])/g, '$1_$2') //在大小写字符之间插入_,小写或数字在前,比如bbbAaa,得到bbb_Aaa    .replace(/_/g, '-') //将_替换成-    .toLowerCase() //转成小写  }var transform=function (obj,properties, duration, ease, callback, delay){			 if (!obj) return;	//参数修正		  if (typeof duration == 'function')      callback = duration, ease = undefined, duration = 400,delay=delay      if (typeof ease == 'function')  //传参为function(properties,duration,callback)        callback = ease, ease = undefined,delay=delay           if (duration) duration = typeof duration == 'number' ? duration :400;		  delay = (typeof delay == 'number') ? delay :0;	       	//参数修正	var nowTransition=prefix.js+'Transition';	var nowTransform=prefix.js+'Transform';	var prefixcss=prefix.css;	if(!prefix.js){		nowTransition='transition';	    nowTransform='transform';		prefixcss='';  //-webkit-transition >> transition  	}		var transitionProperty, transitionDuration, transitionTiming, transitionDelay;//过渡	var key, cssValues = {}, cssProperties, transforms = "";    // transforms 变形   cssValues设置给DOM的样式	var transform;     //变形    var cssReset = {};	var css='';	var cssProperties = [];			  transform = prefixcss + 'transform';       //变形    cssValues[transform]	  cssReset[transitionProperty = prefixcss + 'transition-property'] =	  cssReset[transitionDuration = prefixcss + 'transition-duration'] =	  cssReset[transitionDelay    = prefixcss + 'transition-delay'] =	  cssReset[transitionTiming   = prefixcss + 'transition-timing-function']='';		      // CSS transitions	     for (key in properties){       //如果设置 的CSS属性是变形之类的       if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') '       else cssValues[key] = properties[key], cssProperties.push(dasherize(key))	 } //for end        if (transforms) cssValues[transform] = transforms, cssProperties.push(transform)	          if (duration > 0 && typeof properties === 'object') {         cssValues[transitionProperty] = cssProperties.join(', ')         cssValues[transitionDuration] = duration + 'ms'         cssValues[transitionTiming] = (ease || 'linear')		 cssValues[transitionDelay] = delay + 'ms'       }                      for(var attr in cssValues){				  css += dasherize(attr) + ':' + cssValues[attr]+ ';'							  }						obj.style.cssText=obj.style.cssText+css;						    	  		if(!callback){return } //没有回调函数 return	    var fired = false;		var handler = function () {				 callback && callback.apply(obj,arguments);				 fired=true;				  				if(obj.removeEventListener)				 obj.removeEventListener(transitionEnd,arguments.callee,false)				        };          		  if(obj.addEventListener){	       obj.addEventListener(transitionEnd, handler,false);		  }				  if(!transitionEnd||duration<=0){ //没有  @1 transitionEnd 事件    或者@2 duration为0,即浏览器不支持动画的情况  直接执行动画结束,执行回调。     			 setTimeout(function(){			 handler();			 });			return;		  }		   						 setTimeout(function(){//绑定过事件还做延时处理,是transitionEnd在older Android phones不一定触发			    if(fired) return				  handler()			},(duration + delay) + 25);									  }//end   window.transform=transform;})(window,document);

唯一的缺点  scrollTop 缓动不支持; 这里有个简易的  函数 类似jquery  语法几乎一样

先看效果

相关布局

<ul id="inner" >        <li><a class="on" >护肤</a></li>        <li><a >彩妆</a></li>        <li><a >洗护</a></li>        <li><a >套装</a></li>    </ul>         <ul class="uls" id="uls">        <li id='li1'></li>         <li id='li12'></li>         <li id='li3'></li>   </ul>         <div class="box22"> <div class="boxs">1111111111111111111111111111111111</div>  <div class="boxs">22222222222222222222222222222</div>     <div class="boxs">33333333333333333333333</div>  <div class="boxs" style="height:100px;">4444444444444444444最后一个 </div> </div>   <div id="gpTop">tops</div>

上图相关js

  document.getElementById("gpTop").onclick=function(e){              var  that=this;                 startMove(that,{"scrollTop":0},function(){                    that.innerHTML='到顶了';                     });  //width: 206px; height: 101px; opacity: 0.3;                }                                                var inner=document.getElementById("inner");                var inlione=inner.getElementsByTagName("li");                var box=document.querySelectorAll(".boxs");                                for(var i=0;i<inlione.length;i++) {                   inlione[i].index=i;                 inlione[i].onclick=function(e){                 var that=this;                // console.log(that.index);                 var box2=box[that.index];                 var nowTop=getOffest(box2).top;                // console.log(nowTop);                                   startMove(window,{"scrollTop":nowTop},function(){                    //console.log('success');                    });           }                     }

如果通过原生js  获取  jquey的offset().top  的值呢 如下  这里

  var getOffest=function (obj){var top=0,left=0;if(obj){ while(obj.offsetParent){      top += obj.offsetTop;      left += obj.offsetLeft;      obj = obj.offsetParent;   } }  return{  top : top,  left : left  }}

startMove基于 requestAnimationFrame  兼容ie8+   

语法如下

startMove(element,{"left":1300,"opacity":90},2000,'easeOut',function sa(){			  console.log('回调函数');			 });  //  width: 201px; height: 135px; opacity: 0.8;  只有宽是对的  其他未达到目标
;(function() {  var lastTime = 0;  var vendors = ['ms', 'moz', 'webkit', 'o'];  for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];    window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];  }  if (!window.requestAnimationFrame) {    window.requestAnimationFrame = function(callback, element) {      var currTime = new Date().getTime();      var timeToCall = Math.max(0, 16 - (currTime - lastTime));      var id = window.setTimeout(function() { callback(currTime + timeToCall); },        timeToCall);      lastTime = currTime + timeToCall;      return id;    };  }  if (!window.cancelAnimationFrame) {    window.cancelAnimationFrame = function(id) {      clearTimeout(id);    };  }}());var getStyle=function (obj,attr){	return obj.currentStyle ? obj.currentStyle[attr]:getComputedStyle(obj)[attr];}		  var Tween = {	linear: function (t, b, c, d){  //匀速		return c*t/d + b;	},	easeIn: function(t, b, c, d){  //加速曲线		return c*(t/=d)*t + b;	},	easeOut: function(t, b, c, d){  //减速曲线		return -c *(t/=d)*(t-2) + b;	},	easeBoth: function(t, b, c, d){  //加速减速曲线		if ((t/=d/2) < 1) {			return c/2*t*t + b;		}		return -c/2 * ((--t)*(t-2) - 1) + b;	},	easeInStrong: function(t, b, c, d){  //加加速曲线		return c*(t/=d)*t*t*t + b;	},	easeOutStrong: function(t, b, c, d){  //减减速曲线		return -c * ((t=t/d-1)*t*t*t - 1) + b;	},	easeBothStrong: function(t, b, c, d){  //加加速减减速曲线		if ((t/=d/2) < 1) {			return c/2*t*t*t*t + b;		}		return -c/2 * ((t-=2)*t*t*t - 2) + b;	},	elasticIn: function(t, b, c, d, a, p){  //正弦衰减曲线(弹动渐入)		if (t === 0) { 			return b; 		}		if ( (t /= d) == 1 ) {			return b+c; 		}		if (!p) {			p=d*0.3; 		}		if (!a || a < Math.abs(c)) {			a = c; 			var s = p/4;		} else {			var s = p/(2*Math.PI) * Math.asin (c/a);		}		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;	},	elasticOut: function(t, b, c, d, a, p){    //正弦增强曲线(弹动渐出)		if (t === 0) {			return b;		}		if ( (t /= d) == 1 ) {			return b+c;		}		if (!p) {			p=d*0.3;		}		if (!a || a < Math.abs(c)) {			a = c;			var s = p / 4;		} else {			var s = p/(2*Math.PI) * Math.asin (c/a);		}		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;	},    	elasticBoth: function(t, b, c, d, a, p){		if (t === 0) {			return b;		}		if ( (t /= d/2) == 2 ) {			return b+c;		}		if (!p) {			p = d*(0.3*1.5);		}		if ( !a || a < Math.abs(c) ) {			a = c; 			var s = p/4;		}		else {			var s = p/(2*Math.PI) * Math.asin (c/a);		}		if (t < 1) {			return - 0.5*(a*Math.pow(2,10*(t-=1)) * 					Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;		}		return a*Math.pow(2,-10*(t-=1)) * 				Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;	}}var now=function (){	return +new Date();}function startMove(obj,json,times,fx,fn){		if( typeof times == 'undefined' ){		times = 400;		fx = 'linear';	}		if( typeof times == 'string' ){		if(typeof fx == 'function'){			fn = fx;		}		fx = times;		times = 400;	}	else if(typeof times == 'function'){		fn = times;		times = 400;		fx = 'linear';	}	else if(typeof times == 'number'){		if(typeof fx == 'function'){			fn = fx;			fx = 'linear';		}		else if(typeof fx == 'undefined'){			fx = 'linear';		}	}			var iCur = {};	var startTime = now();		for(var attr in json){		iCur[attr] = 0;				if( attr == 'opacity' ){			if(Math.round(getStyle(obj,attr)*100) == 0){				iCur[attr] = 0;			}			else{				iCur[attr] = Math.round(getStyle(obj,attr)*100) || 100;			}		}		else if(attr == 'scrollTop' ){			     iCur[attr]=window.scrollY|| window.pageYOffset|| document.documentElement.scrollTop;		 			}		else{			iCur[attr] = parseInt(getStyle(obj,attr)) || 0;		}			}			    if(obj.timer){		cancelAnimationFrame(obj.timer)		}		//obj.timer=null;		function update(){					var changeTime = now();		var scale = 1 - Math.max(0,startTime - changeTime + times)/times;				for(var attr in json){						var value = Tween[fx](scale*times, iCur[attr] , json[attr] - iCur[attr] , times );						if(attr == 'opacity'){				obj.style.filter = 'alpha(opacity='+ value +')';				obj.style.opacity = value/100;			}else if(attr == 'scrollTop'){				 window.scrollTo(0, value); 		   }else{				obj.style[attr] = value + 'px';			}					}				if(scale == 1){			    cancelAnimationFrame(obj.timer);			 	fn&&fn.call(obj);				console.log('222222222222');		}else{			 //setup_fps_meters();						obj.timer=requestAnimationFrame(arguments.callee);			}		   }//update  end   //	requestAnimationFrame(update);  //某些时候 画的过快  有bug	update();	}
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn