哈哈,我也有自己的动画类了,各种缓动哦
最近的项目上很可能会用上动画,于是小小地研究了下,主要是参考了cloudgamer 大师的Tween算法及缓动效果一文,然后再简单地进行了一下封装:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/**
* obj: DOM id 或 DOM 对象
* prop: 样式属性,如left、width、opacity
* v1: 初始值
* v2: 最终值
* obj: { duration: 动画时长(毫秒), tweenType: 缓动类型, callBack: 回调 }
* 用法:var t = new Tween('obj', 'left', 0, 800); t.run();
*/
var Tween = (function() {
/**
* t: current time 当前时间
* b: begin value 初始值
* c: changing value 变化量
* d: duration 持续时间
* 都是曲线函数的一些参数,画个图就好理解了
* t是x轴的单位、b是y轴的初始值、b+c是y轴的最终值、d是x轴的最终值,计算出来的结果就是y轴各时刻的值
*/
var _tween = {
Linear: {
easeIn: function(t,b,c,d) {
return c*t/d + b;
},
easeOut: 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;
}
},
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;
}
},
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;
}
},
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;
}
},
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;
}
},
Back: {
easeIn: function(t,b,c,d,s){
if (s == undefined) s = 1.70158;
return c*(t/=d)*t*((s+1)*t - s) + b;
},
easeOut: function(t,b,c,d,s){
if (s == undefined) s = 1.70158;
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
}
}
};
var _interval = 10;
var _Tween = function(obj, prop, v1, v2, opt) {
this.obj = typeof(obj) === 'string' ? document.getElementById(obj) : obj;
this.prop = prop;
this.v1 = v1;
this.v2 = v2;
opt = opt || {};
this.duration = (opt.duration || 1000) / _interval; //默认1秒
this.tweenType = opt.tweenType || 'Quart';
this.currentTime = 0;
this.callBack = opt.callBack || function(){};
};
_Tween.prototype = {
_checkParam : function() {
return this.obj && this.prop && _tween[this.tweenType] &&
(typeof this.v1 !== 'undefined') && (typeof this.v2 !== 'undefined');
},
easeIn : function() {
this._calculate('easeIn');
},
easeOut : function() {
this._calculate('easeOut');
},
_calculate : function(type) {
var t = this;
if (!this._checkParam()) {
return;
}
var result = _tween[this.tweenType][type](this.currentTime, this.v1, this.v2 - this.v1, this.duration);
if (this.prop == 'opacity') {
this.obj.style.opacity = result.toFixed(2);
this.obj.style.filter = 'alpha(opacity=' + Math.ceil(result * 100) + ')';
} else {
this.obj.style[this.prop] = Math.ceil(result) + 'px';
}
if (this.currentTime++ < this.duration) {
this.timeoutId = setTimeout(function(){ t._calculate(type) }, _interval);
} else {
this.currentTime = 0;
this.callBack();
}
},
cancel : function() {
clearTimeout(this.timeoutId);
}
};
_Tween.prototype.run = _Tween.prototype.easeIn;
return _Tween;
})();
传说中的缓动其实和普通的DOM 操作一样,只是其中运用了一些数学公式,啊啊啊,终于知道数学的重要性了 Orz !
使用方法比较简单,如果要让页面上一个id 为objj 的元素向右移动,则:
var t = new Tween('objj', 'left', 0, 650);
t.run();
普通的动画操作是够了,不过还有很多待改进的地方:队列操作、取消动画的开关、初始状态值的优化 等等,有时间再整下咯。