javascript
JavaScript 渐变效果
程序集合了寬度、高度、透明度、top、left的漸變,可以自定義漸變項目和各個項目的初始值結束值,還能以任意點(定點)為中心漸變。
使用該程序能實現很多常見的動畫特效,包括大小變換、位置變換、漸顯漸隱等等。
?
效果:
?
?
程序說明:
漸變效果的原理就是利用定時器不斷設置值,如果要減速效果就設置一個步長(詳細看JavaScript 彈簧效果) 。
這里只是把能漸變的屬性(透明度、寬、高、left、top)整合在一起,使用相同的漸變級數(Step)使漸變同步,形成多個屬性同時漸變的效果。
下面說說有用的地方:
【最終樣式】
在JavaScript 圖片切割效果的邊寬獲取中也說到了最終樣式,在使用offset獲取的數據設置寬度高度的時候,必須先減去最終樣式中的邊框寬度。
在這里我使用了muxrwc的在FF下實現currentStyle方法,這樣在ff和ie都可以從currentStyle獲取最終樣式了:
if(!isIE){
????HTMLElement.prototype.__defineGetter__("currentStyle",?function?()?{
????????return?this.ownerDocument.defaultView.getComputedStyle(this,?null);
????});
}
使用這個獲取邊框寬度:
this._yBorder?=?function(){?return?(parseInt(obj.currentStyle.borderTopWidth)?+?parseInt(obj.currentStyle.borderBottomWidth));?}
【寬度或高度優先】
寬度或高度優先其實就是先執行其中一個漸變,在完成后再執行另一個漸變。
漸變程序中在執行完一次漸變之后會返回一個bool值表示是否漸變完成,利用這個可以這樣:
由于&&的特性,當this.SetWidth()返回true時才會去執行this.SetHeight(),這也是不錯的技巧。
同時為了同步漸變,另外的漸變使用了兩倍的步長:
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保存這個值,在變換前先計算好變換點的位置:
每次變換都根據這個位置和寬度來重新設置left:
可能有人會說直接在原有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結構
例子里實例化這個對象:
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特有的變換位置屬性。
更詳細的應用可以看實例。?
程序代碼:
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;
????????}
????}
??}
};
下載完整測試代碼
總結
以上是生活随笔為你收集整理的JavaScript 渐变效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “如果微信显示已读的话&rd
- 下一篇: 2024 款奥迪 RS Q8 汽车曝光: