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 相关文章推荐
解决 FireFox 下[使用event很麻烦] 的问题.
Aug 22 Javascript
javascript中typeof操作符和constucor属性检测
Feb 26 Javascript
轻松学习jQuery插件EasyUI EasyUI创建CRUD应用
Nov 30 Javascript
JavaScript如何实现对数字保留两位小数一位自动补零
Dec 18 Javascript
使用Angular缓存父页面数据的方法
Jan 03 Javascript
echarts3 使用总结(绘制各种图表,地图)
Jan 05 Javascript
详解jQuery事件
Jan 13 Javascript
详解javascript中对数据格式化的思考
Jan 23 Javascript
详解多页应用 Webpack4 配置优化与踩坑记录
Oct 16 Javascript
详解Vue.js 作用域、slot用法(单个slot、具名slot)
Oct 15 Javascript
如何解决vue在ios微信&quot;复制链接&quot;功能问题
Mar 26 Javascript
vue.js封装switch开关组件的操作
Oct 26 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 filter_var() 函数 Filter 函数
2012/04/25 PHP
PHP 5.3和PHP 5.4出现FastCGI Error解决方法
2015/02/12 PHP
PHP微信红包生成代码分享
2016/10/06 PHP
Laravel如何友好的修改.env配置文件详解
2017/06/07 PHP
Dojo 学习笔记入门篇 First Dojo Example
2009/11/15 Javascript
理解Javascript_08_函数对象
2010/10/15 Javascript
Javascript继承(上)——对象构建介绍
2012/11/08 Javascript
Node.js中的process.nextTick使用实例
2015/06/25 Javascript
基于jquery步骤进度条源码分享
2015/11/12 Javascript
Bootstrap CDN和本地化环境搭建
2016/10/26 Javascript
无法获取隐藏元素宽度和高度的解决方案
2017/03/07 Javascript
基于JS代码实现简单易用的倒计时 x 天 x 时 x 分 x 秒效果
2017/07/13 Javascript
微信小程序tabBar模板用法实例分析【附demo源码下载】
2017/11/28 Javascript
vue mint-ui tabbar变组件使用
2018/05/04 Javascript
JavaScript实现动态留言板
2020/03/16 Javascript
在Python中使用判断语句和循环的教程
2015/04/25 Python
各种Python库安装包下载地址与安装过程详细介绍(Windows版)
2016/11/02 Python
Python字符串拼接六种方法介绍
2017/12/18 Python
Django框架设置cookies与获取cookies操作详解
2019/05/27 Python
ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码
2020/10/21 Python
德国BA保镖药房韩文网:kr.ba.de
2017/09/04 全球购物
洛杉矶生活休闲而精致的基础品牌:Mika Jaymes
2018/01/07 全球购物
优衣库美国官网:UNIQLO美国
2018/04/14 全球购物
巴西网上药店:Drogaria Araujo
2021/01/06 全球购物
Linux管理员面试经常问道的相关命令
2013/04/29 面试题
环境科学专业个人求职信
2013/09/26 职场文书
公司委托书格式范文
2014/04/04 职场文书
倡议书格式范文
2014/04/14 职场文书
《他得的红圈圈最多》教学反思
2014/04/24 职场文书
单位作风建设自查报告
2014/10/23 职场文书
2014年政府采购工作总结
2014/12/09 职场文书
2015高三毕业寄语赠言
2015/02/27 职场文书
军事理论课感想
2015/08/11 职场文书
2016春季幼儿园小班开学寄语
2015/12/03 职场文书
详解MySQL InnoDB存储引擎的内存管理
2021/04/08 MySQL
Python&Matlab实现樱花的绘制
2022/04/07 Python