在搭建博主博客的時候,尋思着作一些效果,看到菜單,就想是否是能夠作一下顏色的漸變,增長一點動態的感受。有個jquery的插件,效果至關不錯,不過博主仍是打算自立更生寫一下,看看能不能實現。javascript
下面就是博主的一些思路和解決辦法,若是對此沒興趣,想直接使用jquery插件的同窗,能夠點這裏css
java
jquery
算法
簡單的講,就是將6位顏色代碼以每兩位轉換爲10進制數,而後計算兩對RGB值的差,根據設定的步長(執行次數),計算每一步須要增長或減小的RGB值,最後變爲目標顏色的RGB值數組
關於16進制轉爲10進制,學校課本上就已經講過了。個位*16的0次方,十位*16的1次方,以此類推。顏色是由RGB組成,每兩位爲一組,如:#123456,R=12,G=34,B=56,但實際上RGB值是10進制,因此,R=12只能說是對應的位置,12轉爲10進制:2*1+1*16=18,34:4*1+3*16=52,56:6*1+5*16=96,因此RGB=[18,52,96]。app
這是數字的,但16進制還有A-F,因此還得先將A-F轉爲10-15,能夠先用一個數組來保存整個16進制對應的數jquery插件
var f=new Array(); f['0']=0; f['1']=1; f['2']=2; f['3']=3; f['4']=4; f['5']=5; f['6']=6; f['7']=7; f['8']=8; f['9']=9; f['A']=10; f['B']=11; f['C']=12; f['D']=13; f['E']=14; f['F']=15;
由於顏色代碼是不區分大小寫的,因此能夠先把顏色所有轉換爲大寫測試
code=code.toLocaleUpperCase();//轉換爲大寫
接着就是16進制轉爲10進制this
//code即爲6位顏色代碼,如:f07786; var r=f[code[0]]*16+f[code[1]]; var g=f[code[2]]*16+f[code[3]]; var b=f[code[4]]*16+f[code[5]];
整個轉換的代碼,寫成一個方法
function colorConversion(code){ var len=code.length; var f=new Array(); f['0']=0; f['1']=1; f['2']=2; f['3']=3; f['4']=4; f['5']=5; f['6']=6; f['7']=7; f['8']=8; f['9']=9; f['A']=10; f['B']=11; f['C']=12; f['D']=13; f['E']=14; f['F']=15; code=code.toLocaleUpperCase();//轉換爲大寫 var s=code.substr(0,1); if(s=='#'){ code=code.substr(1,6); } var r=f[code[0]]*16+f[code[1]]; var g=f[code[2]]*16+f[code[3]]; var b=f[code[4]]*16+f[code[5]]; return [r,g,b]; }
代碼中的s,是用來判斷顏色代碼是否帶有#號,有就去掉,最後返回一個包含RGB值的數組
好比,設定顏色變化次數爲10次,那就須要計算這10次變化,每一次RGB值的增減數值是多少。利用當前顏色的RGB值和目標顏色的RGB的差取絕對值,而後除以10,能夠獲得一個步長,但這個值極可能是小數,能夠把小數捨去,那麼在最後一步增減數值的時候,直接變到目標顏色的RGB值就好了
var _step=10; var _R_step=parseInt(Math.abs(_thisRGB[0]-_toRGB[0])/_step); //R的增減步長 var _G_step=parseInt(Math.abs(_thisRGB[1]-_toRGB[1])/_step); //G的增減步長 var _B_step=parseInt(Math.abs(_thisRGB[2]-_toRGB[2])/_step); //B的增減步長
若是執行次數爲10,也就是要連續的執行10次,當_step=1的時候,就算執行完成。那麼在增減步長上,就會出現,若是_step=10,那麼增減就是1倍步長,若是_step=9,也就是執行到第二步,那增減的就是2倍步長,一直到_step=1,增減9倍步長。這裏可使用這麼一句簡單的計算
var step=10; var _step=step; //循環體內 var s=(step-_step)+1; _step--;
接着判斷當前顏色RGB值和目標RGB的是增長仍是減小
var r=_step==1?_toRGB[0]:(_thisRGB[0]>_toRGB[0]?_thisRGB[0]-_R_step*s:_thisRGB[0]+_R_step*s); var g=_step==1?_toRGB[1]:(_thisRGB[1]>_toRGB[1]?_thisRGB[1]-_G_step*s:_thisRGB[1]+_G_step*s); var b=_step==1?_toRGB[2]:(_thisRGB[2]>_toRGB[2]?_thisRGB[2]-_B_step*s:_thisRGB[2]+_B_step*s);
最後,將顏色輸出
obj.css({'background-color':'rgb('+r+','+g+','+b+')'});
這裏輸出的是rgb()的方式,不要緊,和顏色代碼同理,若是以爲仍是輸出6位代碼,那就將10進制轉成16進制就行了
最後就是用定時器來執行,中間還有對速度和計算,這裏就不講了。最後的執行代碼:
/* 參數: obj:目標對象 thisRGB:當前背景顏色的6位代碼 toRGB:目標背景顏色的6位代碼 thisColor:當前文字顏色的6位代碼 toColor:目標文字顏色的6位代碼 step:執行次數 speed:執行速度 */ function colorGradient(obj,thisRGB,toRGB,thisColor,toColor,step,speed){ var _thisRGB=colorConversion(thisRGB); //16進制轉換10進制 var _toRGB=colorConversion(toRGB); if(thisColor&&toColor){ var _thisColor=colorConversion(thisColor,1); var _toColor=colorConversion(toColor,1); } var step=step?step:3; var _step=step; var _speed=speed?parseInt(speed/step):30; //根據總時間計算每次執行的速度 var _R_step=parseInt(Math.abs(_thisRGB[0]-_toRGB[0])/_step); var _G_step=parseInt(Math.abs(_thisRGB[1]-_toRGB[1])/_step); var _B_step=parseInt(Math.abs(_thisRGB[2]-_toRGB[2])/_step); var timer=setInterval(function(){ if(_step>0){ var s=(step-_step)+1; var r=_step==1?_toRGB[0]:(_thisRGB[0]>_toRGB[0]?_thisRGB[0]-_R_step*s:_thisRGB[0]+_R_step*s); var g=_step==1?_toRGB[1]:(_thisRGB[1]>_toRGB[1]?_thisRGB[1]-_G_step*s:_thisRGB[1]+_G_step*s); var b=_step==1?_toRGB[2]:(_thisRGB[2]>_toRGB[2]?_thisRGB[2]-_B_step*s:_thisRGB[2]+_B_step*s); obj.css({'background-color':'rgb('+r+','+g+','+b+')'}); if(thisColor&&toColor){ var cr=_step==1?_toColor[0]:(_thisColor[0]>_toColor[0]?_thisColor[0]-_R_step*s:_thisColor[0]+_R_step*s); var cg=_step==1?_toColor[1]:(_thisColor[1]>_toColor[1]?_thisColor[1]-_G_step*s:_thisColor[1]+_G_step*s); var cb=_step==1?_toColor[2]:(_thisColor[2]>_toColor[2]?_thisColor[2]-_B_step*s:_thisColor[2]+_B_step*s); obj.css({'color':'rgb('+cr+','+cg+','+cb+')'}); } _step--; }else{ clearInterval(timer); return true; } },_speed); }
這個方法很簡單,但漸變的平滑度通常,特別是在一組對象連續執行的時候。只能說,這是一種很吊絲,很笨的方法,大神都是用Tween算法
使用方法,直接使用jquery的animate就能夠了,只是不用指定當前顏色,程序會自動取當前顏色,不過必須在樣式裏設定background
obj.animate({'background-color':'#ff0000','color':'#000000'});