基于OO的动画片附加插件,可以实现弹跳、渐隐等动画效果 -[修正版]

基于OO的动画附加插件,可以实现弹跳、渐隐等动画效果 ----[修正版]

最近手上的没什么具体的事,把以前写的效果翻了出来发现有些地方不太理想然后修正了下做了个新版的代码如下:

(新版的优化了下以前的运动单一效果,新增了多属性同时修改方法,如果需要队列实现效果的话只需要在回调函数里面在新增此方法即可,以及在函数内部实例化避免多次外部实例)

PS:其实东西的核心没什么太大变化,只是在原本上做了少许的扩充,顺带记录下在做个东西的过程中对于opacity碰到了一些小问题,ie下如果未定义opacity那在获取时会为undefined的,这个比较无语。所以在做透明效果的时候一定要注意了

/*
 createByTommy_20110525
 emial:@csslife@163.com
 用途:
 执行渐隐等动画效果
 传入参数说明:
 1、第一个参数为需要变换对象或ID;
 2、第二个参数为一个对象包含:
 1)、sty->变换对象需要改变的属性,默认为改变宽度(也可以传非style的属性比如scrollTop等)
 2)、curClass->变换对象完成改变后需要添加的当前类,默认为空
 3)、maxVal->改变属于的最大值,默认为0(如果curClass为宽高等style属性表示隐藏),当这个要改变的属性值达到时停止动画
 4)、effect->执行的动画效果默认为outQuad,如需弹跳效果将其值设置为2
 3、最后个参数为可选参数表示当动画执行完毕后运行的回调函数
 ============================================================================================================
 2012年12月5号修正:
 参数:
 1、sty属性和maxVal参数废除,styJson属性新增此属性为json,其对应为属性为style属性,值为style动画最大值
 2、透明属性opacity值修改为百分数
 3、新增isHide属性来设置是否动画结束后隐藏,默认为0时隐藏(如不想加和这个属性同时有不想到0隐藏时那想margin这样的为0的属性写在最前面)
 功能:
 1、新增多属性同时修改动画效果
 2、实现内部实例化,避免了多次new;
 */
(function(localName){
    //animation
    var ani = function(e,s,callback){
        var _this = this;
        if(!(_this instanceof ani)) {return new ani(e,s,callback)}
        this.init.apply(this,arguments)
    }
    ani.prototype = {
        _id:function(i){
            if(!i) return;
            return typeof i != "string" && i.nodeType === 1 ? i : document.getElementById(i);
        },
        init:function(e,s,callback){
            this.e = this._id(e);
            this.setInit(s||{});
            this.getSty(this.e,"display")=="none"&&(this.e.style.display = "block");
            this.fun(this.e,callback)
        },
        formula:function(x){
            var f;
            switch(this.s.effect){
                case 0:
                    f = "outQuad";
                    break;
                case 1:
                    f = "inQuad";
                    break;
                case 2:
                    f = "bounce";
                    break;
                default:
                    f = "easeInBack";
            }
            this.tween ={
                outQuad:function(pos){return Math.pow(pos, 2)},//outQuad
                inQuad:function(pos){return -(Math.pow((pos-1),2)-1)},//inQuad
                bounce:function(pos){//bounce
                    if (pos < (1 / 2.75)) {
                        return (7.5625 * pos * pos);
                    } else if (pos < (2 / 2.75)) {
                        return (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75);
                    } else if (pos < (2.5 / 2.75)) {
                        return (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375);
                    } else {
                        return (7.5625 * (pos -= (2.625 / 2.75)) * pos + .984375);
                    }
                },
                easeInBack:function(pos){var s = 1.70158;return (pos) * pos * ((s + 1) * pos - s);}
            };
            return parseFloat(this.tween[f](x));
        },
        setInit:function(s){
            this.s = {
                styJson:null,
                curClass:"",
                isHide:true,
                effect:1//执行效果
            }
            for(var i in s) this.s[i] = s[i];
        },
        setSty:function(x,attr){
            var x = parseInt(parseFloat(x));
            if(attr=="opacity"){
                this.e.style.opacity = x/100;
                this.e.style.filter = "alpha(opacity="+x+")";
            }else{
                this.e.style[attr] = x + 'px';
                var isIE6 = navigator.appVersion.indexOf("MSIE 6")>-1;
                isIE6&&attr=="top"&&(this.e.style[attr] = x + document.documentElement.scrollTop + 'px');
            }
        },
        getSty:function(e,s){
            return e.currentStyle?e.currentStyle[s]:getComputedStyle(e,null)[s];
        },
        fun:function(obj,callback){
            var D = Date, t = new D, T = 500, _this = this, c = this.s.curClass, curC = this.e.className;
            obj.timer && clearInterval(obj.timer);
            obj.timer = setInterval(function() {
                var z = Math.min(1, (new D - t) / T),
                    maxS,speed;
                for(var sty in _this.s.styJson){
                    maxS = parseInt(_this.s.styJson[sty]);
                    speed = sty =="opacity" ? parseInt(_this.getSty(_this.e,sty))*100 : parseInt(_this.getSty(_this.e,sty));
                    _this.setSty( + speed + (maxS - speed) * _this.formula(z),sty);
                }
                if (z == 1) {
                    clearInterval(obj.timer);
                    if (callback && typeof callback == 'function') callback();
                    if(c!=""&&curC.indexOf(c)<0)_this.e.className += c;
                    maxS==0&&(_this.s.isHide)&&(_this.e.style.display="none");
                }
            },10);
        }
    };
    localName.ani = ani;
})(window);



然后基于这个修正版本的DEMO如下:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="gbk">
<title>test</title>
<style>
	div,h6,body{padding:0;margin:0;}
		div,h6{font:bold 12px/24px 'Tahoma';text-indent:15px;}
	.car-mod{position:relative;width:200px;}
		.car-menu{width:200px;background:#c06;cursor:pointer;color:#fff;}
		.car-box{border:2px solid #c06;width:0;overflow:hidden;filter:alpha(opacity=0);opacity:0;display:none}
		.car-box h6{background-color:#f5f5f5;background-image:-moz-linear-gradient(#f5f5f5,#fff);}
		.things{border-top:1px solid #ccc;padding:50px 15px;}
</style>
</head>

<body>
	<div class="car-mod" id="J_car_mod">
  
    <div class="car-menu">购物车</div>
    
    <div class="car-box" id="J_car_box">
      <h6>我的购物车</h6>
      <div class="things"></div>
    </div>

	</div>
<script src="animation.source.js"></script>
<script>
	(function(){
		//线上调用这个插件的时候直接调用animation.js这个是压缩了的
		var D = document,carMod = D.getElementById("J_car_mod"),carBox = D.getElementById("J_car_box"),carControl=true;
		//移入显示
		carMod.onmouseover = function(even){
			var even = even || window.event,target = even.target || even.srcElement;
			if(target.className=="car-menu"){
				!!carControl&&(ani(carBox,{styJson:{height:200,opacity:100}},function(){carControl=false;ani(carBox,{styJson:{width:300}})}));
			}
			//移出隐藏
			this.onmouseout = function(even){
				var e = even || window.event,
						reltg =  e.relatedTarget ? e.relatedTarget : e.type == 'mouseout' ? e.toElement : e.fromElement;
				while (reltg && reltg != this){reltg = reltg.parentNode;}		 
				if(reltg != this){
					!carControl&&(ani(carBox,{styJson:{width:0}},function(){carControl=true;ani(carBox,{styJson:{height:0,opacity:0}})}));
				}
			}
		}
	})()

</script>
</body>
</html>