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

lewo的博客      2022-02-08     443

关键词:

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

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

// Tween类
var Tween = {
    Linear: function(t,b,c,d){ return c*t/d + b; },
    Quad: {
        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;
        },
        easeInOut: function(t,b,c,d){
            if ((t/=d/2) < 1) return c/2*t*t + b;
            return -c/2 * ((--t)*(t-2) - 1) + b;
        }
    },
    Cubic: {
        easeIn: function(t,b,c,d){
            return c*(t/=d)*t*t + b;
        },
        easeOut: function(t,b,c,d){
            return c*((t=t/d-1)*t*t + 1) + b;
        },
        easeInOut: function(t,b,c,d){
            if ((t/=d/2) < 1) return c/2*t*t*t + b;
            return c/2*((t-=2)*t*t + 2) + b;
        }
    },
    Quart: {
        easeIn: function(t,b,c,d){
            return c*(t/=d)*t*t*t + b;
        },
        easeOut: function(t,b,c,d){
            return -c * ((t=t/d-1)*t*t*t - 1) + b;
        },
        easeInOut: 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;
        }
    },
    Quint: {
        easeIn: function(t,b,c,d){
            return c*(t/=d)*t*t*t*t + b;
        },
        easeOut: function(t,b,c,d){
            return c*((t=t/d-1)*t*t*t*t + 1) + b;
        },
        easeInOut: function(t,b,c,d){
            if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
            return c/2*((t-=2)*t*t*t*t + 2) + b;
        }
    },
    Sine: {
        easeIn: function(t,b,c,d){
            return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
        },
        easeOut: function(t,b,c,d){
            return c * Math.sin(t/d * (Math.PI/2)) + b;
        },
        easeInOut: function(t,b,c,d){
            return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
        }
    },
    Expo: {
        easeIn: function(t,b,c,d){
            return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
        },
        easeOut: function(t,b,c,d){
            return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
        },
        easeInOut: function(t,b,c,d){
            if (t==0) return b;
            if (t==d) return b+c;
            if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
            return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
        }
    },
    Circ: {
        easeIn: function(t,b,c,d){
            return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
        },
        easeOut: function(t,b,c,d){
            return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
        },
        easeInOut: function(t,b,c,d){
            if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
            return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
        }
    },
    Elastic: {
        easeIn: function(t,b,c,d,a,p){
            if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.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;
        },
        easeOut: function(t,b,c,d,a,p){
            if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.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);
        },
        easeInOut: function(t,b,c,d,a,p){
            if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.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 -.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 )*.5 + c + b;
        }
    },
    Back: {
        easeIn: function(t,b,c,d,s){
            if (s == undefined) s = 1.70158;
            return c*(t/=d)*t*((s+1)*t - s) + b;
        },
        easeOut: function(t,b,c,d,s){
            if (s == undefined) s = 1.70158;
            return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
        },
        easeInOut: function(t,b,c,d,s){
            if (s == undefined) s = 1.70158; 
            if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
            return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
        }
    },
    Bounce: {
        easeIn: function(t,b,c,d){
            return c - Tween.Bounce.easeOut(d-t, 0, c, d) + b;
        },
        easeOut: function(t,b,c,d){
            if ((t/=d) < (1/2.75)) {
                return c*(7.5625*t*t) + b;
            } else if (t < (2/2.75)) {
                return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
            } else if (t < (2.5/2.75)) {
                return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
            } else {
                return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
            }
        },
        easeInOut: function(t,b,c,d){
            if (t < d/2) return Tween.Bounce.easeIn(t*2, 0, c, d) * .5 + b;
            else return Tween.Bounce.easeOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
        }
    }
};

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

//利用tween.js返回特殊值,生成不同效果
            function tweenFn(obj,attr,value,endFn){
                var timer = null;
                var start = 0;        //开始位置
//                var value = value        //改变值大小
                var t = 0;                //从0步开始
                var endT = 30;            //结束步数
                clearInterval(timer);
                timer = setInterval(function(){
                            t++;
                            if(t>endT){
                                clearInterval(timer);
                                endFn && endFn();//回调函数存在则返回
                                return;
                            };
                        obj.style[attr] = Tween.Cubic.easeInOut(t,start,value,endT)+"px";
                },30);
            }

函数说明: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  
跳动缓动

tween.js的动画效果

...用tween.js语法需要哪些条件来做运动 1.初始位置2.目标点缓动函数  1.linear 匀速  2.Quad二次方缓动效果  3.Cubic三次方缓动效果  4.Quart四次方缓动效果  5.Quint五次方缓动效果  6.Sin 查看详情

window.requestanimationframe与tween.js配合使用实现动画缓动效果

window.requestAnimationFrame概述window.requestAnimationFrame()这个方法是用来在页面重绘之前,通知浏览器调用一个指定的函数,以满足开发者操作动画的需求。这个方法接受一个函数为参,该函数会在重绘前调用。注意: 如果想得到连... 查看详情

tween.js动画效果

一、apply,和call的用法。先来一个与本次博文无关的东西,就是apply和call的用法。其实apply和call的用法都一样,只是他们的传参不一样。apply是数组,而call是单独的传,类似枚举。1.列子一把arguments转化为标准数组,可以使用push... 查看详情

