运动:
a). 连续不断的走
for
定时器:setInterval();
b). 改变某一个属性(left)
让Div走一个
定时器的时间给30ms ?
a). 人的眼睛最容易接受
b). 时间给小一点,程序的性能开销大
定时器的问题 ?
a). 不能设置太小的值
0 -> 其实不是0
b). 时间越小越不稳定
c). 多标签打开浏览器,定时器在背景的标签里面执行变慢了
运动:
多长时间 -> 已知
总时间:1000
起点,终点 -> 已知
总距离:终点-起点
多长时间走一次 30ms
总次数:总时间/30
1000/30
把一个数变成整数 ?
a). parseInt();
b). Math.floor(); √ 用floor性能最优
c). Math.ceil();
d). Math.round();
一次能走多少 ?
总距离/总次数
现在走到哪里了 ?:n*总距离/总次数
链式运动:
判断第一次运动完成 ?
回调函数
move(oDiv,'width',400,1000,complete);
运动形式:
匀速运动:'linear'
var a = n/count;
var cur = start[name] + dis[name] * a;
加速运动:'ease-in'
var a = n/count;
var cur = start[name] + dis[name] * a*a*a;
减速(缓冲)运动:'ease-out'
var a = 1 - n/count;
var cur = start[name]+dis[name]*(1-a*a*a);
运动框架(封装的函数):
a). 通用性
b). 方便
最后封装的运动框架:move(oDiv,json,options);
options:可选json{}
duration
easing
complete
代码
// ojb : 物体 ,json :要改变的属性, duration 总时间 ,easing 运动形式 ,complete: 链式运动回调函数
function getStyle(obj,name) {
return (obj.currentStyle || getComputedStyle(obj,false))[name];
}
function move(obj,json,options) {
options = options || {}
options.duration = options.duration || 500;
options.easing = options.easing || 'ease-out';
clearInterval(obj.timer); // 定时器先关后开
//总次数
var count = Math.floor(options.duration/30);
var start = {}; // 起点
var dis = {}; // 总距离
// 循环获取起点位置 ,然后计算出总距离
for (var name in json) {
start[name] = parseFloat(getStyle(obj,name));
// 总距离 = 终点 - 起点
dis[name] = json[name] -start[name];
};
var n =0; //当前已经走了多少次了
obj.timer = setInterval(function () {
n++;
//循环让所有的属性改变
for (var name in json) {
// 根据运动形式 计算每次走的距离
switch(options.easing){
case 'linear': //匀速
var a = n/count;
var cur = start[name] + dis[name]*a;
break;
case 'ease-in': // 加速
var a = n/count;
var cur =start[name] + dis[name] *a*a*a;
break;
case 'ease-out': // 缓冲
var a = 1- n/count;
var cur = start[name] + dis[name]*(1-a*a*a);
break;
}
//设置样式
if ( name = 'opacity') {
obj.style.opacity = cur;
obj,style.filter = 'alpha(opacity:'+cur*100+')';
} else {
obj.style[name] = cur + 'px';
}
}
//判断当前走的次数跟总是是否相等,相等表示已经走完了
if (n == count) {
clearInterval(obj.timer);
//回调链式运动函数
options.complete && options.complete();
}
},30);
}