前面我们已经介绍了速度动画、透明度动画、多物体运动和任意值变化,并且我们在效果(二)中介绍到我们封装了一个简单的插件雏形,接下来我们对前面的动画效果进行进一步扩充,尽量将我们的框架做到更实用。在这里我们还需要了解两个运动,一个是链式运动,一个是同时运动。它们间的区别分别是:链式运动是指运动一个接着一个(一个运动完成马上进行下一个运动);而同时运动是指所有的运动同时进行。在这里,我们该如何实现呢?
1、链式运动
前面的效果中,我们已经能对任意值进行相应的变化,我们该如何在一个动画后添加一个动画呢?
思路:我们能不能在参数中传入一个函数,当一个效果完成后马上执行后面的函数(效果),该函数可以是想要的动画效果
实现:在function startMove(obj,attr,iTarget)中在传入一个参数fn,代表一个函数。这时我们还需要修改的有在定时器的后面增加一个判断if(fn){fn(); },当存在fn函数时执行fn函数,当不存在fn函数时清除定时器。这样我们的window.onload函数也应该发生相应变化,代码如下:
所以我们得到链式运动的如下代码:
<script type="text/javascript">
window.onload = function(){
var Li = document.getElementById('li1');
Li.onmouseover = function(){
startMove(Li,{width:202,height:200,opacity:100});
};
Li.onmouseout = function(){
startMove(Li,{width:200,height:100,opacity:30});
};
};
function getStyle(obj,attr) {
if(obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj,false)[attr];
}
}
function startMove(obj,json,fn) {
//定义标杆
var flag = true; //假设的
clearInterval(obj.timer);
obj.timer = setInterval(function() {
for(var attr in json) {
var icur = 0;
if(attr == 'opacity') {
icur = Math.round(parseFloat(getStyle(obj,attr)) * 100);
} else {
icur = parseInt(getStyle(obj,attr));
}
var speed = (json[attr] - icur) / 10;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if(json[attr] != icur) {
flag = false;
}
if(attr == 'opacity') {//判断是否为opacity
obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')';
obj.style.opacity = (icur + speed) / 100;
} else {
obj.style[attr] = icur + speed + 'px';
}
if(flag){
clearInterval(obj.timer);
if(fn){
fn();
}
}
}
},30)
}
</script>
这样我们的同时运动的动画效果就实现了。在这里,你有没有觉得很神奇?
在这里我们已经将一个简单的运动插件封装完成了,我们将里面的代码做一些解释,并且将它保存为一个foodoir.animate.js文件,代码如下:
if(obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj,false)[attr];
}
}
function startMove(obj,fn) {
clearInterval(obj.timer); //清除定时器,避免重复生成多个定时器
obj.timer = setInterval(function() {
var flag = true; //假设刚开始时所有运动都已完成
for(var attr in json) { //遍历json
var icur = null;
//1.判断类型
if(attr == 'opacity') {
icur = Math.round(parseFloat(getStyle(obj,attr)) * 100);
} else {
icur = parseInt(getStyle(obj,attr));
}
//2.算速度
var speed = (json[attr] - icur) / 5;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
//3.检测停止
if(icur != json[attr]) {
flag = false;
}
if(attr == 'opacity') {
obj.style.filter = 'alpha(opacity:' + (icur + speed) + ')';
obj.style.opacity = (icur + speed) / 100;
} else {
obj.style[attr] = icur + speed + 'px';
}
}
if(flag) { //当所有运动都完成时,清除定时器
clearInterval(obj.timer);
if(fn) {
fn();
}
}
},30);
}