怎样写一个通用的JavaScript效果库!(2/2)

来源:互联网 发布:键盘自动按键软件 编辑:程序博客网 时间:2024/06/11 18:54

来源:http://www.cnblogs.com/ashun/archive/2007/01/16/javascript-effect2.html 

在上个随笔中贴出了效果库的整体框架,和一个简单的opacity插件. 今天这个随笔主要是扩展其他常用
效果插件,毕竟框架只能是个空壳,内容还是要自己充实。
如果看过了我上篇的实现细节,这里就不多说废话了,来段代码先:

/****************************************************/

// 移动, 这里是move to  就是移动到 x,y 当然,大家也可以再扩展一个move by  移动x个象素
Effect.Init.move=function(effect){   //初始化
    if (effect.options.x!==undefined || effect.options.y!==undefined){        
        
var pos=Position.cumulativeOffset(effect.element);
        effect.setting.left       
=pos[0];
        effect.setting.top          
=pos[1];
        effect.setting.position 
=effect.element.style.position;     
        effect.element.style.position    
="absolute"
        effect.options.x
=(effect.options.x===undefined)?effect.setting.left:effect.options.x;
        effect.options.y
=(effect.options.y===undefined)?effect.setting.top :effect.options.y;                        
    }

}


Effect.Fn.move
=function(effect,pos){     //效果
    if (effect.options.x===undefined && effect.options.y===undefined) return        
    effect.element.style.left
=effect.setting.left + (effect.options.x-effect.setting.left) * pos +"px";
    effect.element.style.top 
=effect.setting.top  + (effect.options.y-effect.setting.top ) * pos +"px";
}

/****************************************************/




/****************************************************/
// zoom   by Go_Rush(阿舜) from http://ashun.cnblogs.com/
Effect.Init.zoom=function(effect){    
    effect.setting.zoom      
=effect.element.style.zoom || 1;
    
// firefox 不支持 css的 zoom 用  改变 width,height的方式代替
    if (effect.options.zoom!==undefined && navigator.userAgent.toLowerCase().indexOf('firefox') != -1){                    
        effect.options.w
=effect.element.offsetWidth  * effect.options.zoom;
        effect.options.h
=effect.element.offsetHeight * effect.options.zoom;    
    }

}

Effect.Fn.zoom
=function(effect,pos){
    
if (effect.options.zoom===undefined) return;
    effect.element.style.zoom
=effect.setting.zoom+(effect.options.zoom-effect.setting.zoom)*pos
}


/****************************************************/


/****************************************************/
// size  同上,是 size to, 改变到指定大小 by Go_Rush(阿舜) from http://ashun.cnblogs.com/
Effect.Init.size=function(effect){
    
if (effect.options.w!==undefined || effect.options.h!==undefined){
        effect.setting.overflow   
=effect.element.style.overflow || 'visible';
        effect.setting.width      
=effect.element.offsetWidth;
        effect.setting.height      
=effect.element.offsetHeight; 
        effect.element.style.overflow 
="hidden"    
        effect.options.w
=(effect.options.w===undefined)?effect.setting.width :effect.options.w;
        effect.options.h
=(effect.options.h===undefined)?effect.setting.height:effect.options.h;            
    }

}


Effect.Fn.size
=function(effect,pos){    
    
if (effect.options.w===undefined && effect.options.h===undefined) return;
    effect.element.style.width 
=effect.setting.width + (effect.options.w-effect.setting.width ) * pos +"px";
    effect.element.style.height
=effect.setting.height+ (effect.options.h-effect.setting.height) * pos +"px";
}

/****************************************************/


