JavaScript 渐变效果

程序集合了宽度、高度、透明度、top、left的渐变,可以自定义渐变项目和各个项目的初始值结束值,还能以任意点(定点)为中心渐变。

使用该程序能实现很多常见的动画特效,包括大小变换、位置变换、渐显渐隐等等。

效果:

程序说明:

渐变效果的原理就是利用定时器不断设置值,如果要减速效果就设置一个步长(详细看JavaScript 弹簧效果) 。
这里只是把能渐变的属性(透明度、宽、高、left、top)整合在一起,使用相同的渐变级数(Step)使渐变同步,形成多个属性同时渐变的效果。

下面说说有用的地方:


【最终样式】
JavaScript 图片切割效果的边宽获取中也说到了最终样式,在使用offset获取的数据设置宽度高度的时候,必须先减去最终样式中的边框宽度。
在这里我使用了muxrwc的在FF下实现currentStyle方法,这样在ff和ie都可以从currentStyle获取最终样式了:

JavaScript 渐变效果JavaScript 渐变效果Code
if (!isIE){
HTMLElement.prototype.defineGetter(“currentStyle “,function () {
return this .ownerDocument.defaultView.getComputedStyle(this ,null );
});
}

使用这个获取边框宽度:

this ._xBorder =function (){return (parseInt(obj.currentStyle.borderLeftWidth)+parseInt(obj.currentStyle.borderRightWidth)); }
this ._yBorder =function (){return (parseInt(obj.currentStyle.borderTopWidth)+parseInt(obj.currentStyle.borderBottomWidth)); }

【宽度或高度优先】
宽度或高度优先其实就是先执行其中一个渐变,在完成后再执行另一个渐变。
渐变程序中在执行完一次渐变之后会返回一个bool值表示是否渐变完成,利用这个可以这样:

this .SetWidth()&&this .SetHeight();

由于&&的特性,当this.SetWidth()返回true时才会去执行this.SetHeight(),这也是不错的技巧。
同时为了同步渐变,另外的渐变使用了两倍的步长:

JavaScript 渐变效果JavaScript 渐变效果Code
this .Step =2 *this .Step;
this .SetOpacity();this .SetTop();this .SetLeft();
this .Step =this .Step /2;

这样就能做出宽度或高度优先的效果了。

【定点渐变】
先说说原理,例如以宽度中点为参照点,可以想象如果宽度减少n,那只要left相对增加n*0.5(即n/2),
那么就可以做出以中点为中心变换的效果(当然要先把变换对象设为相对或绝对定位)。
那这个”0.5″怎么来的呢?有点数理知识应该知道就是渐变对象左边到变换点跟渐变对象总宽度的比
程序里用Width.pos保存这个值,在变换前先计算好变换点的位置:

this ._x =this ._obj.offsetLeft +this ._obj.offsetWidth *this .Width.pos;

每次变换都根据这个位置和宽度来重新设置left:

this ._obj.style.left =this ._x -this ._obj.offsetWidth *this .Width.pos +”px “;

可能有人会说直接在原有left基础上加上变换宽度*Width.pos不是一样吗?
但问题是经过多次的变换计算(到达目标值前会有多次计算)之后得到的值已经不准确了。
因为在变换计算过程中很多小数会被忽略,随着计算次数增多结果的出入也越大,
所以先定好变换位置参照值(_x),这样不论经过多少次计算变换位置都不会走位了。

同理只要设置不同的Width.pos(包括负数和大于1的数)和Height.pos就可以以任意点为中心渐变了。

还有就是程序的设计也花了不少心思,为了提高整合度,做了一个FadeStruct的结构,其中run、start、end、target属性分别是是否渐变、开始值、结束值、目标值。
用了两次的Object.extend来设置默认值,详细可以看程序。

使用说明:

必要的参数只有一个,就是渐变对象,不过只有渐变对象是没有效果的,必须设置其他属性:
Opacity:透明渐变参数
Height:高度渐变参数
Width:宽度渐变参数
Top:Top渐变参数
Left:Left渐变参数
Step:10,//变化率
Time:10,//变化间隔
Mode:”both”,//渐变顺序
Show:false,//是否默认打开状态
onFinish:function(){}//完成时执行

