# learn Tween **Repository Path**: YZH_cd/learn-Tween ## Basic Information - **Project Name**: learn Tween - **Description**: tween js 学习项目 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2018-01-01 - **Last Updated**: 2023-06-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # learn Tween tween js 学习项目 ### 创建Tween实例 创建一个Tween实例非常简单,只需要一个变量对象,指明变化属性即可。 >`var position = { x: 100, y: 0 };` >`var tween = new TWEEN.Tween(position);` ### 控制单个tween __这里的方法均是TWEEN对象静态方法__ #### start 和 stop start函数可以开始一个tween变换,stop函数用于停止变换。stop一个正在变换或者已经变换完毕的tween,没有任何影响。start函数可接受一个参数用于延迟开始。 > `tween.start()` #### update update函数,一般情况下不用马上调用,除非要使用大量hacks > `tween.update(100)` #### chain 当我们需要多个tween链式执行时,需要用到chain函数 > `tweenA.chain(tweenB)` 无限循环链式执行 > `tweenA.chain(tweenB)` > `tweenB.chain(tweenA)` 有时想要在一个tween动画结束后,同时开始多个tween,也可以使用chain函数 > `tweenA.chain(tweenB, tweenC)` > __注意:此时chain返回的是tweenA而不是一个新tween__ #### repeat 想让一个tween动画永远执行下去,可以chain自身 > `tweenA.chain(tweenA)` 更好的做法是使用`repeat`函数,`repeat`接收一个参数,描述在动画第一次执行完成后,还要执行多少次 > `tween.repeat(10); //总共执行了11次` > `tween.repeat(Infinity); //Infinity关键字,表示永久循环` #### yoyo 在动画完成时产生一个类似于悠悠球的弹跳效果。只能在`repeat`时起作用 #### delay 在`start`前,等待指定毫秒数,用于延迟执行 > `tween.delay(1000);` > `tween.start();` > `//在1秒后开始tween` ### 控制所有tween实例 __这里几个方法除了update都不常用,它们均定义在TWEEN全局对象下__ #### update(time) 同上面update函数 #### getAll 和 removeAll 获取当前存在的所有tween实例,得到一个数组;通过一次调用从该数组中删除所有tween; #### add(tween) 和 remove(tween) 添加一个tween实例到当前twenn列表中;从当前tween列表中删除指定tween实例。 ### 控制tween实例组 引入tween group原因:在复杂页面,可能会有很多tween实例,彼此状态应该独立,但控制函数大多是全局TWEEN的方法,直接控制当前tween实例列表所有实例。比如:一个组件调用TWEEN.update()时,另一个组件调用了TWEEN.removeAll(),这自然有问题产生。 通过`TWEEN.Group`构建的group实例解决该问题。 > `var groupA = new TWEEN.Group();` > `var groupB = new TWEEN.Group();` 在实例化Tween对象时,给入一个可选的二参,为指定group对象 > `var tweenA = new Tween({ x: 1 }, groupA).to({ x: 100 }, 1000).start()` > `var tweenB = new Tween({ x: 1 }, groupB).to({ x: 100 }, 1000).start()` 此时通过group对象调用控制函数,只影响group内的tween对象 > `groupA.update(); // 只更新 tweenA` > `groupB.update(); // 只更新 tweenB` > `TWEEN.update(); // 只更新 tweenC` > `groupA.removeAll(); // 只删除 tweenA` > `groupB.removeAll(); // 只删除 tweenB` > `TWEEN.removeAll(); // 只删除 tweenC` ### 应用缓动函数 #### easing(instanceof TWEEN.Easing) 为当前tween实例,使用指定的缓动函数。 > `tween.easing(TWEEN.EasingQuadratic.In); //二次方缓入函数` 缓动函数均定义在TWEEN下Easing类中 #### 自定义缓动函数 因为Tween对缓动函数的封装,自定义缓动函数只要满足以下两点即可: * 接收一个参数k,表示tween的进度,取值范围[0-1] * 有取决于k的值的返回值 > `function tenStepEasing(k) {` >   `return Math.floor(k / 10) * 10; ` > `}` 应用自定义缓动函数 > `tween.easing(tenStepEasing)` ### 事件回调 我们可以在一个tween实例生命周期中特定位置插入执行我们自己定义的函数。这让我们可以利用tween实现除了数值改变之外的效果。 > `var obj = {x: 0};` > `var tween = new TWEEN.Tween(obj)` >     `.to({x: 100})` >    `.start();` #### onStart 在一个tween实例生命周期范围内只执行一次,执行于第一次差值计算之前。有`repeat`函数时也只执行一次。 > `tween.to({x: 100})` >    `.onStart(function(obj){ console.lol(boj.x) })` >    `.repeat(Infinity);` #### onStop 当tween变化明确结束之后执行,有chain函数时,当所有可能的tween变化结束之后执行 #### onUpdate 在每一次属性值变化后执行。可以通过参数形式拿到每一次修改的属性值。 > `tween.onUpdate(function(obj){` >   `console.log(obj)` > ` });` #### onComplete 一个tween实例正常结束时执行 ### tween进阶 #### 相对值 在使用`to`函数时除了给入结果值外,还可以给入带符号的相对值,当tween开始时,Tween.js会根据相对值计算新的结果值。 > `var tween = new TWEEN.Tween(obj);` > `tween.to({x: 100})` 以上代码,假设obj.x为初始值为0,则:   结果值为:100   变化量为:0 ~ 100 假设obj.x初始值为-100,则:   结果值为:100   变化量为:-100 ~ 100 > `tween.to({x: '+100'})` 以上代码,假设obj.x初始值为0,则:   结果值为:0 + 100 = 100   变化量为:0 ~ 100 假设obj.x初始值为-100,则:   结果值为:-100 + 100 = 0   变化量位:-100 ~ 0    #### 数组值 `to`函数不仅可以给入相对值,还可以给入由绝对值组成的数组。 > `tween.to({x: [0, -100, 100]})` 此时在变化时有以下三点特征: * 按正常算法计算进度值 * 计算出的进度值会作为参数注入到“插入函数”中 * “插入函数”会根据进度值和数组值,生成一个插入值 Tween可用的插入函数有三种: * TWEEN.Interpolation.Linear * TWEEN.Interpolation.Bezier * TWEEN.Interpolation.CatmullRom 默认是Linear,通过以下方式引用插入函数 > `tween.interpolation(TWEEN.Interpolation.Bezier);` __注意:“插入函数”是对单个tween来说是全局的,不能实现对同一个tween实例的不同属性值使用不同的“插入函数”。若想,只能用两个twenn实例处理同一个属性对象,并给入不同的“插入函数”__ ### 更高性能 #### 使用高性能css属性 当我们需要一个位移动画时,往往会使用`top`和`left`属性。 > `tween.onUpdate(function(obj){` >   `oDiv.style.left = obj.left + 'px';` >   `oDiv.style.top = obj.top + 'px';` > `})` 这样每一次修改都会触发页面重绘,效能低下。可以使用`transform`属性代替,`transform`属性在条件允许时可以启用硬件加速,性能远高于`top left`属性。 > `tween.onUpdate(function(obj){` >   `oDiv.style.transform = 'translate('+ obj.left + 'px, ' + obj.top + 'px)';` >`})` #### 对垃圾回收机制友好 如果使用`onUpdate`回调,那么要注意,onUpdate会被频繁调用,如果回调函数复杂会有严重的性能问题。所以,要保证回调简单,同时做好内存监控