blogs
blogs copied to clipboard
Tween.js 的使用
Tween.js 只有 5.6k,拿来做动画是一个不错的选择。 是 CreateJS(神器)旗下的一个子项目,受众庞大,值得一学。
<script src="https://cdn.bootcss.com/tween.js/r14/Tween.min.js"></script>
以下代码请注意 TWEEN
/ Tween
/ tween
三者的区别
基础
写个小 demo 先来感受一下 Tween.js 的魅力: 就是以下这样简单的 4 步完成值的匀速变化。
// 指定动画对象
var pos = {x: 0, y: 0};
var tween = new TWEEN.Tween(pos);
// 指定动画目标 和 运行时间
tween.to({x: 200}, 1000);
// 启动 tween
tween.start();
// 动画不断更新
animate();
function animate() {
TWEEN.update();
requestAnimationFrame(animate);
}
// 监听动画变动
tween.onUpdate(function(){
console.log(this.x)
});
动画流程
update
即更新一次,如果传入某毫秒值作为参数,则一直更新该时间对应的动画值,试一次就懂了。
stop
即可暂停动画,再次 start
则从暂停处继续动画。
start
传入某毫秒值作为参数的话,代表动画将从该时间开始。
动画队列
TWEEN.getAll()
获取动画队列,数组类型,动画完成就会清出队列。
TWEEN.removeALL()
清空队列。
TWEEN.add(B)
添加一个队列,与 chain
不同在于 add
是同时运行的。
TWEEN.remove(B)
把 B 从队列中清除。
动画队列拼接
A.chain(B)
可以连接多个动画,B 将在 A 结束之后运行。
- B 的定义最好写在 A.start() 之前
- 如果同时写 B.start(),会既立刻运行,也在 A 结束时运行。
- B 的回调是独立的,所以除了 A.onUpdate,B.onUpdate 也要写
- B 与 A 操作同一个对象是没问题的
动画循环
repeat
循环动画,且 chain 还是跟在 repeat 最终结束之后。
yoyo
需与 repeat 合用,且需传入非 0 参数,偶数次动画会反向运行。
tween.repeat(1); // 将运行总共 2 次
tween.repeat(Infinity); // 无限循环
tween.yoyo(1); // 一次正序一次倒序的运行
动画延迟
delay
延迟运行。概念比较好理解,但眉头一皱,发现此事并不简单。
- 放在 start 前面还是后面,效果是不同的
- repeat 时,是延迟后再运行的,即每次重复都有延时
动画缓冲
TWEEN.Easing 下有 Linear, Quadratic, Cubic, Quartic, Quintic, Sinusoidal, Exponential, Circular, Elastic, Back, Bounce 这 11 种类型的缓动类型。
除 Linear 只有 None 外,其他都含有 In, Out, InOut 3 种缓动效果。所以共计 31 种。
easing
方法传入以上参数,即可实现各种节奏效果。
tween.easing(TWEEN.Easing.Linear.None);
tween.easing(TWEEN.Easing.Bounce.InOut);
自定义缓动函数则传入一个方法,返回该时间帧应该改用的时间帧即可
tween.easing(function(k){
console.log(k); // k 为时间进度,范围 [0, 1)
return Math.floor(k * 10) / 10;
});
具体的效果区别,可参见此 DEMO,右键在新标签打开连接
动画回调
- tween.onStart
- tween.onStop
- tween.onUpdate
- tween.onComplete
自己写的动画工具
曾经为了简化写动画的过程,也搞过一个这样的动画类工具,发出来缅怀一下。
!(function(){
// 判断类型
window.Type = function(obj) {
var typeStr = Object.prototype.toString.call(obj).split(" ")[1];
return typeStr.substr(0, typeStr.length - 1).toLowerCase();
}
// 区间内持续时间的变化
window.smooth = function(fn, duration, option, finish) {
var type, per, now = Date.now(), Timer, count = 0;
var _optionType = Type(option);
if (_optionType === 'boolean') { // 循环模式
type = 'infinite';
duration = duration || 25;
} else if (_optionType === 'number') { // 限定次数
type = 'remain';
duration = duration || 25;
var remain = option;
} else { // 运行一次,但 duration 期间按设备性能持续运行 fn
type = 'animate';
duration = duration || 1000;
if (option) finish = option;
}
_run();
function _run() {
per = Math.min(1, (Date.now() - now) / duration);
if (per < 1) {
if (type === 'animate') fn(per, ++count);
Timer = requestAnimationFrame(_run);
} else {
if (type === 'animate' && finish) finish();
if (type === 'infinite' || count < remain) {
now = Date.now();
fn(++count);
if (count === remain && finish) finish()
Timer = requestAnimationFrame(_run);
} else {
cancelAnimationFrame(Timer);
}
}
}
return {
stop: function() {
cancelAnimationFrame(Timer);
}
}
}
})()
个人觉得写的还是不错的,我也在经常使用, 只比 Tween.js 少了两个回调和 easing 而已。
之后如何使用,就看你的项目需求咯,加油大宝贝。