在页面中实现运动的四种方式

1.速度版:

 1 function startMove(obj,json,fnEnd){
 2     if(obj.timer){
 3         clearInterval(obj.timer);
 4     }
 5     obj.timer = setInterval(function(){
 6         doMove(obj,json,fnEnd);
 7     },30);
 8 }
 9 function doMove(obj,json,fnEnd){
10     var iCur = 0;
11     var attr = null;
12     var bStop = true;
13     for(attr in json){
14         if(attr=='opacity'){
15             iCur = parseInt(100*parseFloat(getStyle(obj,attr)));
16         }
17         else{
18             iCur = parseInt(getStyle(obj,attr));
19         }
20         var iSpeed = (json[attr] - iCur)/8;
21         iSpeed = iSpeed>0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
22         if(json[attr]!=iCur){
23             bStop = false;
24         }
25         if(attr=='opacity'){
26             obj.style.filter = 'alpha(opacity='+ (iCur + iSpeed) +')';
27             obj.style.opacity = (iCur + iSpeed)/100;
28         }
29         else{
30             obj.style[attr] = iCur + iSpeed + 'px';
31         }
32     }
33     if(bStop){
34         clearInterval(obj.timer);
35         obj.timer = null;
36         if(fnEnd){
37             fnEnd();
38         }
39     }
40 }
41 function getStyle(obj,attr){
42     if(obj.currentStyle){
43         return obj.currentStyle[attr];
44     }
45     else{
46         return getComputedStyle(obj)[attr];
47     }
48 }

速度版运动框架有个小问题,不是代码的问题,而是浏览器本身的功能问题。当运动途中,切换页面或缩小浏览器窗口后,浏览器会自动放慢页面中所有的定时器,这样可能会导致页面中的定时器出问题:比如有的定时器有回调函数,有的定时器没有,当重新切换回原来的页面时,有回调函数的定时器可能回调会来不及执行,造成页面中定时器的混乱状态,影响页面的效果。如果是一个简单的轮播图效果,我们可以使用如下代码简单处理下:

1 window.onfocus = function(){
2     console.log(1);
3     timer = setInterval(toRun,2000);
4 };
5 
6 window.onblur = function(){
7     console.log(2);
8     clearInterval(timer);
9 };

 