其中Opacity、Height、Width、Top、Left比较特别,是FadeStruct结构

例子里实例化这个对象:

JavaScript 渐变效果JavaScript 渐变效果Code
var f =new Fade(“idFade “, { Show:true ,
Opacity: { run:true },
Height: { run:true },
Width: { run:true , pos: .5 },
Top: { run:true , end:70 }
});

设置run为true就表示开启这个变换,start和end是开始和结束值,pos是Height和Width特有的变换位置属性。

更详细的应用可以看实例。

程序代码:

JavaScript 渐变效果JavaScript 渐变效果Code
var isIE =(document.all)?true :false ;

var $=function (id) {
return “string “==typeof id ?document.getElementById(id) : id;
};

if (!isIE){
HTMLElement.prototype.defineGetter(“currentStyle “,function () {
return this .ownerDocument.defaultView.getComputedStyle(this ,null );
});
}

var Class ={
create:function () {
return function () {
this .initialize.apply(this , arguments);
}
}
}

Object.extend =function (destination, source) {
for (var property in source) {
destination[property]=source[property];
}
return destination;
}

var FadeStruct =function (options){
this .run =false ;//是否渐变this .start =0 ;//开始值this .end =0 ;//结束值this .target =0 ;//目标值Object.extend(this , options ||{});
}

var Fade =Class.create();
Fade.prototype ={
initialize:function (obj, options) {

var obj =$(obj);
obj.style.overflow =”hidden “;
this ._obj =obj;

this ._timer =null ;//定时器this ._finish =true ;//是否执行完成this ._fun =function (){};//渐变程序this ._x =this ._y =0 ;//变换点位置//设置获取透明度程序this ._setOpacity =isIE ?function (opacity){ obj.style.filter =”alpha(opacity:”+opacity +”)”; } :function (opacity){ obj.style.opacity =opacity /100 ; };
this ._getOpacity =isIE ?function (){return parseInt(obj.filters[“alpha “].opacity); } :function (opacity){return 100 *parseFloat(obj.currentStyle.opacity); };

//获取边框宽度程序this ._xBorder =function (){return (parseInt(obj.currentStyle.borderLeftWidth)+parseInt(obj.currentStyle.borderRightWidth)); }
this ._yBorder =function (){return (parseInt(obj.currentStyle.borderTopWidth)+parseInt(obj.currentStyle.borderBottomWidth)); }

this .SetOptions(options);

this .Mode =this .options.Mode;
this .Time =Math.abs(this .options.Time);
this .onFinish =this .options.onFinish;

//先设置特殊默认值this .Opacity =new FadeStruct({ end:100 });
this .Top =new FadeStruct({ start:this ._obj.offsetTop, end:this ._obj.offsetTop });
this .Left =new FadeStruct({ start:this ._obj.offsetLeft, end:this ._obj.offsetLeft });
this .Height =new FadeStruct({ end:this ._obj.offsetHeight -this ._yBorder() });
this .Width =new FadeStruct({ end:this ._obj.offsetWidth -this ._xBorder() });

//再设置用户默认值Object.extend(this .Opacity,this .options.Opacity);
Object.extend(this .Top,this .options.Top);
Object.extend(this .Left,this .options.Left);
Object.extend(this .Height,this .options.Height);
Object.extend(this .Width,this .options.Width);

//变换位置参数this .Height.pos =Number(this .options.Height.pos);
this .Width.pos =Number(this .options.Width.pos);

//设置成默认状态this .Show =!this .options.Show;
this .Step =1 ;
this .Start();
//重新设置Step this .Step =Math.abs(this .options.Step);
},
//设置默认属性SetOptions:function (options) {
this .options ={//默认值Opacity: {},//透明渐变参数Height: {},//高度渐变参数Width: {},//宽度渐变参数Top: {},//Top渐变参数Left: {},//Left渐变参数Step:10 ,//变化率Time:10 ,//变化间隔Mode:”both “,//渐变顺序Show:false ,//是否默认打开状态onFinish:function (){}//完成时执行};
Object.extend(this .options, options ||{});
},
//触发Start:function () {
clearTimeout(this ._timer);
//取反表示要设置的状态this .Show =!this .Show;
//为避免透明度为null值,需要先设置一次透明度if (this .Opacity.run){this ._setOpacity(this .Show ?this .Opacity.start :this .Opacity.end); }
//根据状态设置目标值if (this .Show){
this .Opacity.target =this .Opacity.end;
this .Top.target =this .Top.end;
this .Left.target =this .Left.end;
this .Height.target =this .Height.end;
this .Width.target =this .Width.end;
}else {
this .Opacity.target =this .Opacity.start;
this .Top.target =this .Top.start;
this .Left.target =this .Left.start;
this .Height.target =this .Height.start;
this .Width.target =this .Width.start;
}
//设置渐变程序switch (this .Mode.toLowerCase()) {
case “width “:
this ._fun =function (){
this .SetWidth()&&this .SetHeight();
//由于分了两步,下面的步长变成两倍this .Step =2 this .Step;
this .SetOpacity();this .SetTop();this .SetLeft();
this .Step =this .Step /2;}
break ;
case “height “:
this ._fun =function (){
this .SetHeight()&&this .SetWidth();
//由于分了两步,下面的步长变成两倍this .Step =2
this .Step;
this .SetOpacity();this .SetTop();this .SetLeft();
this .Step =this .Step /2;}
break ;
case “both “:
default :
this ._fun =function (){this .SetHeight();this .SetWidth();this .SetOpacity();this .SetTop();this .SetLeft();}
}
//获取变换点位置//由于设置变换点后与top和left变换有冲突只能执行其一if (this .Height.pos){this ._y =this ._obj.offsetTop +this ._obj.offsetHeight this .Height.pos;this .Top.run =false ; }
if (this .Width.pos){this ._x =this ._obj.offsetLeft +this ._obj.offsetWidth
this .Width.pos;this .Left.run =false ; }