/****************************************************/
// 背景色 by Go_Rush(阿舜) from http://ashun.cnblogs.com/
Effect.Init.bgcolor=function(effect){
    
if (effect.options.bgcolor!==undefined && /^/#?[a-f0-9]{6}$/i.test(effect.options.bgcolor)){
        
var color =effect.element.style.backgroundColor || "#ffffff";
        
//FireFox 下,即使css样式设置背景为 #ffffff格式,但程序取到的是 rgb(255,255,255)格式, 这里把他转化为 #ffffff格式
        if (/rgb/i.test(color)){               // "rgb(255, 0, 255)"
            //var arr=color.replace(/[rgb/(/s/)]/gi,"").split(",")
            var arr=eval(color.replace("rgb","new Array"))       
            color
="#"+Number(arr[0]).toColorPart()+Number(arr[1]).toColorPart()+Number(arr[2]).toColorPart()
        }

        effect.setting.bgcolor
=color
    }

}

Effect.Fn.bgcolor
=function(effect,pos){    
    
if (effect.options.bgcolor===undefined) return;
    
var c1=effect.setting.bgcolor,c2=effect.options.bgcolor
    
var arr1=[parseInt(c1.slice(1,3),16),parseInt(c1.slice(3,5),16),parseInt(c1.slice(5),16)]
    
var arr2=[parseInt(c2.slice(1,3),16),parseInt(c2.slice(3,5),16),parseInt(c2.slice(5),16)]
    
var r=Math.round(arr1[0]+(arr2[0]-arr1[0])*pos)
    
var g=Math.round(arr1[1]+(arr2[1]-arr1[1])*pos)
    
var b=Math.round(arr1[2]+(arr2[2]-arr1[2])*pos)
    effect.element.style.backgroundColor
="#"+r.toColorPart()+g.toColorPart()+b.toColorPart()
}

/****************************************************/


/****************************************************/
// 透明度,这个上个贴过了   by Go_Rush(阿舜) from http://ashun.cnblogs.com/
Effect.Init.opacity=function(effect){
    
if (effect.options.opacity===undefined) return;
    effect.setting.opacity
=Opacity(effect.element);    
}


Effect.Fn.opacity
=function(effect,pos){
    
if (effect.options.opacity===undefined) return;
    Opacity(effect.element,effect.setting.opacity
+(effect.options.opacity-effect.setting.opacity)*pos);    
}

/****************************************************/


这里 effect.setting 是非常有用而且非常重要的冬冬,所有的通过options传进来自定义函数都可以
通过effect.setting来获取element最初的设置。 在很多场合,我们需要在 options 中传一个 onComplete
函数进来, 用来在效果执行完毕后,打扫战场,恢复一些设置。
这些效果是可以重叠的,大家可以看看下面我写的例子。

写了十来个例子,应该很详细了。

完整的,可调试代码和例子如下:


<script language="javascript">
/*
    这个函数的代码来自 Prototype.js  http://prototype.conio.net/
    如果页面引用了prototype.js ,则可以删除下面这个函数,
    当然,即使不删除也没关系,因为作了简单的兼容性判断
*/

(
function(){   
    
if     (!("Prototype" in window)){
        Prototype
={emptyFunction:function(){}};
        Class 
={
            create: 
function(){return function(){this.initialize.apply(this, arguments)}}
        }
;        
        $ 
= function(element){
            
return typeof(element)=="string"?document.getElementById(element):element
        }
;
        $A
= function(arrLike){
            
for(var i=0,ret=[];i<arrLike.length;i++) ret[i]=arrLike[i];
            
return ret
        }
;    
        
        Number.prototype.toColorPart 
=function(){return String("00"+this.toString(16)).slice(-2)};        
        Function.prototype.bind 
= function() {
             
var __method = this, args = $A(arguments), object = args.shift();
            
return function(){return __method.apply(object, args.concat($A(arguments)))}
        }


        Position
=
             cumulativeOffset: 
function(element) {
                
var valueT = 0, valueL = 0;
                
do {
                  valueT 
+= element.offsetTop  || 0;
                  valueL 
+= element.offsetLeft || 0;
                  element 
= element.offsetParent;
                }
 while (element);
                
return [valueL, valueT];
            }

        }
        
    }

}
)()

/*
    1.读取/设置 透明度,
    2.如果只传了一个参数element,则返回 element的透明度 (0<value<1)
    3.如果传了两个参数 element和value 则把element的透明度设置为value  value范围 0-1
    
*/

