系列文章导航
JavaScript动画1-速度动画
JavaScript动画2-缓冲运动
JavaScript动画3-多物体运动
JavaScript动画4-任意属性值
JavaScript动画5-链式运动
JavaScript动画6-同时运动
所有源代码
同时运动
如果我们想要同时改变元素的宽度和高度,前面的代码就不能实现了。
change(div, "width", 400);
change(div, "height", 400);
结果是,div只改变了height,并没有改变width,因为change函数一进去就clearInterval(obj.timer),把div的定时器清除了。
我们需要想其他办法。这里用到了json。
这里我们设计成这样的形式:
animate(div, {width: 200, height: 200, opacity: 100},function(){
alert("Finished!");
});
我们把上一节课的change函数改名为animate,更为贴切。把需要改变的属性通过一个json的形式传进animate函数,然后在函数内依次遍历json中的属性,就可以实现同时改变多个属性了。
当然,不可能真正做到同时改变多个属性,但在极短的时间内,依次改变多个属性,每个属性只改变一点点,这样就能在宏观上造成多个属性同时改变的错觉。
我们来看一下最终完成的animate函数:
function animate(obj, attrs, fn) {
if (obj.timer) {
clearInterval(obj.timer);
}
obj.timer = setInterval(function () {
var allCompleted = true;
for (var attr in attrs) {
//取得当前值
var currentValue = 0;
if (attr == 'opacity') {
currentValue = Math.round((parseFloat(getStyle(obj, attr)) * 100));
} else {
currentValue = parseInt(getStyle(obj, attr));
}
//计算速度
var speed = (attrs[attr] - currentValue) / 10; //缓冲运动
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
//检测停止
if (currentValue != attrs[attr]) {
allCompleted = false;
}
if (attr == 'opacity') {
obj.style.opacity = (currentValue + speed) / 100;
} else {
obj.style[attr] = currentValue + speed + 'px';
}
}
if (allCompleted) { //只有当所有的属性都完成,才清除定时器
clearInterval(obj.timer);
if (fn) {
fn();
}
}
}, 30);
}
大部分代码都是相同的,最不同的地方是我们在定时器内加入了一个循环,依次遍历json中的属性,这样才能做到多个属性同时改变。
值得注意的是,我们设置了一个allCompleted的布尔值,只有当所有属性值都完成的时候,才清除定时器,这样才不会造成“只有一个属性完成,其他属性才完成一半,定时器就被清除了”的情况出现。
调用也非常简单:
var div8 = document.getElementById("div8");
div8.onmouseover = function () {
var _this = this;
animate(_this, {width: 400, height: 400, opacity: 50}, function () {
alert("hello");
});
};
div8.onmouseout = function () {
var _this = this;
animate(_this, {width: 200, height: 200, opacity: 100});
};
完成的效果图: