首页 >web前端 >html教程 >移动端 动画函数 的 封装_html/css_WEB-ITnose

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

WBOY
WBOY原创
2016-06-24 11:29:391481浏览

移动端 单页有时候 制作只用到简单的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();	}
声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn