tween.js缓动补间动画算法示例


Posted in Javascript onFebruary 13, 2018

一、理解tween.js

如果看到上面的已经理解了,可以跳过下面的部分.下面为对Tween.js的解释 下面就介绍如何使用这个Tween了,首先b、c、d三个参数(即初始值,变化量,持续时间)在缓动开始前,是需要先确定好的。 首先引入一个概念就补间动画 Flash做动画时会用到Tween类,利用它可以做很多动画效果,例如缓动、弹簧等等。 tween.js在Flash中可以解释为补间动画. 那么问题来了,什么是补间动画呢?

相信学过Flash的都知道补间动画是flash主要的非常重要的表现手段之一.补间动画有动作补间动画与形状补间动画两种,但是在js中却不需要了解这么多. 好了,废话不多说,先看看百度百科关于补间动画给出的定义: 补间动画:做flash动画时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动; 插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的

那么什么是关键帧呢? 举个栗子: 先科普一下,平常所看的电影,动画都是24帧的,24帧为一秒.在人眼可以捕捉的范围内.可以想象两个点之间有有22个点,形成一条直线或者曲线.而每一个点就代表一帧,帧——就是动画中最小单位的单幅影像画面,而单幅影像画面就可以看做是一个对象(一切皆对象,除去值类型)了.而这条线就代表对象的运动轨迹.

二、四个参数

  1. t: current time-->代表第一个点,也就是第一帧,也就是一个动画开始的地方。
  2. b: beginning value-->代表初始值,也就是开始量,我们看电影或者动画一般都不会看序幕把,那么跳过开头部分,选择第一帧和最后一帧之间你要开始看位置,而此位置就是初始值。
  3. c: change in value-->代表的就是最后一帧减去初始值就是变化量,
  4. d: duration-->代表最后一帧,1s的结束,也是动画的结束。

tween.js的使用 1.下载 2.引入 3.使用tween.js语法

Tween.缓动函数名.缓动效果名(t,b,c,d);

注意:当开始步数增加到与结束步数相等时,整个运动结束. 注注意:只有当t增加到与d相等时才会结束运动;如果不等,运动不会停止.

三、tween文件代码

/*
 * Tween.js
 * t: current time(当前时间);
 * b: beginning value(初始值);
 * c: change in value(变化量);
 * d: duration(持续时间)。
*/
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) { //加速
      var s;
      if (t==0) return b;
      if ((t /= d) == 1) return b + c;
      if (typeof p == "undefined") p = d * .3;
      if (!a || a < Math.abs(c)) {
        s = p / 4;
        a = c;
      } else {
        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) { //减速
      var s;
      if (t==0) return b;
      if ((t /= d) == 1) return b + c;
      if (typeof p == "undefined") p = d * .3;
      if (!a || a < Math.abs(c)) {
        a = c; 
        s = p / 4;
      } else {
        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) { //先加速后减速
      var s;
      if (t==0) return b;
      if ((t /= d / 2) == 2) return b+c;
      if (typeof p == "undefined") p = d * (.3 * 1.5);
      if (!a || a < Math.abs(c)) {
        a = c; 
        s = p / 4;
      } else {
        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 (typeof s == "undefined") s = 1.70158;
      return c * (t /= d) * t * ((s + 1) * t - s) + b;
    },
    easeOut: function(t, b, c, d, s) {
      if (typeof 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 (typeof 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;
      }
    }
  }
}
Math.tween = Tween;

四、举个栗子

<!DOCTYPE html>
<html>

  <head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="Tween/tween.js"></script>
    <style>
      *{margin: 0;padding: 0;}
      .out{width: 800px;height: 500px;background: #e5e5e5;position: relative;padding: 20px;text-align: center;}
      .inner{width: 50px;height: 50px;border-radius: 50%;background: #FF0000; position: absolute;left: 50px;top: 50px;}
    </style>
  </head>

  <body>
    <div id="app" class="out">
      <div class="inner" id="ball"></div>
      <button id="start" @click="start()">start</button>
    </div>
  </body>
  <script type="text/javascript">
    var app = new Vue({
      el: '#app',
      data: {
        t: 0,
        b: 50,
        c: 500,
        d: 1500,
      },
      methods:{
        start(){
          var t = this.t;
          const b = this.b;
          const c = this.c;
          const d = this.d;
          const setInt = setInterval(()=>{
            t++;
            console.log(t)
            if(t==300){clearInterval(setInt)}
            console.log(t);
            const ballLeft = Tween.Linear(t,b,c,d)+"px";
            ball.style.left = ballLeft;
          },20)
        }
      }
    })
  </script>
</html>

五、个人体会

tween的优势在于tween实现效果是依据算法,不是某种语言的语法,因此可以运用的地方很广泛,一次学习终身受益。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript使用技巧精萃[代码非常实用]
Nov 21 Javascript
javascript 简练的几个函数
Aug 29 Javascript
JavaScript 闭包在封装函数时的简单分析
Nov 28 Javascript
增强用户体验友好性之jquery easyui window 窗口关闭时的提示
Jun 22 Javascript
jquery插件hiAlert实现网页对话框美化
May 03 Javascript
详解JavaScript中void语句的使用
Jun 04 Javascript
jQuery3.0中的buildFragment私有函数详解
Aug 16 Javascript
jQuery菜单实例(全选,反选,取消)
Aug 28 jQuery
JavaScript实现打印星型金字塔功能实例分析
Sep 27 Javascript
使用Nuxt.js改造已有项目的方法
Aug 07 Javascript
解决layer弹出层自适应页面大小的问题
Sep 16 Javascript
ES6如何用一句代码实现函数的柯里化
Jan 18 Javascript
基于Node.js实现压缩和解压缩的方法
Feb 13 #Javascript
Vue打包后出现一些map文件的解决方法
Feb 13 #Javascript
nginx部署访问vue-cli搭建的项目的方法
Feb 12 #Javascript
vue2.0实现前端星星评分功能组件实例代码
Feb 12 #Javascript
nginx+vue.js实现前后端分离的示例代码
Feb 12 #Javascript
Vue+webpack项目基础配置教程
Feb 12 #Javascript
详解vue-admin和后端(flask)分离结合的例子
Feb 12 #Javascript
You might like
PHP 多进程 解决难题
2009/06/22 PHP
为PHP5.4开启Zend OPCode缓存
2014/12/26 PHP
PHP实现的XML操作类【XML Library】
2016/12/29 PHP
浅谈PHP发送HTTP请求的几种方式
2017/07/25 PHP
laravel 框架配置404等异常页面
2019/01/07 PHP
PHP中单例模式的使用场景与使用方法讲解
2019/03/18 PHP
PHP中number_format()函数的用法讲解
2019/04/08 PHP
使用composer 安装 laravel框架的方法图文详解
2019/08/02 PHP
javascript indexOf函数使用说明
2008/07/03 Javascript
javascript整除实现代码
2010/11/23 Javascript
js控制的回到页面顶端goTop的代码实现
2013/03/20 Javascript
JavaScript 创建运动框架的实现代码
2013/05/08 Javascript
JS制作图形验证码实现代码
2020/10/19 Javascript
微信小程序 教程之注册程序
2016/10/17 Javascript
jquery表单插件form使用方法详解
2017/01/20 Javascript
jquery将标签元素的高设为屏幕的百分比
2017/04/19 jQuery
bootstrap是什么_动力节点Java学院整理
2017/07/14 Javascript
Vue利用路由钩子token过期后跳转到登录页的实例
2017/10/26 Javascript
全面了解JavaScript的作用域链
2019/04/03 Javascript
Vue匿名插槽与作用域插槽的合并和覆盖行为
2019/04/22 Javascript
vue自定义js图片碎片轮播图切换效果的实现代码
2019/04/28 Javascript
Android 自定义view仿微信相机单击拍照长按录视频按钮
2019/07/19 Javascript
JavaScript实现4位随机验证码的生成
2021/01/28 Javascript
12步入门Python中的decorator装饰器使用方法
2016/06/20 Python
Python两个字典键同值相加的几种方法
2019/03/05 Python
pyqt 实现为长内容添加滑轮 scrollArea
2019/06/19 Python
Selenium自动化测试工具使用方法汇总
2020/06/12 Python
python+django+selenium搭建简易自动化测试
2020/08/19 Python
python装饰器实现对异常代码出现进行自动监控的实现方法
2020/09/15 Python
Python创建文件夹与文件的快捷方法
2020/12/08 Python
Bose美国官网:购买Bose耳机和音箱
2019/03/10 全球购物
英国电子专家:maplin
2019/09/04 全球购物
大客户销售经理职责
2013/12/04 职场文书
活动总结报告格式
2014/05/09 职场文书
学习党的群众路线剖析材料
2014/10/09 职场文书
JavaScript架构搭建前端监控如何采集异常数据
2022/06/25 Javascript