• 利用tween.js算法生成缓动效果


      在讲tween类之前,不得不提的是贝塞尔曲线了。首先,贝塞尔曲线是指依据四个位置任意的点坐标绘制出的一条光滑曲线。它在作图工具或动画中中运用得比较多,例如PS中的钢笔工具,firework中的画笔等等。无论运用在哪里,它们的原理都是一样的。同样,在用js实现运动效果时,我们也可以利用贝塞尔曲线来实现不同的特效,而tween.js就是一个封装好的计算辅助算法。你可以通过连续输入多个值,然后利用贝塞尔曲线公式输出不同的值,最终形成了一条光滑的曲线。因为一条曲线上的值的不一样的,所以我们可以利用曲线的特性创造出不同的效果。

      tween.js封装了多种效果的计算方法,我们可以利用里面的公式或者自己重写方法。以下是源代码,可根据自己的需要增删使用。 

      1 // Tween类
      2 var Tween = {
      3     Linear: function(t,b,c,d){ return c*t/d + b; },
      4     Quad: {
      5         easeIn: function(t,b,c,d){
      6             return c*(t/=d)*t + b;
      7         },
      8         easeOut: function(t,b,c,d){
      9             return -c *(t/=d)*(t-2) + b;
     10         },
     11         easeInOut: function(t,b,c,d){
     12             if ((t/=d/2) < 1) return c/2*t*t + b;
     13             return -c/2 * ((--t)*(t-2) - 1) + b;
     14         }
     15     },
     16     Cubic: {
     17         easeIn: function(t,b,c,d){
     18             return c*(t/=d)*t*t + b;
     19         },
     20         easeOut: function(t,b,c,d){
     21             return c*((t=t/d-1)*t*t + 1) + b;
     22         },
     23         easeInOut: function(t,b,c,d){
     24             if ((t/=d/2) < 1) return c/2*t*t*t + b;
     25             return c/2*((t-=2)*t*t + 2) + b;
     26         }
     27     },
     28     Quart: {
     29         easeIn: function(t,b,c,d){
     30             return c*(t/=d)*t*t*t + b;
     31         },
     32         easeOut: function(t,b,c,d){
     33             return -c * ((t=t/d-1)*t*t*t - 1) + b;
     34         },
     35         easeInOut: function(t,b,c,d){
     36             if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
     37             return -c/2 * ((t-=2)*t*t*t - 2) + b;
     38         }
     39     },
     40     Quint: {
     41         easeIn: function(t,b,c,d){
     42             return c*(t/=d)*t*t*t*t + b;
     43         },
     44         easeOut: function(t,b,c,d){
     45             return c*((t=t/d-1)*t*t*t*t + 1) + b;
     46         },
     47         easeInOut: function(t,b,c,d){
     48             if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
     49             return c/2*((t-=2)*t*t*t*t + 2) + b;
     50         }
     51     },
     52     Sine: {
     53         easeIn: function(t,b,c,d){
     54             return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
     55         },
     56         easeOut: function(t,b,c,d){
     57             return c * Math.sin(t/d * (Math.PI/2)) + b;
     58         },
     59         easeInOut: function(t,b,c,d){
     60             return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
     61         }
     62     },
     63     Expo: {
     64         easeIn: function(t,b,c,d){
     65             return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
     66         },
     67         easeOut: function(t,b,c,d){
     68             return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
     69         },
     70         easeInOut: function(t,b,c,d){
     71             if (t==0) return b;
     72             if (t==d) return b+c;
     73             if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
     74             return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
     75         }
     76     },
     77     Circ: {
     78         easeIn: function(t,b,c,d){
     79             return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
     80         },
     81         easeOut: function(t,b,c,d){
     82             return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
     83         },
     84         easeInOut: function(t,b,c,d){
     85             if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
     86             return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
     87         }
     88     },
     89     Elastic: {
     90         easeIn: function(t,b,c,d,a,p){
     91             if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
     92             if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
     93             else var s = p/(2*Math.PI) * Math.asin (c/a);
     94             return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
     95         },
     96         easeOut: function(t,b,c,d,a,p){
     97             if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
     98             if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
     99             else var s = p/(2*Math.PI) * Math.asin (c/a);
    100             return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
    101         },
    102         easeInOut: function(t,b,c,d,a,p){
    103             if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
    104             if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
    105             else var s = p/(2*Math.PI) * Math.asin (c/a);
    106             if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
    107             return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
    108         }
    109     },
    110     Back: {
    111         easeIn: function(t,b,c,d,s){
    112             if (s == undefined) s = 1.70158;
    113             return c*(t/=d)*t*((s+1)*t - s) + b;
    114         },
    115         easeOut: function(t,b,c,d,s){
    116             if (s == undefined) s = 1.70158;
    117             return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
    118         },
    119         easeInOut: function(t,b,c,d,s){
    120             if (s == undefined) s = 1.70158; 
    121             if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
    122             return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
    123         }
    124     },
    125     Bounce: {
    126         easeIn: function(t,b,c,d){
    127             return c - Tween.Bounce.easeOut(d-t, 0, c, d) + b;
    128         },
    129         easeOut: function(t,b,c,d){
    130             if ((t/=d) < (1/2.75)) {
    131                 return c*(7.5625*t*t) + b;
    132             } else if (t < (2/2.75)) {
    133                 return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
    134             } else if (t < (2.5/2.75)) {
    135                 return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
    136             } else {
    137                 return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
    138             }
    139         },
    140         easeInOut: function(t,b,c,d){
    141             if (t < d/2) return Tween.Bounce.easeIn(t*2, 0, c, d) * .5 + b;
    142             else return Tween.Bounce.easeOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
    143         }
    144     }
    145 };
    点击展开源代码

      下载地址:http://pan.baidu.com/s/1sjQdWQx

      这个算法可以用在很多地方,如果滚动条的移动,物块的移动或各种渐变等等。今天我就用物块移动demo的例子来讲讲这个辅助计算类怎么用吧,首先我们得创建一个定时器或者函数,一下是我常用的方法。

     1             //利用tween.js返回特殊值,生成不同效果
     2             function tweenFn(obj,attr,value,endFn){
     3                 var timer = null;
     4                 var start = 0;        //开始位置
     5 //                var value = value        //改变值大小
     6                 var t = 0;                //从0步开始
     7                 var endT = 30;            //结束步数
     8                 clearInterval(timer);
     9                 timer = setInterval(function(){
    10                             t++;
    11                             if(t>endT){
    12                                 clearInterval(timer);
    13                                 endFn && endFn();//回调函数存在则返回
    14                                 return;
    15                             };
    16                         obj.style[attr] = Tween.Cubic.easeInOut(t,start,value,endT)+"px";
    17                 },30);
    18             }

      函数说明:obj,绑定执行的对象;

           attr,改变的属性值;

           value,改变值的大小;

           endFn,执行完毕的回调函数,没有可不写;

           start,属性初始值;

           t,endT,执行的步数,可理解为分多少次执行完。

          函数第十六行中Tween.Cubic.easeInOut(...)为调用tween.js中的方法,可根据实际需求修改Cubic或easeInOut的值。我把里面所有的方法列表如下:

    Linear

    线性匀速变化

    Quad

    easeIn

    easeOut

    easeInOut  
    二次方缓动 Expo

    easeIn

    easeOut

    easeInOut
    指数曲线缓动
    Cubic

    easeIn

    easeOut

    easeInOut  
    三次方缓动 Circ  easeIn

    easeOut

    easeInOut  
    圆周曲线缓动
    Quart  easeIn

    easeOut

    easeInOut  
    四次方缓动 Elastic  easeIn

    easeOut

    easeInOut  
    弹性伸缩缓动
    Quint

    easeIn

    easeOut

    easeInOut   
    五次方缓动 Back  easeIn

    easeOut

    easeInOut  
    返回缓动
    Sine  easeIn

    easeOut

    easeInOut  
    正弦曲线缓动 Bounce  easeIn

    easeOut

    easeInOut  
    跳动缓动

      请查看本人写的Demo,里面包含了所有效果:www.chengguanhui.com/demos/tween/index.html

     

  • 相关阅读:
    【新特性速递】数字输入框的前缀和后缀(位于输入框内部)
    【新特性速递】进度条,进度条,进度条
    【新特性速递】当法语遇上FineUI(Bonjour)!
    【新特性速递】自定义数字输入框的小数分隔符和千分位分隔符
    【经验分享】FineUICore中如何处理文件导出异常?
    【网友作品】服装分销系统架构与界面分享(基于FineUICore基础版)
    FineUIPro/Mvc/Core v6.3.0 正式发布了!
    星球居民突破 1700 人!
    【新特性速递】开关样式复选框增强!
    【新特性速递】为RenderField新增QuickSortField属性!
  • 原文地址:https://www.cnblogs.com/chengguanhui/p/4664144.html
Copyright © 2020-2023  润新知