2.时间版:

  1 function startMove(obj,json,times,fx,fn){
  2     
  3     if( typeof times == 'undefined' ){
  4         times = 400;
  5         fx = 'linear';
  6     }
  7     
  8     if( typeof times == 'string' ){        
  9         if(typeof fx == 'function'){
 10             fn = fx;
 11         }
 12         fx = times;
 13         times = 400;
 14     }
 15     else if(typeof times == 'function'){
 16         fn = times;
 17         times = 400;
 18         fx = 'linear';
 19     }
 20     else if(typeof times == 'number'){
 21         if(typeof fx == 'function'){
 22             fn = fx;
 23             fx = 'linear';
 24         }
 25         else if(typeof fx == 'undefined'){
 26             fx = 'linear';
 27         }
 28     }
 29     
 30     var iCur = {};
 31     for(var attr in json){
 32         iCur[attr] = 0;
 33         attr == 'opacity' ? iCur[attr] = Math.round(getStyle(obj,attr)*100) : iCur[attr] = parseInt(getStyle(obj,attr));
 34     }
 35     
 36     var startTime = now();    
 37     clearInterval(obj.timer);
 38     
 39     obj.timer = setInterval(function(){
 40         
 41         var changeTime = now();     
 42         var t = times - Math.max(0,startTime - changeTime + times);  
 43         
 44         for(var attr in json){
 45             
 46             var value = Tween[fx](t,iCur[attr],json[attr]-iCur[attr],times);
 47             
 48             if(attr == 'opacity'){
 49                 obj.style.opacity = value/100;
 50                 obj.style.filter = 'alpha(opacity='+value+')';
 51             }
 52             else{
 53                 obj.style[attr] = value + 'px';
 54             }
 55             
 56         }
 57         
 58         if(t == times){ 
 59             clearInterval(obj.timer);
 60             fn && fn.call(obj); 
 61         }
 62         
 63     },20);
 64     
 65     function getStyle(obj,attr){ return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj,false)[attr]; }
 66     function now(){ return (new Date()).getTime(); }    
 67 };
 68 
 69 var Tween = {
 70     linear: function (t, b, c, d){  //匀速
 71         return c*t/d + b;
 72     },
 73     easeIn: function(t, b, c, d){  //加速曲线
 74         return c*(t/=d)*t + b;
 75     },
 76     easeOut: function(t, b, c, d){  //减速曲线
 77         return -c *(t/=d)*(t-2) + b;
 78     },
 79     easeBoth: function(t, b, c, d){  //加速减速曲线
 80         if ((t/=d/2) < 1) {
 81             return c/2*t*t + b;
 82         }
 83         return -c/2 * ((--t)*(t-2) - 1) + b;
 84     },
 85     easeInStrong: function(t, b, c, d){  //加加速曲线
 86         return c*(t/=d)*t*t*t + b;
 87     },
 88     easeOutStrong: function(t, b, c, d){  //减减速曲线
 89         return -c * ((t=t/d-1)*t*t*t - 1) + b;
 90     },
 91     easeBothStrong: function(t, b, c, d){  //加加速减减速曲线
 92         if ((t/=d/2) < 1) {
 93             return c/2*t*t*t*t + b;
 94         }
 95         return -c/2 * ((t-=2)*t*t*t - 2) + b;
 96     },
 97     elasticIn: function(t, b, c, d, a, p){  //正弦衰减曲线(弹动渐入)
 98         if (t === 0) { 
 99             return b; 
100         }
101         if ( (t /= d) == 1 ) {
102             return b+c; 
103         }
104         if (!p) {
105             p=d*0.3; 
106         }
107         if (!a || a < Math.abs(c)) {
108             a = c; 
109             var s = p/4;
110         } else {
111             var s = p/(2*Math.PI) * Math.asin (c/a);
112         }
113         return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
114     },
115     elasticOut: function(t, b, c, d, a, p){    //正弦增强曲线(弹动渐出)
116         if (t === 0) {
117             return b;
118         }
119         if ( (t /= d) == 1 ) {
120             return b+c;
121         }
122         if (!p) {
123             p=d*0.3;
124         }
125         if (!a || a < Math.abs(c)) {
126             a = c;
127             var s = p / 4;
128         } else {
129             var s = p/(2*Math.PI) * Math.asin (c/a);
130         }
131         return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
132     },    
133     elasticBoth: function(t, b, c, d, a, p){
134         if (t === 0) {
135             return b;
136         }
137         if ( (t /= d/2) == 2 ) {
138             return b+c;
139         }
140         if (!p) {
141             p = d*(0.3*1.5);
142         }
143         if ( !a || a < Math.abs(c) ) {
144             a = c; 
145             var s = p/4;
146         }
147         else {
148             var s = p/(2*Math.PI) * Math.asin (c/a);
149         }
150         if (t < 1) {
151             return - 0.5*(a*Math.pow(2,10*(t-=1)) * 
152                     Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
153         }
154         return a*Math.pow(2,-10*(t-=1)) * 
155                 Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
156     },
157     backIn: function(t, b, c, d, s){     //回退加速(回退渐入)
158         if (typeof s == 'undefined') {
159            s = 1.70158;
160         }
161         return c*(t/=d)*t*((s+1)*t - s) + b;
162     },
163     backOut: function(t, b, c, d, s){
164         if (typeof s == 'undefined') {
165             s = 3.70158;  //回缩的距离
166         }
167         return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
168     }, 
169     backBoth: function(t, b, c, d, s){
170         if (typeof s == 'undefined') {
171             s = 1.70158; 
172         }
173         if ((t /= d/2 ) < 1) {
174             return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
175         }
176         return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
177     },
178     bounceIn: function(t, b, c, d){    //弹球减振(弹球渐出)
179         return c - Tween['bounceOut'](d-t, 0, c, d) + b;
180     },       
181     bounceOut: function(t, b, c, d){
182         if ((t/=d) < (1/2.75)) {
183             return c*(7.5625*t*t) + b;
184         } else if (t < (2/2.75)) {
185             return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
186         } else if (t < (2.5/2.75)) {
187             return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
188         }
189         return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
190     },      
191     bounceBoth: function(t, b, c, d){
192         if (t < d/2) {
193             return Tween['bounceIn'](t*2, 0, c, d) * 0.5 + b;
194         }
195         return Tween['bounceOut'](t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
196     }
197 }

时间版函数是基于Tween的扩展,利用了Tween的运动样式,当然jQuery也是基于Tween的时间版运动,但是并没有扩展Tween中的更多的运动形式,如果需要,我们还可以扩展jQuery的运动形式,编写一个扩展jQuery的运动插件。

3.jQuery运动插件扩展:

  1 $.extend(jQuery.easing , {
  2     
  3     easeIn: function(x,t, b, c, d){  //加速曲线
  4         return c*(t/=d)*t + b;
  5     },
  6     easeOut: function(x,t, b, c, d){  //减速曲线
  7         return -c *(t/=d)*(t-2) + b;
  8     },
  9     easeBoth: function(x,t, b, c, d){  //加速减速曲线
 10         if ((t/=d/2) < 1) {
 11             return c/2*t*t + b;
 12         }
 13         return -c/2 * ((--t)*(t-2) - 1) + b;
 14     },
 15     easeInStrong: function(x,t, b, c, d){  //加加速曲线
 16         return c*(t/=d)*t*t*t + b;
 17     },
 18     easeOutStrong: function(x,t, b, c, d){  //减减速曲线
 19         return -c * ((t=t/d-1)*t*t*t - 1) + b;
 20     },
 21     easeBothStrong: function(x,t, b, c, d){  //加加速减减速曲线
 22         if ((t/=d/2) < 1) {
 23             return c/2*t*t*t*t + b;
 24         }
 25         return -c/2 * ((t-=2)*t*t*t - 2) + b;
 26     },
 27     elasticIn: function(x,t, b, c, d, a, p){  //正弦衰减曲线(弹动渐入)
 28         if (t === 0) { 
 29             return b; 
 30         }
 31         if ( (t /= d) == 1 ) {
 32             return b+c; 
 33         }
 34         if (!p) {
 35             p=d*0.3; 
 36         }
 37         if (!a || a < Math.abs(c)) {
 38             a = c; 
 39             var s = p/4;
 40         } else {
 41             var s = p/(2*Math.PI) * Math.asin (c/a);
 42         }
 43         return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
 44     },
 45     elasticOut: function(x,t, b, c, d, a, p){    //正弦增强曲线(弹动渐出)
 46         if (t === 0) {
 47             return b;
 48         }
 49         if ( (t /= d) == 1 ) {
 50             return b+c;
 51         }
 52         if (!p) {
 53             p=d*0.3;
 54         }
 55         if (!a || a < Math.abs(c)) {
 56             a = c;
 57             var s = p / 4;
 58         } else {
 59             var s = p/(2*Math.PI) * Math.asin (c/a);
 60         }
 61         return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
 62     },    
 63     elasticBoth: function(x,t, b, c, d, a, p){
 64         if (t === 0) {
 65             return b;
 66         }
 67         if ( (t /= d/2) == 2 ) {
 68             return b+c;
 69         }
 70         if (!p) {
 71             p = d*(0.3*1.5);
 72         }
 73         if ( !a || a < Math.abs(c) ) {
 74             a = c; 
 75             var s = p/4;
 76         }
 77         else {
 78             var s = p/(2*Math.PI) * Math.asin (c/a);
 79         }
 80         if (t < 1) {
 81             return - 0.5*(a*Math.pow(2,10*(t-=1)) * 
 82                     Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
 83         }
 84         return a*Math.pow(2,-10*(t-=1)) * 
 85                 Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
 86     },
 87     backIn: function(x,t, b, c, d, s){     //回退加速(回退渐入)
 88         if (typeof s == 'undefined') {
 89            s = 1.70158;
 90         }
 91         return c*(t/=d)*t*((s+1)*t - s) + b;
 92     },
 93     backOut: function(x,t, b, c, d, s){
 94         if (typeof s == 'undefined') {
 95             s = 3.70158;  //回缩的距离
 96         }
 97         return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
 98     }, 
 99     backBoth: function(x,t, b, c, d, s){
100         if (typeof s == 'undefined') {
101             s = 1.70158; 
102         }
103         if ((t /= d/2 ) < 1) {
104             return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
105         }
106         return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
107     },
108     bounceIn: function(x,t, b, c, d){    //弹球减振(弹球渐出)
109         return c - this['bounceOut'](x,d-t, 0, c, d) + b;
110     },       
111     bounceOut: function(x,t, b, c, d){
112         if ((t/=d) < (1/2.75)) {
113             return c*(7.5625*t*t) + b;
114         } else if (t < (2/2.75)) {
115             return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
116         } else if (t < (2.5/2.75)) {
117             return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
118         }
119         return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
120     },      
121     bounceBoth: function(x,t, b, c, d){
122         if (t < d/2) {
123             return this['bounceIn'](x,t*2, 0, c, d) * 0.5 + b;
124         }
125         return this['bounceOut'](x,t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
126     }
127     
128 });

当页面需要扩展jQuery运动形式时,可以直接把这个代码拷在我们自己写的js文件中。

4.animation动画:

 1 @-moz-keyframes btnPage { 
 2   0% { -moz-transform: translateY(6px); }
 3   50% { -moz-transform: translateY(0); }
 4   100% { -moz-transform: translateY(6px); } 
 5 }
 6 @-webkit-keyframes btnPage { 
 7   0% { -webkit-transform: translateY(6px); }
 8   50% { -webkit-transform: translateY(0); }
 9   100% { -webkit-transform: translateY(6px); } 
10 }
11 @keyframes btnPage { 
12   0% { transform: translateY(6px); }
13   50% { transform: translateY(0); }
14   100% { transform: translateY(6px); } 
15 }
16 /*btn-page*/
17 .btn-page { 
18     position: fixed; 
19     _position: absolute; 
20     z-index: 100; 
21     left: 50%; 
22     bottom: 30px; 
23     _bottom: auto; 
24     margin-left: -12px; 
25     width: 25px; 
26     height: 17px; 
27     overflow: hidden; 
28     cursor: pointer; 
29     background-position: 0 -18px; 
30     _top: expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight -30)); 
31     -moz-animation: btnPage 1.2s ease-in-out infinite; 
32     -webkit-animation: btnPage 1.2s ease-in-out infinite; 
33     animation: btnPage 1.2s ease-in-out infinite; 
34 }

当我们的页面需要添加CSS3动画时,只需要定义好关键帧和运动的名称,然后把这个运动名称引入我们需要的class里面,就可以利用js动态的添加或改变CSS3动画了。

 

posted @ 2016-06-02 14:47  _yh  阅读(531)  评论(0编辑  收藏  举报