this .Run();
},
//执行Run:function () {
clearTimeout(this ._timer);
this ._finish =true ;
//执行渐变this ._fun();
//未完成继续执行if (this ._finish) {this .onFinish(); }
else {var oThis =this ;this ._timer =setTimeout(function (){ oThis.Run(); },this .Time); }
},
//设置高度渐变SetHeight:function () {
var iGet =this .Get(this .Height,this ._obj.offsetHeight -this ._yBorder());
if (isNaN(iGet))return true ;

this ._obj.style.height =iGet +”px “;
//如果有变换点设置if (this .Height.pos){this ._obj.style.top =this ._y -this ._obj.offsetHeight *this .Height.pos +”px “; }
return false ;
},
//设置宽度渐变SetWidth:function () {
var iGet =this .Get(this .Width,this ._obj.offsetWidth -this ._xBorder());
if (isNaN(iGet))return true ;

this ._obj.style.width =iGet +”px “;
if (this .Width.pos){this ._obj.style.left =this ._x -this ._obj.offsetWidth *this .Width.pos +”px “; }
return false ;
},
//设置top渐变SetTop:function () {
var iGet =this .Get(this .Top,this ._obj.offsetTop);
if (isNaN(iGet))return true ;

this ._obj.style.top =iGet +”px “;
return false ;
},
//设置left渐变SetLeft:function () {
var iGet =this .Get(this .Left,this ._obj.offsetLeft);
if (isNaN(iGet))return true ;

this ._obj.style.left =iGet +”px “;
return false ;
},
//设置透明渐变SetOpacity:function () {
var iGet =this .Get(this .Opacity,this ._getOpacity());
if (isNaN(iGet))return true ;

this ._setOpacity(iGet);
return false ;
},
//获取设置值Get:function (o, now){
if (o.run){
var iStep =(o.target -now)/this .Step;
if (iStep){
this ._finish =false ;
if (Math.abs(iStep)<1 ){ iStep =iStep >0 ?1 :-1 ; }
return now +iStep;
}
}
}
};

下载完整测试代码

Original: https://www.cnblogs.com/cloudgamer/archive/2008/08/27/1277131.html
Author: cloudgamer
Title: JavaScript 渐变效果

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/535908/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球