tween.js

 简要教程tween.js是一款可生成平滑动画效果的js动画库。相关的动画库插件还有:snabbt.js强大的jQuery动画库插件和Tweene-超级强大的jQuery动画代理插件。tween.js允许你以平滑的方式修改元素的属性值。你只需要告诉tween你想修改... 查看详情

#wpf动画速率效果

...动函数来实现这一功能。除此之外,WPF还有关键帧动画,利用关键帧动画能够很好的控制动画的细节,与美工的很多设计保持完美一致。关键帧动画中还有一套叫做样条关键帧动画(SplineKeyFrame),这个动画利用一个三次贝塞尔... 查看详情

animationjs控制缓动效果

<!DOCTYPEhtml><html><head><metacharset="utf-8"/><title>缓动效果</title></head><body><divid="btn"style=‘position:absolute;‘>按钮</div><scripttyp 查看详情

使用鼠标滚轮平滑滚动缓动效果[关闭]

】使用鼠标滚轮平滑滚动缓动效果[关闭]【英文标题】:Smoothscrollingeasingeffectwithmousewheel[closed]【发布时间】:2012-02-2621:18:27【问题描述】:我最近看到了这个网站http://www.ascensionlatorre.com/home,我喜欢鼠标滚轮滚动的工作方式-缓... 查看详情

为啥我的旋转动画有缓动效果?

】为啥我的旋转动画有缓动效果?【英文标题】:Whythereiseasingeffectonmyrotatinganimation?为什么我的旋转动画有缓动效果?【发布时间】:2013-06-1016:34:20【问题描述】:我正在尝试开发我的第一个Android应用。我读了很多关于动画的文... 查看详情

易语言exui登录界面(附带缓动效果)源码

易语言EXUI登录界面(附带缓动效果)源码,调用了精易模块。登录的时候有动效果,可以更换配色,按钮样式和背景图片,界面做的挺好看。下载地址:https://6yunpan.pipipan.com/fs/17009107-357509637 查看详情

wpf中listbox滚动时的缓动效果

原文:WPF中ListBox滚动时的缓动效果 上周工作中遇到的问题:常规的ListBox在滚动时总是一格格的移动,感觉上很生硬。所以想要实现类似Flash中的那种缓动的效果,使ListBox滚动时可以很流畅。修改模板里的动画效果是一... 查看详情

镜头以及各种运动的缓动效果

...值的结果作为新的当前值,下一帧继续插值。实际产生的缓动效果比匀加速(减速)效果更好。可以加入两个控制参数,以调节变化的 查看详情

如何对精灵动作应用不同的缓动效果?

】如何对精灵动作应用不同的缓动效果?【英文标题】:Howtoapplydifferenteasingeffectstospriteaction?【发布时间】:2013-09-2611:23:03【问题描述】:我在Cocos2D描述的here中使用了很多CCEase*功能。iOS7SpriteKit也有SKActionTimingMode。但是只有简单... 查看详情

canvas缓动3

这次缓动的是旋转旋转,写完之后才知道原来rotate是绕原点旋转,而且还带着rect本身的X与Y一起,所以我采用了translate达到位移效果,以免旋转到画布外面去,画完之后效果惨不忍睹,原来是忘记还原变形了,最后加上了save和re... 查看详情

js动画公式

//效果://Linear:无缓动效果//Quadratic:二次方的缓动(t^2)//Cubic:三次方的缓动(t^3)//Quartic:四次方的缓动(t^4)//Quintic:五次方的缓动(t^5)//Sinusoidal:正弦曲线的缓动(sin(t))//Exponential:指数曲线的缓动(2^t)//Circular:... 查看详情

用缓动函数模拟物理动画

用缓动函数模拟物理动画 1、缓动函数简介   <1>缓动函数的动画效果是建立在CALayer层级的关键帧动画基础之上     也就是说用普通的UIView的Animation是无法直接实现缓动函数   <2&g... 查看详情

threejs基础代码段tweenjs补间动画(代码片段)

...、Tweenjs是什么?    tween.js是一款可生成平滑动画效果的js动画库,只需要告诉tween你想修改什么值,以及动画结束时它的最终值是什么,动画花费多少时间等信息,tween引擎就可以计算从开始动画点到结束动画点... 查看详情

js实现缓动效果-让div运动起来

vartween={linear:function(t,b,c,d){returnc*t/d+b;},easeIn:function(t,b,c,d){returnc*(t/=d)*t+b;},strongEaseIn:function(t,b,c,d){returnc*(t/=d)*t*t*t*t+b;},strongEaseOut:function(t,b,c,d){returnc*((t=t 查看详情

quick-cocos2dx之transition.execute()的缓动效果

...cs/en-us/misc/transitions.html。侵权请告知,即刻删除)什么是缓动,缓动(easing)是指动画效果在运行时被指定速度,使视感更加真实。比較经典的,缓慢開始。然后加速称为“缓入”(easein),高速開始。然后减速称为“缓出”(easeout... 查看详情