JS动画框架二

动画原理

前面的动画框架一已经满足我们能够将一个物体水平移动了。但是根据思路,是可以让很多属性“动起来”的。
如果我们 让一个物体自身宽高可以变化,还可以水平,垂直移动。 又应该怎么实现呢?



根据前面的框架思路,还是很简单的。

前面的框架代码:

//animation:让指定的dom元素缓动到指定位置
function animation(obj,target){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
    var speed = (target - obj.offsetLeft)/10;
    speed = speed>0?Math.ceil(speed):Math.floor(speed);
    obj.style.left = obj.offsetLeft + speed +"px";
    if(obj.offsetLeft==target){
        clearInterval(obj.timer);
    }

},30)
}

实现思路:

将要操作的属性用JSON存起来,遍历操作,加上回调函数就可以实现了。
首先要实现获取对象属性,先写一个获取属性的函数:

//获取任意属性
function getStyle(obj,attr){
    if(window.getComputedStyle){
        return window.getComputedStyle(obj,null)[attr]
    }else{
        return obj.currentStyle[attr];
    }
}

实现代码如下:

function animation(obj,json,fn){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var flag = true;
        //json里面有几个属性就要执行几次
        for(var key in json){
            var target = parseInt(json[key]);
            var speed = (target - parseInt(getStyle(obj,key)))/10;
            speed = speed>0?Math.ceil(speed):Math.floor(speed);
            obj.style[key] = parseInt(getStyle(obj,key)) +speed+"px";
            if(parseInt(getStyle(obj,key))!=target){
                flag = false;
            }
        }
        if(flag){
            clearInterval(obj.timer);
            if(fn){
                fn();
            }
        }
    },20)
            }

例如:让一个div动起来JSON中的属性同时到达,回调函数执行弹出‘1’:

var div = document.getElementsByTagName('div')[0];
var attrJson = {
    "width": "800px",
    "height": "50px",
    "top":"300px",
    "left":"400px",
};
animation(div,attrJson,function(){
                alert(1)
            });

若要分别运动,则每次调用函数,实现一个属性即刻,然后回调函数执行下一个。
现在宽高上下左右都可以‘动’起来了。还差个棘手的透明度,实现如下
思路大同小异,只不过要处理兼容:

function animation(obj,json){//opacity传0-1之间的数字
    obj.timer = setInterval(function(){
        var target = Math.round(json['opacity']*100)//0-100
        var leader = getStyle(obj,'opacity')*100//0-100
        var speed = (target-leader)/10;
        speed = speed>0?Math.ceil(speed):Math.floor(speed);
        leader = leader + speed;//0-100
        obj.style.opacity = leader/100;
        obj.style.filter = "alpha(opacity="+leader+")";
        if(leader==target){
            clearInterval(obj.timer);
        }
    },30)
}

整合框架:

最后
一个可以宽高上下左右透明度都控制的简单框架如下:

/**
 * 缓动框架
 * @param obj       需要移动的标签
 * @param target    移动的参数JSON格式
 * @param callback  接收调用者传递的回调函数
 */
function animation(obj, target, callback){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
        var isClearInterval = true;     // 记录是否需要清除定时
        for (var key in target){
            var t = target[key]; // 目标位置
            var c = getStyle(obj, key);  // 当前位置
            // 判断key有没有是opacity
            if (key === 'opacity'){
                c = Math.round(c * 100);
                // 如果传值取整是0,表示参数是小数需要*100,否则取数字本身
                t = parseInt(t) == 0 || parseInt(t) == 1 ? t * 100 : t;
            }else{
                c = parseInt(c);    // 去除返回的单位
            }
            // (目标 - 当前) / 10
            var s = (t - c) / 10;   // 每次移动的距离
            s = s > 0 ? Math.ceil(s) : Math.floor(s);
            if (key === 'opacity'){
                obj.style[key] = (c + s) / 100;
                obj.style.filter = '(alpha='+(c+s)+')';
            }else {
                obj.style[key] = c + s + 'px';
            }
            if (c + s != t){ // 判断是否移动到目录位置
                isClearInterval = false;
            }
        }
        if (isClearInterval){   // 只有所有的目标都到达预定位置才能清除定时器
            clearInterval(obj.timer);
            /*
            当动画执行完成以后,再判断是否有需要执行callback
            判断用户是否有传递回调函数,如果有执行回调函数
             */
            if (callback){
                callback(); // 执行回调函数
            }
        }
    }, 10);
}

/**
 * 获取标签的样式
 * @param obj       获取样式的对象
 * @param property  获取的属性名称
 */
function getStyle(obj, property){
    if (window.getComputedStyle){
        return window.getComputedStyle(obj, null)[property];
    }else{  // IE678
        return obj.currentStyle[property];
    }
}

结:

到这里‘动画框架’就告一段落了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值