tween.js缓动补间动画算法示例
作者:李俊杰 发布时间:2024-05-21 10:13:40
一、理解tween.js
如果看到上面的已经理解了,可以跳过下面的部分.下面为对Tween.js的解释 下面就介绍如何使用这个Tween了,首先b、c、d三个参数(即初始值,变化量,持续时间)在缓动开始前,是需要先确定好的。 首先引入一个概念就补间动画 Flash做动画时会用到Tween类,利用它可以做很多动画效果,例如缓动、弹簧等等。 tween.js在Flash中可以解释为补间动画. 那么问题来了,什么是补间动画呢?
相信学过Flash的都知道补间动画是flash主要的非常重要的表现手段之一.补间动画有动作补间动画与形状补间动画两种,但是在js中却不需要了解这么多. 好了,废话不多说,先看看百度百科关于补间动画给出的定义: 补间动画:做flas * 时,在两个关键帧中间需要做“补间动画”,才能实现图画的运动; 插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的
那么什么是关键帧呢? 举个栗子: 先科普一下,平常所看的电影,动画都是24帧的,24帧为一秒.在人眼可以捕捉的范围内.可以想象两个点之间有有22个点,形成一条直线或者曲线.而每一个点就代表一帧,帧——就是动画中最小单位的单幅影像画面,而单幅影像画面就可以看做是一个对象(一切皆对象,除去值类型)了.而这条线就代表对象的运动轨迹.
二、四个参数
t: current time-->代表第一个点,也就是第一帧,也就是一个动画开始的地方。
b: beginning value-->代表初始值,也就是开始量,我们看电影或者动画一般都不会看序幕把,那么跳过开头部分,选择第一帧和最后一帧之间你要开始看位置,而此位置就是初始值。
c: change in value-->代表的就是最后一帧减去初始值就是变化量,
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实现效果是依据算法,不是某种语言的语法,因此可以运用的地方很广泛,一次学习终身受益。
来源:https://segmentfault.com/a/1190000013272336


猜你喜欢
- 1、方法一在使用多线程更新 MongoDB 数据时,需要注意以下几个方面:确认您的数据库驱动程序是否支持多线程。在 PyMongo 中,默认
- 什么是pyecharts?pyecharts 是一个用于生成 Echarts 图表的类库。echarts是百度开源的一个数据可视化 JS 库
- 使用Requests测试带签名的接口部分业务为了安全需要,需要对接口请求数据做签名校验,一般制定一下规则1、业务方接入系统,需申请业务ID以
- 测试环境:先让我们熟悉下基本的sql语句,来查看下我们将要测试表的基本信息use infomation_schemaSELECT * FRO
- 本文实例讲述了Python面向对象封装操作。分享给大家供大家参考,具体如下:目标士兵突击案例身份运算符封装封装 是面向对象编程的一大特点面向
- 本文实例讲述了python实现给微信公众号发送消息的方法。分享给大家供大家参考,具体如下:现在通过发微信公众号信息来做消息通知和告警已经很普
- 最近,我有机会在一个真实的 Golang 场景中使用泛型,同时寻找与 Stream filter(Predicate<? super
- MySQL数据库管理软件有两种版本,一种是企业版,一种是社区版,其中,前者是收费的,如果是个人使用的,社区版足矣。下载mysql-5.7.1
- 前言:要翻转图像,我们需要使用pygame.transform.flip(Surface, xbool, ybool) 方法,该方法被调用来
- 前言python 中 if 的用法(if else, if not, elif)if语句实际上是:if True: …
- 正则中有分组这个功能,在golang中也可以使用命名分组。一次匹配的情况场景还原如下:有一行文本,格式为:姓名 年龄 邮箱地址请将其转换为一
- python实现rsa加密实例详解一 代码import rsakey = rsa.newkeys(3000)#生成随机秘钥privateKe
- 一、文章前言此文主要实现识别人体的轮廓范围,与背景进行分离并保存效果图,适用于拍照背景替换及透明背景的人像图(png格式)转换。二、具体流程
- 如何远程读取数据库页面?见下:<%Set HttpObj = Server.CreateObject(&
- 学过Python的人应该都知道,Python是支持多线程的,并且是native的线程。本文主要是通过thread和threading这两个模
- 大数据预测是大数据最核心的应用,是它将传统意义的预测拓展到“现测”。大数据预测的优势体现在,它把一个非常困难的预测问题,转化为一个相对简单的
- 前言在CSDN发的第一篇文章,时隔两年,终于实现了爬微博的自由!本文可以解决微博预登录、识别“展开全文”并爬取完整数据、翻页设置等问题。由于
- 目录一、v-bind关键源码分析1、v-bind化的属性统一存储在哪里:attrsMap与attrsList2、解析HTML,解析出属性集合
- 本文实例讲述了JS实现判断有效的数独算法。分享给大家供大家参考,具体如下:判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入
- 最近的一个页面中碰到的,本来想用 border 来模拟设计图的虚线效果,但是很明显 border 效果不如设计图来的好看。顺便研究了下 da