function Opacity(element,value){
    
//by Go_Rush(阿舜) from http://ashun.cnblogs.com/
    var ret;
    
if (value===undefined){   //读取
        if (!/msie/i.test(navigator.userAgent))
            
if (ret=element.style.opacity) return parseFloat(ret);          
        
try{return element.filters.item('alpha').opacity/100}catch(x){return 1.0}
    }
else{                   //设置        
        value=Math.min(Math.max(value,0.00001),0.999999)    //这句修复一些非ie浏览器opacity不能设置为1的bug
        if (/msie/i.test(navigator.userAgent)) return element.style.filter="alpha(opacity="+value*100+")"
        
return element.style.opacity=value        
    }

}



Effect        
=Class.create();
Effect.Fn    
=new Object();
Effect.Init 
=new Object();

Effect.prototype
={
    
//by Go_Rush(阿舜) from http://ashun.cnblogs.com/
    
    initialize: 
function(element,options) {
        
this.element  = $(element);
            
this.options  = options || {};
         
this.duration = (this.options.duration || 2* 1000;   //效果执行时间
        this.fps      = this.options.fps || 50;                 //频率
           this.steps    = Math.floor(this.duration/this.fps);   //当前步长,注: 这个变量是递减的,当它0的时候意味着整个效果结束
        this.maxSteps = this.steps;             //整个效果的步长
        this.setting  = new Object();  
        
this.timer    = null;        

           
if (this.options.delay){    // 延时处理
             var _this=this;
             setTimeout(
function(){
                 _this.setup(_this);
                (_this.options.onStart 
|| Prototype.emptyFunction)(_this);
                 _this.run();
                }
, _this.options.delay*1000);
        }
else{
            
this.setup(this);
            (
this.options.onStart || Prototype.emptyFunction)(this);        
            
this.run();      
        }

   }
,
   run: 
function() {
        
if (this.isFinished())  return (this.options.onComplete || Prototype.emptyFunction)(this);
        
if (this.timer)   clearTimeout(this.timer);
        
this.duration -= this.fps;
        
this.steps--;                           
        
var pos=1-this.steps/this.maxSteps    ;    //总进度的百分比
        this.loop(this,pos);    
        (
this.options.onUpdate || Prototype.emptyFunction)(this,pos);      
        
this.timer = setTimeout(this.run.bind(this), this.fps);
   }
,
   isFinished: 
function() 
           
return this.steps <= 0;
   }
,
   setup:
function(effect){       //初始化设置所有效果单元
           for(var key in Effect.Init){
            
if (typeof(Effect.Init[key])!="function"continue;
            
try{Effect.Init[key](this)}catch(x){}
        }

    }
,
   loop:
function(effect,pos){           //执行所有效果单元
        for(var key in Effect.Fn){
            
if (typeof(Effect.Fn[key])!="function"continue;
            
try{Effect.Fn[key](effect,pos)}catch(x){}
        }

   }

}


/****************************************************/

// 移动, 这里是move to  就是移动到 x,y 当然,大家也可以再扩展一个move by  移动x个象素
Effect.Init.move=function(effect){   //初始化
    if (effect.options.x!==undefined || effect.options.y!==undefined){        
        
var pos=Position.cumulativeOffset(effect.element);
        effect.setting.left       
=pos[0];
        effect.setting.top          
=pos[1];
        effect.setting.position 
=effect.element.style.position;     
        effect.element.style.position    
="absolute"
        effect.options.x
=(effect.options.x===undefined)?effect.setting.left:effect.options.x;
        effect.options.y
=(effect.options.y===undefined)?effect.setting.top :effect.options.y;            
    }

}


Effect.Fn.move
=function(effect,pos){     //效果
    if (effect.options.x===undefined && effect.options.y===undefined) return        
    effect.element.style.top 
=effect.setting.top  + (effect.options.y-effect.setting.top ) * pos +"px";
    effect.element.style.left
=effect.setting.left + (effect.options.x-effect.setting.left) * pos +"px";
    
}

/****************************************************/




/****************************************************/
// zoom
Effect.Init.zoom=function(effect){    
    effect.setting.zoom      
=effect.element.style.zoom || 1;
    
// firefox 不支持 css的 zoom 用  改变 width,height的方式代替
    if (effect.options.zoom!==undefined && navigator.userAgent.toLowerCase().indexOf('firefox') != -1){                    
        effect.options.w
=effect.element.offsetWidth  * effect.options.zoom;
        effect.options.h
=effect.element.offsetHeight * effect.options.zoom;    
    }

}

Effect.Fn.zoom
=function(effect,pos){
    
if (effect.options.zoom===undefined) return;
    effect.element.style.zoom
=effect.setting.zoom+(effect.options.zoom-effect.setting.zoom)*pos
}


/****************************************************/


/****************************************************/
// size  同上,是 size to, 改变到指定大小
Effect.Init.size=function(effect){
    
if (effect.options.w!==undefined || effect.options.h!==undefined){
        effect.setting.overflow   
=effect.element.style.overflow || 'visible';
        effect.setting.width      
=effect.element.offsetWidth;
        effect.setting.height      
=effect.element.offsetHeight; 
        effect.element.style.overflow 
="hidden"    
        effect.options.w
=(effect.options.w===undefined)?effect.setting.width :effect.options.w;
        effect.options.h
=(effect.options.h===undefined)?effect.setting.height:effect.options.h;            
    }

}


Effect.Fn.size
=function(effect,pos){    
    
if (effect.options.w===undefined && effect.options.h===undefined) return;
    effect.element.style.width 
=effect.setting.width + (effect.options.w-effect.setting.width ) * pos +"px";
    effect.element.style.height
=effect.setting.height+ (effect.options.h-effect.setting.height) * pos +"px";
}

/****************************************************/


/****************************************************/
// 背景色
Effect.Init.bgcolor=function(effect){
    
if (effect.options.bgcolor!==undefined && /^/#?[a-f0-9]{6}$/i.test(effect.options.bgcolor)){
        
var color =effect.element.style.backgroundColor || "#ffffff";
        
//FireFox 下,即使css样式设置背景为 #ffffff格式,但程序取到的是 rgb(255,255,255)格式, 这里把他转化为 #ffffff格式
        if (/rgb/i.test(color)){               // "rgb(255, 0, 255)"
            //var arr=color.replace(/[rgb/(/s/)]/gi,"").split(",")
            var arr=eval(color.replace("rgb","new Array"))       
            color
="#"+Number(arr[0]).toColorPart()+Number(arr[1]).toColorPart()+Number(arr[2]).toColorPart()
        }

        effect.setting.bgcolor
=color
    }

}

Effect.Fn.bgcolor
=function(effect,pos){    
    
if (effect.options.bgcolor===undefined) return;
    
var c1=effect.setting.bgcolor,c2=effect.options.bgcolor
    
var arr1=[parseInt(c1.slice(1,3),16),parseInt(c1.slice(3,5),16),parseInt(c1.slice(5),16)]
    
var arr2=[parseInt(c2.slice(1,3),16),parseInt(c2.slice(3,5),16),parseInt(c2.slice(5),16)]
    
var r=Math.round(arr1[0]+(arr2[0]-arr1[0])*pos)
    
var g=Math.round(arr1[1]+(arr2[1]-arr1[1])*pos)
    
var b=Math.round(arr1[2]+(arr2[2]-arr1[2])*pos)
    effect.element.style.backgroundColor
="#"+r.toColorPart()+g.toColorPart()+b.toColorPart()
}

/****************************************************/


/****************************************************/
// 透明度,这个上个贴过了
Effect.Init.opacity=function(effect){
    
if (effect.options.opacity===undefined) return;
    effect.setting.opacity
=Opacity(effect.element);    
}


Effect.Fn.opacity
=function(effect,pos){
    
if (effect.options.opacity===undefined) return;
    Opacity(effect.element,effect.setting.opacity
+(effect.options.opacity-effect.setting.opacity)*pos);    
}

/****************************************************/



function foo1(){
    
new Effect("div1",{bgcolor:"#3a3e3f"})
}


function foo2(){
    
new Effect("div1",{w:150,h:100})
}



function foo3(){
    
new Effect("div1",{x:100,y:100})
}



function foo4(){
    
new Effect("div1",{opacity:0.2})
}


function foo5(){
    
new Effect("div1",{zoom:2})
}


function foo6(){
    
new Effect("div1",{w:222,h:111,onComplete:function(){
            
new Effect("div1",{x:100,y:300,onComplete:function(){
                
new Effect("div1",{opacity:0.7,onComplete:function(){
                    
new Effect("div1",{zoom:2,onComplete:function(){
                        
new Effect("div1",{bgcolor:"#111111",onComplete:function(){                
                            alert(
"all done")
                        }
}
)
                    }
}
)
                }
}
)
            }
}
)
        }
}
)
}



function fix1(){
    
new Effect("div1",{zoom:4,opacity:0,x:0,y:0,onComplete:function(eff){
        eff.element.style.display
="none"
    }
}
)
}




function fix2(){
    
new Effect("div1",{y:80,h:22})
}



function fix3(){   //注意这种复合  
    new Effect("div1",{h:22,onComplete:function(eff){
            
new Effect("div1",{w:0})
    }
}
)
    
new Effect("div1",{opacity:0,duration:4})

}


function fix4(){
    
new Effect("div1",{opacity:0,zoom:0})
}



function fix5(){
    
new Effect("div1",{bgcolor:"#000000",onComplete:function(){
        
new Effect("div1",{bgcolor:"#ffffff"})
    }
}
)
}


var i=0;
function fix6(){
    
if (++i>5return false;
    
new Effect("div1",{x:280,delay:0.5,duration:0.1,onComplete:function(){
        
new Effect("div1",{x:320,duration:0.1,onComplete:function(){        
            
new Effect("div1",{x:280,duration:0.1,onComplete:function(){        
                
new Effect("div1",{x:320,duration:0.1,onComplete:function(){        
                    
new Effect("div1",{x:280,duration:0.1,onComplete:function(){        
                        
new Effect("div1",{x:300,duration:0.1,onComplete:function(){    
                            fix6()    
                        }
}
)        
                    }
}
)        
                }
}
)        
            }
}
)                    
        }
}
)        
    }
}
)
}



</script>
<fieldset>
<legend>单一效果</legend>
<button onclick="javascript:foo1()">颜 色 foo1</button>&nbsp;
<button onclick="javascript:foo2()">大 小 foo2</button>&nbsp;
<button onclick="javascript:foo3()">位 置 foo3</button>&nbsp;
<button onclick="javascript:foo4()">透 明 度 foo4</button>&nbsp;
<button onclick="javascript:foo5()">Zoom foo5</button>&nbsp;
<button onclick="javascript:foo6()">所有 foo6</button>&nbsp;
<br />
</fieldset>
<br />
<fieldset>
<legend>复合效果</legend>
<button onclick="javascript:fix1()"> 淡出fix1</button>&nbsp;
<button onclick="javascript:fix2()"> 折起fix2</button>&nbsp;
<button onclick="javascript:fix3()"> 慢慢变小消失 fix3</button>&nbsp;
<button onclick="javascript:fix4()"> 慢慢变小消失2 fix4</button>&nbsp;
<button onclick="javascript:fix5()"> 变色 fix5</button>&nbsp;
<button onclick="javascript:fix6()"> 震动5次 fix6</button>&nbsp;
<br />
</fieldset>

<br />
<br />
<button onclick="javascript:location.reload()"> 每次效果后按这里恢复</button>&nbsp;
<br/> 
<br/>
注意 FireFox 不支持 Zoom

<div id="div1" style="border:1px solid red;width:300px;height:150px;overflow:hidden;position:absolute;left:300px;top:200px;z-index:2;background-color:#ffffff"> 
      
<a href="http://ashun.cnblogs.com/">Go_Rush(阿舜)</a>
    
<img src="http://www.google.com/intl/zh-CN_ALL/images/logo.gif"><br />
</div>