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

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

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
}
<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"></li>
<li ><img src="../../images/2a.jpg"></li>
<li ><img src="../../images/3a.jpg"></li>
<li style="background:#ddd;" >44444444444</li>
</ul>
</div>
$("#some_element").animate(
{
opacity:0.25,
left:‘50px‘,
color:‘#abcdef‘,
rotateZ:‘45deg‘,
translate3d:‘0,10px,0‘
},
500,
‘ease-out‘,function(){ alert(‘回调‘); }
)
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);
先看效果

<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>
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‘);
});
}
}
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(element,{"left":1300,"opacity":90},2000,‘easeOut‘,function sa(){
console.log(‘回调函数‘);
}); // width: 201px; height: 135px; opacity: 0.8; 只有宽是对的 其他未达到目标
浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果。比如,通过requestAnimationFrame(),JS动画能够和CSS动画/变换或SVG SMIL动画同步发生。另外,如果在一个浏览器标签页里运行一个动画,当这个标签页不可见时,浏览器会暂停它,这会减少CPU,内存的压力,节省电池电量。
相信日后 requestAnimationFrame 在移动端发展的前景是相当不错的,目前安卓上感觉还是有点丢帧。抖动明显;
如下 jquery:
// Start an animation from one number to another
custom: function( from, to, unit ) {
var self = this,
fx = jQuery.fx,
raf;
this.startTime = fxNow || createFxNow();
this.start = from;
this.end = to;
this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
this.now = this.start;
this.pos = this.state = 0;
function t( gotoEnd ) {
return self.step(gotoEnd);
}
t.elem = this.elem;
if ( t() && jQuery.timers.push(t) && !timerId ) {
// Use requestAnimationFrame instead of setInterval if available
if ( requestAnimationFrame ) {
timerId = true;
raf = function() {
// When timerId gets set to null at any point, this stops
if ( timerId ) {
requestAnimationFrame( raf );
fx.tick();
}
};
requestAnimationFrame( raf );
} else {
timerId = setInterval( fx.tick, fx.interval );
}
}
},
http://stackoverflow.com/questions/7999680/why-doesnt-jquery-use-requestanimationframe
为啥jquery 放弃,上面说的比较完善;
;(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();
}
另外比较强大的 动画库 推荐
http://daniel-lundin.github.io/snabbt.js/index.html
标签:
原文地址:http://www.cnblogs.com/surfaces/p/5129868.html