/**
* Created by Administrator on 2016/7/27.
*/
//JS动画框架
//实现变速运动、多物体运动、链式运动、同时运动
//目前只是改变了宽度高度和透明度 位置(本例使用top)
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,false)[attr];
}
}
function startMove(obj,json,fn){//json为一个json对象,为了实现同时运动 fn为一个函数为了实现链式运动
var attrs={width:0,height:0,opacity:0,top:0}; //同时运动时,为防止一个运动先到达目标值 而把定时器给关掉 造成所以运动都停止的情况,多加一个判断
// 当一个运动先到达目标值时,其未停止只是每次运动都为0
// 先列举出所有可能的属性值 初始化为0 达到目标值变为1 当attrs对象的所有值加起来等于json的长度时 说明同时运动结束 就可以关掉定时器了
var num=0;//获取json对象中键值对的个数
for(var attr in json) {
num++;
}
clearInterval(obj.timer); //为保证多物体互补干扰 timer和icur设置为 局部变量
obj.timer=setInterval(function(){
for(var attr in json) { //实现同时运动 本质是每次先前面的运动再后面后面的运动 并不是真正的同时
var icur = 0;//当前值
var iTarget = json[attr];//目标值
//透明度
if (attr == "opacity") {
icur = Math.round(parseFloat(getStyle(obj, attr)) * 100);
}
//宽高
else {
icur = parseInt(getStyle(obj, attr)); //因为offsetwidth获得的整个标签的宽度(自身+边框等等),这样就带来一些不准确的结果,比如变窄的动画
//左右边框宽度一共10px,当快达到目标时,offsetWidth=当前-speed+10px(边框),这样宽度非但没有小,而且更大了 这样就死循环了
// 为了只是获得自身的宽高度 用style的width/height
}
var speed = (iTarget - icur) / 8; //做变速运动
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);//大于0向上取整 小于0向下取整 保证速度最小值为 1、-1 越接近目标 速度越慢 最慢为1 则肯定能使下面
//的判断语句的==号 成立
//停止条件
if (icur == iTarget) {
attrs[attr]=1;
if(attrs['width']+attrs['height']+attrs['opacity']+attrs['top']==num){
clearInterval(obj.timer);
if(fn){
fn();
}
}
} else {
if (attr == 'opacity') {//兼容问题 二者都是设置透明度 不过opacity的范围为0-1 所以/100
obj.style.filter = 'alpha:(opacity:' + icur + speed + ')'; //IE
obj.style.opacity = (icur + speed) / 100;//支持opacity的浏览器 FF Chrome等
} else {//宽高 位置
obj.style[attr] = icur + speed + 'px';
}
}
} },30);
}
/*链式运动调用
Li.onmouseover=function(){
startMove(Li,{width:400},function(){//先宽
startMove(Li,{height:200},function(){//后高
startMove(Li,{opacity:100});//再透明度
});}); }
同时运动
startMove(Li,{width:201,height:200,opacity:100});
*/
JS实现运动的动画效果 框架
最新推荐文章于 2025-06-04 18:19:51 发布